当前位置: 首页 > 知识库问答 >
问题:

基于Android的人脸识别

柯伟志
2023-03-14

我试图在Android上开发一个人脸识别应用程序,因为我不想在项目上使用NDK(根本没有时间切换),我坚持用Java开发整个应用程序,因此我遇到了一些问题:

>

  • 似乎Contrib模块没有包含在OpenCV 2.4.2中。有没有在项目中使用它?

    我尝试使用JavaCV来使用Contrib模块的“FaceRecognizer”类。有两个可用的类,称为“FaceRecognizer”和“FaceRecognizerPTR”。有人知道这两者有什么区别吗?

    上面提到的类有一个名为“train”的方法,它(在C++中)接收两个向量,类型为“mat和integer”(model->train(images,labels)&train(vector theImages,vector theLabels )。我试图在Java中传递它们arraylist &arraylist 和向量,但似乎该方法显式地接受“cvarr”数据类型,我不知道如何获取...错误如下:

    类型opencv_contrib.FaceRecognizer中的方法train(opencv_core.cvarr,opencv_core.cvarr)不适用于参数(ArrayList,ArrayList)

    有人知道如何将ArrayList更改为CvArr吗?!

    这是我的第一个帖子,我不确定是在一个帖子中还是在三个帖子中问所有的三个问题,所以很抱歉给您带来不便...如果您需要任何关于该项目的其他信息,请随时询问。

  • 共有1个答案

    包承望
    2023-03-14

    下面的文章是由Petter Christian Bjelland写的,所以所有的功劳都是他的。我把它贴在这里,因为他的博客此刻似乎处于维护模式,但我认为值得分享。

    我找不到任何关于如何使用OpenCV和Java执行人脸识别的教程,所以我决定在这里分享一个可行的解决方案。由于训练模型是在每次运行时构建的,因此该解决方案以其当前形式非常低效,但它显示了使其工作所需的内容。

    下面的类有两个参数:包含训练面的目录的路径和要分类的图像的路径。并不是说所有的图像都必须是相同的大小,而且人脸已经从他们的原始图像中剪掉了(如果你还没有做人脸检测,请看这里)。

    为了简单起见,该类还要求训练图像具有文件名格式:。例如:

    1-jon_doe_1.png
    1-jon_doe_2.png
    2-jane_doe_1.png
    2-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上的回复。

    @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);
    }
    
    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);
    }
    
    @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);
    

    这会让你学到一个特征脸模型。就这样!

     类似资料:
    • 我成功地获得了tflite文件。 在android部分,我选择了Java语言来加载tflite文件和预测新图像的情绪。我已经过了Tensorflow-lite网站中给出的“图像分类”的例子,但是我很困惑如何使用它。我不知道如何阅读tflite并用它来预测新图像的输出并在android应用上显示结果。请帮助我一些好的资源和解释

    • 我正在开发一个用于人脸识别的android应用程序,使用JavaCV,JavaCV是OpenCv的非官方包装器。导入后,我应用并测试以下已知方法: 使用createLBPHFaceRecognizer()方法的LBPH 使用createFisherFaceRecognizer()方法的fisherface 使用createEigenFaceRecognizer()方法的特征面 在识别检测到的人脸之

    • 问题内容: 使用Android,什么是面部识别的开源选项。 问题答案: 这是我在人脸识别库上找到的一些链接。 Android的FaceDetector.Face 教程:在Android中实现人脸检测 OpenCV Facerecog 图片识别链接: moodstocks ltutech

    • 本文向大家介绍Python基于Dlib的人脸识别系统的实现,包括了Python基于Dlib的人脸识别系统的实现的使用技巧和注意事项,需要的朋友参考一下 之前已经介绍过人脸识别的基础概念,以及基于opencv的实现方式,今天,我们使用dlib来提取128维的人脸嵌入,并使用k临近值方法来实现人脸识别。 人脸识别系统的实现流程与之前是一样的,只是这里我们借助了dlib和face_recognition

    • 使用ML Kit的人脸识别API,您可以检测图像中的人脸并识别关键面部特征。 借助人脸识别功能,您可以获取所需的信息,以执行修饰自拍和美化人像等任务或从用户照片中生成头像。由于ML Kit可以执行实时的人脸识别,因此您可以将其用于视频聊天或会对玩家表情进行响应的游戏等应用程序。 iOS Android 核心功能 识别和定位面部特征 获取检测到的每个人脸的眼睛,耳朵,脸颊,鼻子和嘴巴的坐标。 识别面

    • 1.1. 1.FACE SDK集成 1.2. 2. 接口说明及示例 1.2.1. 2.0 人脸检测参数配置: 1.2.2. 2.1 单帧图片检测: 1.2.3. 2.2 相机预览人脸检测: 1.2.4. 2.3 人脸数据库操作: Version:facelib.aar 1.1. 1.FACE SDK集成 添加三方依赖库: dependencies { compile 'com.rokid: