martes, 23 de febrero de 2016

Classification of object in Android - Fourth Week

In my forth week I worked on a code for classifying images in Android. That is possible using the SVM calculated in the program in Python. The Support Vector Machine is saved in a file from Python and then is loaded on Android. It is also necessary to use OpenCV to get the local descriptors from the testing image and use the codebook to get the global descriptor. The codebook is also saved in a file from Python and loaded on Android using CSV format.

How to use OpenCV on an Android Activity

I created a new Activity on the Android project called TestActivity to make the debugging easier. It uses a picture that was already taken and stored in memory. To make an Activity work with OpenCV you can follow this tutorial
http://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html.
In my case I added a LoaderCallback attribute to the TestActivity class:

private BaseLoaderCallback mLoaderCallback =
new BaseLoaderCallback(this) {
  @Override
  public void onManagerConnected(int status) {
      switch (status) {
          case LoaderCallbackInterface.SUCCESS: {
              Log.d(TAG, "OpenCV loaded");
          }
          break;
          default: {
              super.onManagerConnected(status);
          }
          break;
      }
  }
};

And this lines inside the onCreate() method:

// --------------------------------------------------------------------------
// OpenCVLoader
if (!OpenCVLoader.initDebug()) {
  mLoaderCallback.
onManagerConnected(LoaderCallbackInterface.INIT_FAILED);
} else {
mLoaderCallback.
onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
// ---------------------------------------------------------------------------

Loading an OpenCV SVM on Android 

To use the SVM previously computed with Python it was necessary to do something triky. The SVM class has a function load(filename). The problem is that in Android filenames are not as easy as in a PC. You may have the file stored in external or internal memory, on the local folder of the app or in the res/raw/ directory of the source code. So I followed a sample from OpenCV Android, a project called face-detection. They store the model file in a /res/raw/ directory inside the source code and what they do is to open it and make a local copy of it. So when the load method is called it uses the local copy.

InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
FileOutputStream os = new FileOutputStream(mCascadeFile);

byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
  os.write(buffer, 0, bytesRead);
}
is.close();
os.close();

mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath());

The method getAbsolutePath( ) is what you need as filename. After using that I was able to load the SVM and use it to predict the class of the image.

Result

Finally I also had to create a Vlad class to calculate the global descriptor for the image using the codebook and the local descriptors. After I did that I had all the elements to do a classification for the input image, which was an image of potatoes, and was correctly classified as that.


No hay comentarios.:

Publicar un comentario