Ask Your Question
3

Face Recognition on Android

asked 2012-07-28 03:50:34 -0600

Mohammad gravatar image

updated 2012-07-29 00:59:00 -0600

Kirill Kornyakov gravatar image

Hi

I'm trying to develop a Face Recognition app on Android and since I don't want to use NDK on the project (simply don't have the time to switch), I'm sticking to develop the whole app with Java and therefor I'm having some problems :

  1. It seems the Contrib Module isn't included in OpenCV 2.4.2 . is there anyway to use it in the project ?

  2. I tried using JavaCV to use the Contrib Module's "FaceRecognizer" class. there are two classes available called "FaceRecognizer" & "FaceRecognizerPtr". does anybody know what the difference between these two is ?

  3. The classes mentioned above have a method called "Train" which (In C++) receives two Vectors of types "Mat & Integer" ( model->train(images,labels) & train(Vector<mat> theImages, Vector<int> theLabels) . I tried passing them ArrayList<mat> & ArrayList<integer> and Vectors in Java but it seems that the method explicitly accepts the "CvArr" Data type which I'm not sure how to acquire... Here is the error :

The method train(opencv_core.CvArr, opencv_core.CvArr) in the type opencv_contrib.FaceRecognizer is not applicable for the arguments (ArrayList<mat>, ArrayList<integer>

Does anyone know how to change my ArrayList to CvArr ?!

This is my first post and I wasn't sure whether to ask all three questions in one post or in three posts so sorry for any inconveniences... If you need any other Information about the project, feel free to ask.

edit retag flag offensive close merge delete

Comments

Please note that OpenCV has its own Java API. I don't know what is the current status of FaceRecognizer support, but if it is not available, it will be definitely done in near future.

Kirill Kornyakov gravatar imageKirill Kornyakov ( 2012-07-29 00:58:16 -0600 )edit
1

I'd like to add to this. The cv::FaceRecognizer got a major overhaul in OpenCV 2.4.2, which came out just a month ago. So it may take some time to expose it to the other languages, I also need to do a minor correction to the interface.

Philipp Wagner gravatar imagePhilipp Wagner ( 2012-07-29 04:46:27 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
5

answered 2012-07-28 04:40:31 -0600

updated 2012-10-27 11:54:03 -0600

Update: I have found a blog post, that shows how to use the FaceRecognizer with JavaCV:

Original Post: Without ever having used javacv, let's see how far we can get by just looking at the interfaces! The project is on googlecode, which makes it easy to browse the code: http://code.google.com/p/javacv.

First have a look at how cv::FaceRecognizer has been wrapped (opencv_contrib.java, line 845 at time of writing this):

@Namespace("cv") public static class FaceRecognizer extends Algorithm {
    static { Loader.load(); }
    public FaceRecognizer() { }
    public FaceRecognizer(Pointer p) { super(p); }

    public /*abstract*/ native void train(@ByRef MatVector src, @Adapter("ArrayAdapter") CvArr labels);
    public /*abstract*/ native int predict(@Adapter("ArrayAdapter") CvArr src);
    public /*abstract*/ native void predict(@Adapter("ArrayAdapter") CvArr src, @ByRef int[] label, @ByRef double[] dist);
    public native void save(String filename);
    public native void load(String filename);
    public native void save(@Adapter("FileStorageAdapter") CvFileStorage fs);
    public native void load(@Adapter("FileStorageAdapter") CvFileStorage fs);
}

Aha, so you need to pass a MatVector for the images! You can pass the labels in a CvArr (one row or one column). The MatVector is defined in opencv_core, line 4629 (at time of writing this) and it looks like this:

public static class MatVector extends Pointer {
    static { load(); }
    public MatVector()       { allocate();  }
    public MatVector(long n) { allocate(n); }
    public MatVector(Pointer p) { super(p); }
    private native void allocate();
    private native void allocate(@Cast("size_t") long n);

    public native long size();
    public native void resize(@Cast("size_t") long n);

    @Index @ValueGetter public native @Adapter("MatAdapter") CvMat getCvMat(@Cast("size_t") long i);
    @Index @ValueGetter public native @Adapter("MatAdapter") CvMatND getCvMatND(@Cast("size_t") long i);
    @Index @ValueGetter public native @Adapter("MatAdapter") IplImage getIplImage(@Cast("size_t") long i);
    @Index @ValueSetter public native MatVector put(@Cast("size_t") long i, @Adapter("MatAdapter") CvArr value);
}

Again just by looking at the code, I guess it can be used like this:

int numberOfImages = 10;
// Allocate some memory:
MatVector images = new MatVector(numberOfImages);
// Then fill the MatVector, you probably want to do something useful instead:
for(int idx = 0; idx < numberOfImages; idx++){
   // Load an image:
   CvArr image = cvLoadImage("/path/to/your/image");
   // And put it into the MatVector:
   images.put(idx, image);
}

You probably want to write yourself a method that does the conversion from a Java ArrayList to a MatVector (if such a function does not exist in javacv yet).

Now to your second question. FaceRecognizer is the equivalent to cv::FaceRecognizer. The native OpenCV C++ classes return a cv::Ptr<cv::FaceRecognizer>, which is a (Smart) Pointer to a cv::FaceRecognizer. This has to be wrapped as well. See a pattern here?

The interface of FaceRecognizerPtr now looks like this:

@Name("cv::Ptr<cv::FaceRecognizer>")
public static class FaceRecognizerPtr extends Pointer {
    static { load(); }
    public FaceRecognizerPtr()       { allocate();  }
    public FaceRecognizerPtr(Pointer p) { super(p); }
    private native void allocate();

    public native FaceRecognizer get();
    public native FaceRecognizerPtr put(FaceRecognizer value);
}

So you can either get a FaceRecognizer from this class or put a ... (more)

edit flag offensive delete link more

Comments

Thanks Philipp...

But I'm having a little trouble trying to load data into CvArr... I already have the labels as strings of data... but I can't seem to find a way to insert these labels as an array to CvArr... let's call it a lack of OpenCV knowledge... can anybody help me with this issue ?!

Mohammad gravatar imageMohammad ( 2012-08-07 06:29:20 -0600 )edit

I can tell how to do it in OpenCV C++ sure, but this is JavaCV. So such questions are best asked on the JavaCV mailing list, which is available at:

Philipp Wagner gravatar imagePhilipp Wagner ( 2012-08-07 10:38:37 -0600 )edit

Thanks ! Will Check it Out...

Mohammad gravatar imageMohammad ( 2012-08-09 19:20:03 -0600 )edit

Hi Philipp! Thats a nice explaination...can I have the opencv implementation of face recognition for android. That'll a great help.

MatRat gravatar imageMatRat ( 2013-05-27 20:34:37 -0600 )edit

Hi Philipp! I am afraid I have some trouble with javacv as most of the classes from com.googlecode.javacv.cpp package are annotated with com.googlecode.javacpp.annotation.Properties and that annotation uses a property inherit which is not defined in Properties annotation. Using javacpp-0.5.jar

gunar gravatar imagegunar ( 2013-08-07 02:07:43 -0600 )edit

Question Tools

Stats

Asked: 2012-07-28 03:50:34 -0600

Seen: 8,651 times

Last updated: Dec 01 '12