我正在尝试在Android上开发一个Face Recognition应用程序,因为我不想在项目上使用NDK(只是没有时间切换),我坚持使用Java开发整个应用程序,因此我遇到了一些问题:
>似乎Contrib模块不包含在OpenCV 2.4.2中.无论如何在项目中使用它?
>我尝试使用JavaCV来使用Contrib Module的“FaceRecognizer”类.有两个类可用,称为“FaceRecognizer”& “FaceRecognizerPtr”.有谁知道这两者之间的区别是什么?
>上面提到的类有一个叫做“Train”的方法,它在(C语言中)接收两个类型为“Mat& Integer”的矢量(模型 – >列车(图像,标签)& train(Vector< mat> theImages,Vector< ; int> theLabels).我尝试在Java中传递它们ArrayList< mat>& ArrayList< integer>和Vectors但似乎该方法显式接受了“CvArr”数据类型,我不知道如何获取…这是错误:
The method train(opencv_core.CvArr, opencv_core.CvArr) in the type
opencv_contrib.FaceRecognizer is not applicable for the arguments
(ArrayList, ArrayList)
有谁知道如何将我的ArrayList更改为CvArr?
这是我的第一篇文章,我不确定是在一个帖子还是在三个帖子中提出所有三个问题,对于给您带来的任何不便表示遗憾…如果您需要有关该项目的任何其他信息,请随时提出.
解决方法:
更新
以下文章是由Petter Christian Bjelland撰写的,所以所有的功劳都是他的.我在这里发帖,因为他的博客目前似乎处于维护模式,但我认为值得分享.
使用JavaCV进行人脸识别(自http://pcbje.com起)
我找不到任何关于如何使用OpenCV和Java进行人脸识别的教程,所以我决定在这里分享一个可行的解决方案.由于培训模型是在每次运行时构建的,因此解决方案的当前形式效率非常低,但它显示了使其工作所需的内容.
下面的类有两个参数:包含训练面的目录的路径以及要分类的图像的路径.并非所有图像都必须具有相同的尺寸,并且必须从原始图像中裁剪出面部(如果尚未进行面部检测,请查看此处).
为了简化这篇文章,该课程还要求训练图像具有文件名格式:< label> -rest_of_filename.png.例如:
1-jon_doe_1.png1-jon_doe_2.png2-jane_doe_1.png2-jane_doe_2.png
… 等等.
代码:
import com.Googlecode.javacv.cpp.opencv_core;import static com.Googlecode.javacv.cpp.opencv_highgui.*;import static com.Googlecode.javacv.cpp.opencv_core.*;import static com.Googlecode.javacv.cpp.opencv_imgproc.*;import static com.Googlecode.javacv.cpp.opencv_contrib.*;import java.io.file;import java.io.filenameFilter;public class OpenCVFaceRecognizer { public static voID main(String[] args) { String trainingDir = args[0]; Iplimage testimage = cvLoadImage(args[1]); file root = new file(trainingDir); filenameFilter pngFilter = new filenameFilter() { public boolean accept(file dir, String name) { return name.tolowerCase().endsWith(".png"); } }; file[] imagefiles = root.Listfiles(pngFilter); MatVector images = new MatVector(imagefiles.length); int[] labels = new int[imagefiles.length]; int counter = 0; int label; Iplimage img; Iplimage grayimg; for (file image : imagefiles) { // Get image and label: img = cvLoadImage(image.getabsolutePath()); label = Integer.parseInt(image.getname().split("\-")[0]); // Convert image to grayscale: grayimg = Iplimage.create(img.wIDth(), img.height(), IPL_DEPTH_8U, 1); cvCvtcolor(img, grayimg, CV_BGR2GRAY); // Append it in the image List: images.put(counter, grayimg); // And in the labels List: labels[counter] = label; // Increase counter for next image: counter++; } FaceRecognizer faceRecognizer = createFisherFaceRecognizer(); // FaceRecognizer faceRecognizer = createEigenFaceRecognizer(); // FaceRecognizer faceRecognizer = createLBPHFaceRecognizer() faceRecognizer.train(images, labels); // Load the test image: Iplimage greyTestimage = Iplimage.create(testimage.wIDth(), testimage.height(), IPL_DEPTH_8U, 1); cvCvtcolor(testimage, greyTestimage, CV_BGR2GRAY); // And get a prediction: int predictedLabel = faceRecognizer.predict(greyTestimage); System.out.println("Predicted label: " + predictedLabel); }}
该类需要OpenCV Java接口.如果您正在使用Maven,则可以使用以下pom.xml检索所需的库:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupID>com.pcbje</groupID> <artifactID>opencvfacerecognizer</artifactID> <version>0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>opencvfacerecognizer</name> <url>http://pcbje.com</url> <dependencIEs> <dependency> <groupID>com.Googlecode.javacv</groupID> <artifactID>javacv</artifactID> <version>0.3</version> </dependency> <!-- For linux x64 environments --> <dependency> <groupID>com.Googlecode.javacv</groupID> <artifactID>javacv</artifactID> <classifIEr>linux-x86_64</classifIEr> <version>0.3</version> </dependency> <!-- For OSX environments --> <dependency> <groupID>com.Googlecode.javacv</groupID> <artifactID>javacv</artifactID> <classifIEr>macosx-x86_64</classifIEr> <version>0.3</version> </dependency> </dependencIEs> <repositorIEs> <repository> <ID>javacv</ID> <name>JavaCV</name> <url>http://maven2.javacv.Googlecode.com/git/</url> </repository> </repositorIEs></project>
原帖
引自我在http://answers.opencv.org/question/865/the-contrib-module-problem的回复.
在没有使用过javacv的情况下,让我们看看我们可以通过查看接口获得多远!该项目位于Googlecode上,可以轻松浏览代码:http://code.google.com/p/javacv.
首先看看如何包装cv :: FaceRecognizer(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);}
啊哈,所以你需要为图像传递MatVector!您可以在CvArr(一行或一列)中传递标签. MatVector在opencv_core, line 4629 (at time of writing 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);}
再看看代码,我想它可以像这样使用:
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);}
您可能想要自己编写一个方法来执行从Java ArrayList到MatVector的转换(如果javacv中还没有这样的函数).
现在回答你的第二个问题. FaceRecognizer等同于cv :: FaceRecognizer.本机OpenCV C类返回一个cv :: Ptr< cv :: FaceRecognizer> ;,这是一个指向cv :: FaceRecognizer的(智能)指针.这也必须包装好.看到这里的模式?FaceRecognizerPtr的界面现在看起来像这样:
@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);}
因此,您可以从此类获取FaceRecognizer或将FaceRecognizer放入其中.您应该只关注get(),因为指针由创建具体FaceRecognizer算法的方法填充:
@namespace("cv") public static native @ByVal FaceRecognizerPtr createEigenFaceRecognizer(int num_components/*=0*/, double threshold/*=DBL_MAX*/);@namespace("cv") public static native @ByVal FaceRecognizerPtr createFisherFaceRecognizer(int num_components/*=0*/, double threshold/*=DBL_MAX*/);@namespace("cv") public static native @ByVal FaceRecognizerPtr createLBPHFaceRecognizer(int radius/*=1*/, int neighbors/*=8*/, int grID_x/*=8*/, int grID_y/*=8*/, double threshold/*=DBL_MAX*/);
所以,一旦你有FaceRecognizerPtr,你可以做以下事情:
// Holds your training data and labels:MatVector images;CvArr labels;// Do something with the images and labels... Probably fill them?// ...// Then get a Pointer to a FaceRecognizer (FaceRecognizerPtr).// Java doesn't have default parameters, so you have to add some yourself,// if you pass 0 as num_components to the EigenFaceRecognizer, the number of// components is determined by the data, for the threshold use the maximum possible// value if you don't want one. I don't kNow the constant in Java:FaceRecognizerPtr model = createEigenFaceRecognizer(0, 10000);// Then train it. See how I call get(), to get the FaceRecognizer insIDe the FaceRecognizerPtr:model.get().train(images, labels);
这会让你学会一个特征脸模型.就是这样!
总结以上是内存溢出为你收集整理的Android上的人脸识别全部内容,希望文章能够帮你解决Android上的人脸识别所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)