Ask Your Question

Revision history [back]

Low FPS when using CascadeClassifier in Android

I'm new to OpenCV and I've loaded the sample face detection app onto my Android device (Samsung Galaxy Nexus) and it works brilliantly, with a FPS around 20-25 FPS (depending on lighting conditions).

However, when I go to make my own code (which is highly based upon the sample code), the frame rate drops considerably, and now I'm only getting around 1-2 FPS.

I'm following the basic skeleton of the sample application, and the important work is done in the onCameraFrame method, which is as follows:

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    // this method recieves the input frame from the camera BEFORE it is drawn on the
    // screen of the device. The face detection happens here.

    rgba = inputFrame.rgba();
    gray = inputFrame.gray();
    MatOfRect faces = new MatOfRect(); //dense for each face
    if (javaDetector != null) {
        javaDetector.detectMultiScale(gray, faces, 1.1, 2, 2, new Size(0, 0.2f), new Size());
    }

    Rect[] arrayFaces = faces.toArray();
    for (int i = 0; i < arrayFaces.length; i++) {
        Core.rectangle(rgba, arrayFaces[i].tl(), arrayFaces[i].br(), rectangleColor, rectangleColor, 3);
    }
    return rgba;
}

The code that I have to load the library (in the BaseLoaderCallback method) is here:

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                File classifierDir = getDir("cascade", Context.MODE_PRIVATE);
                try {
                    InputStream is = getResources().openRawResource(R.raw.haarcascade_frontalface_alt);
                    File classifierFile = new File(classifierDir, "haarcascade_frontalface_alt.xml");
                    FileOutputStream os = new FileOutputStream(classifierFile);

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

                    javaDetector = new CascadeClassifier(classifierFile.getAbsolutePath());
                    if (javaDetector.empty()) {
                        throw new FileNotFoundException();
                    }
                    classifierDir.delete();
                } catch (FileNotFoundException ex) {
                    Log.e(TAG, "Unable to load facial definitions");
                } catch (IOException iex) {
                    Log.e(TAG, "Unable to open facial definitions file");
                }
                mOpenCvCameraView.enableView();
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

Which is essentially the same as the sample application. Is there a reason why that my version is running so slowly?

click to hide/show revision 2
retagged

updated 2014-07-10 14:30:58 -0600

berak gravatar image

Low FPS when using CascadeClassifier in Android

I'm new to OpenCV and I've loaded the sample face detection app onto my Android device (Samsung Galaxy Nexus) and it works brilliantly, with a FPS around 20-25 FPS (depending on lighting conditions).

However, when I go to make my own code (which is highly based upon the sample code), the frame rate drops considerably, and now I'm only getting around 1-2 FPS.

I'm following the basic skeleton of the sample application, and the important work is done in the onCameraFrame method, which is as follows:

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    // this method recieves the input frame from the camera BEFORE it is drawn on the
    // screen of the device. The face detection happens here.

    rgba = inputFrame.rgba();
    gray = inputFrame.gray();
    MatOfRect faces = new MatOfRect(); //dense for each face
    if (javaDetector != null) {
        javaDetector.detectMultiScale(gray, faces, 1.1, 2, 2, new Size(0, 0.2f), new Size());
    }

    Rect[] arrayFaces = faces.toArray();
    for (int i = 0; i < arrayFaces.length; i++) {
        Core.rectangle(rgba, arrayFaces[i].tl(), arrayFaces[i].br(), rectangleColor, rectangleColor, 3);
    }
    return rgba;
}

The code that I have to load the library (in the BaseLoaderCallback method) is here:

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                File classifierDir = getDir("cascade", Context.MODE_PRIVATE);
                try {
                    InputStream is = getResources().openRawResource(R.raw.haarcascade_frontalface_alt);
                    File classifierFile = new File(classifierDir, "haarcascade_frontalface_alt.xml");
                    FileOutputStream os = new FileOutputStream(classifierFile);

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

                    javaDetector = new CascadeClassifier(classifierFile.getAbsolutePath());
                    if (javaDetector.empty()) {
                        throw new FileNotFoundException();
                    }
                    classifierDir.delete();
                } catch (FileNotFoundException ex) {
                    Log.e(TAG, "Unable to load facial definitions");
                } catch (IOException iex) {
                    Log.e(TAG, "Unable to open facial definitions file");
                }
                mOpenCvCameraView.enableView();
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

Which is essentially the same as the sample application. Is there a reason why that my version is running so slowly?