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)
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.
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.