0

I'm trying to use facial recognition with Android . All the loads are ok , but the haarcascade_frontalface_alt2.xml file wich i don't know how to load it using JavaCV. This is the code i have:

public static void detectFacialFeatures()
{
    // The cascade definition to be used for detection.

    // This will redirect the OpenCV errors to the Java console to give you
    // feedback about any problems that may occur.
    new JavaCvErrorCallback();

    // Load the original image.

    // We need a grayscale image in order to do the recognition, so we
    // create a new image of the same size as the original one.
    IplImage grayImage = IplImage.create(iplImage.width(),iplImage.height(), IPL_DEPTH_8U, 1);

    // We convert the original image to grayscale.
    cvCvtColor(iplImage, grayImage, CV_BGR2GRAY);

    CvMemStorage storage = CvMemStorage.create();

    // We instantiate a classifier cascade to be used for detection, using the cascade definition.
    CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(cvLoad("./haarcascade_frontalface_alt2.xml"));

    // We detect the faces.
    CvSeq faces = cvHaarDetectObjects(grayImage, cascade, storage, 1.1, 1, 0);

    Log.d("CARAS","Hay "+faces.total()+" caras ahora mismo");
}

The problem is here

CvHaarClassifierCascade(cvLoad("./haarcascade_frontalface_alt2.xml"));

I have tried putting the xml file it into the /assets folder , but i have no idea of how must i load it. It's always giving me the next error:

03-26 17:31:25.385: E/cv::error()(14787): OpenCV Error: Null pointer (Invalid classifier cascade) in CvSeq* cvHaarDetectObjectsForROC(const CvArr*, CvHaarClassifierCascade*, CvMemStorage*, std::vector<int>&, std::vector<double>&, double, int, int, CvSize, CvSize, bool), file /home/saudet/projects/cppjars/OpenCV-2.4.4/modules/objdetect/src/haar.cpp, line 1514

... looking more near at the error it points to this code line:

CvSeq faces = cvHaarDetectObjects(grayImage, cascade, storage, 1.1, 1, 0);

That's why i'm pretty sure that the problem comes from the haarcascade_frontalface_alt2.xml load.

Thanks for your help.

P.D: I want to include the cascade into the apk not in sdcard .

A.Quiroga
  • 5,704
  • 6
  • 37
  • 58

2 Answers2

0

If your cascade is in SD card you can use:

CascadeClassifier cascade = new CascadeClassifier(Environment.getExternalStorageDirectory().getAbsolutePath() + "/cascade.xml");

Environment.getExternalStorageDirectory().getAbsolutePath() give you right path to SD card and next - is address to your file in your SD.

McBodik
  • 743
  • 1
  • 7
  • 21
  • sorry but i was waiting about an include in apk cascade file. – A.Quiroga Mar 26 '13 at 22:39
  • I had the same problem. But still don't know how to do that. I try read from assets like `file:///android_asset/cascade.xml` and [also this](http://stackoverflow.com/a/8475135/2099287) but it was unsuccessfuly. Maybe it's device specific and in some devices it will be work. I think the way is - write xml from asset to SD, read and after delete. Perhaps in the future will be the best way. – McBodik Mar 27 '13 at 10:37
0

You can pack your file in apk and then copy it to external location so it is accessible by OpenCV functions.

    try {
        File learnedInputFile = new File(Environment.getExternalStorageDirectory().getPath() + "/learnedData.xml");
        if (!learnedInputFile.exists()) {
            InputStream learnedDataInputStream = assetManager.open("learnedData.xml");
            FileOutputStream learnedDataOutputStream = new FileOutputStream(learnedInputFile);

            // copy file from asset folder to external location, i.e. sdcard
            byte[] buffer = new byte[300];
            int n = 0;
            while (-1 != (n = learnedDataInputStream.read(buffer))) {
                learnedDataOutputStream.write(buffer, 0, n);
            }
        }
        classifier.load(learnedInputFile.getAbsolutePath());
    } catch (IOException exception) {
        // there are no learned data, train ml algorithm or show error, etc.
    }
marci003
  • 21
  • 1
  • This is actually not JavaCV, but official java api bindings for OpenCV, but CvLoad in your case should work instead of my CvStatModel::load() function. – marci003 Apr 09 '13 at 16:33