怎样使用OpenCV进行人脸识别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎样使用OpenCV进行人脸识别相关的知识,希望对你有一定的参考价值。

参考技术A

昨天刚回答过,修改下错别字放上来了。

不知道你说的人脸识别是识别出来是某个人还是只是在图像中检测出人脸。

刚用opencv完成对自己的人脸识别,但是还需要继续优化。说一下大致步骤吧:

1、首先就是数据的准备,你要从网络上下载一些人脸库,后面用来训练人脸识别模型。人脸检测模型opencv是自带的,但是识别模型需要自己训练。下载人脸库之后需要对人脸进行标记,这是一个繁琐的工作,不过网上有脚本或者自己写个程序简化工作量。

2、把数据标记好之后就是opencv的事情。训练的函数非常简单。只有下面这三句:

Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
model->train(images, labels);
model->save("MyFacePCAModel.xml");

3、然后打开摄像头进行人脸检测,就是框出人脸的位置。人脸检测模型是opencv自带的。

CascadeClassifier cascade;
cascade.load("haarcascade_frontalface_alt.xml");

这是加载的方法。

cascade.detectMultiScale(gray, faces,
    1.1, 2, 0
    //|CV_HAAR_FIND_BIGGEST_OBJECT
    //|CV_HAAR_DO_ROUGH_SEARCH
    | CV_HAAR_SCALE_IMAGE,
    Size(30, 30));

这是检测的方法。这里检测得到的就是一个一个的人脸的矩形框,然后用画矩形的方法把它们画出来就行了。

4、然后就是对检测到的人脸进行识别了,用我们刚才训练好的人脸模型。加载:

Ptr<FaceRecognizer> modelPCA = createEigenFaceRecognizer();
modelPCA->load("MyFacePCAModel.xml");

预测:

int predictPCA = 0;
if (face.rows >= 120)

    resize(face, face_test, Size(92, 112));         

if (!face_test.empty())

    predictPCA = modelPCA->predict(face_test);

如果预测结果等于标记结果,说明识别正确。

大致流程就这样了,如果你对opencv有了一定的了解,应该能看懂了。没看懂只能私聊了。

使用 Android 进行 OpenCV 人脸识别

【中文标题】使用 Android 进行 OpenCV 人脸识别【英文标题】:OpenCV face recognition with Android 【发布时间】:2021-03-01 15:00:54 【问题描述】:

我对 android 很陌生,因为我有一个维护项目。我完成了项目的其他部分,如身份验证、令牌设置等......其中面部识别用于识别人。

以前它工作正常并拍摄图像,用它训练并识别出这个人。(显然不是我做的:))。现在它抛出错误

添加人员 ActivityCvException [org.opencv.core.CvException: 简历::异常: /build/master_pack-android/opencv/modules/core/src/matrix.cpp:1047: 错误:(-13)矩阵不连续,因此它的行数可以 不能在函数 cv::Mat 中改变 cv::Mat::reshape(int, int) const

代码示例如下
public void training() 
    Thread thread;
    try
    PreferenceManager.setDefaultValues(getApplicationContext(), R.xml.preferences, false);
    catch (Exception e)
        AddPersonActivity.this.runOnUiThread(new Runnable() 
            public void run() 
                WriteLog("Add Person Activity" +e.fillInStackTrace());
                errorAlert("Add Person Activity" +e.fillInStackTrace());
                VolleyHelper.progressDialog.dismiss();
            
        );

    
    WriteLog("training 1 ");

    final Handler handler = new Handler(Looper.getMainLooper());
    thread = new Thread(new Runnable() 
        public void run() 
            if (!Thread.currentThread().isInterrupted()) 
                try 
                    WriteLog("training 2 ");
                PreProcessorFactory ppF = new PreProcessorFactory(AddPersonActivity.this);
                PreferencesHelper preferencesHelper = new PreferencesHelper(AddPersonActivity.this);
                String algorithm = preferencesHelper.getClassificationMethod();

                FileHelper fileHelper = new FileHelper();
                fileHelper.createDataFolderIfNotExsiting();
                final File[] persons = fileHelper.getTrainingList();
                if (persons.length > 0) 
                    Recognition rec = RecognitionFactory.getRecognitionAlgorithm(getApplicationContext(), Recognition.TRAINING, algorithm);
                    for (File person : persons) 
                        if (person.isDirectory()) 
                            File[] files = person.listFiles();
                            int counter = 1;
                            for (File file : files) 
                                if (FileHelper.isFileAnImage(file)) 
                                    Mat imgRgb = Imgcodecs.imread(file.getAbsolutePath());
                                    Imgproc.cvtColor(imgRgb, imgRgb, Imgproc.COLOR_BGRA2RGBA);
                                    Mat processedImage = new Mat();
                                    imgRgb.copyTo(processedImage);
                                    List<Mat> images = ppF.getProcessedImage(processedImage, PreProcessorFactory.PreprocessingMode.RECOGNITION);
                                    if (images == null || images.size() > 1) 
                                        continue;
                                     else 
                                        processedImage = images.get(0);
                                    
                                    if (processedImage.empty()) 
                                        continue;
                                    
                                    String[] tokens = file.getParent().split("/");
                                    final String name = tokens[tokens.length - 1];

                                    for (int i = 0; i < files.length; i++) 
                                        File myfile = new File(person +

                                                "\\" + files[i].getName());
                                        String long_file_name = files[i].getName();
                                        System.out.println(long_file_name);
                                        System.out.print(long_file_name);

                                        myfile.renameTo(new File(person +
                                                "\\" + long_file_name + "_101" + ".png"));
                                    

                                    WriteLog("training 3 ");

                                    MatName m = new MatName("processedImage", processedImage);
                                    fileHelper.saveMatToImage(m, FileHelper.DATA_PATH);


                                    rec.addImage(processedImage, name, false);

                                    counter++;
                                
                            
                        
                    

                    try 

                        if (rec.train()) 
                            if (zipFileAtPath("/storage/emulated/0/Pictures/facerecognition/training/" + lcode, "/storage/emulated/0/Pictures/facerecognition/data/SVM/" + lcode + ".zip")) 
                                WriteLog("training 4 ");
                                if (zipFileAtPath("/storage/emulated/0/Pictures/facerecognition/data/SVM", "/storage/emulated/0/Pictures/facerecognition/" + "SVM_" + lcode + ".zip")) 
                                    WriteLog("training 5 ");
                                    fileupload(getintent.getStringExtra("lcode"));
                                 else 
                                    Toast.makeText(getApplicationContext(), "No Face Recognised", Toast.LENGTH_SHORT).show();
                                
                             else 
                                Toast.makeText(getApplicationContext(), "No Face Recognised", Toast.LENGTH_SHORT).show();
                            
                         else 
                            Toast.makeText(getApplicationContext(), "Try Again", Toast.LENGTH_SHORT).show();
                            
                        
                     catch (Exception e) 
                        WriteLog("Add Person Activity" +e.fillInStackTrace());
                        errorAlert("Add Person Activity" +e.fillInStackTrace());

                    


                    handler.post(new Runnable() 
                        @Override
                        public void run() 

                        
                    );
                 else 
                    Thread.currentThread().interrupt();
                

             catch (Exception e) 
                    AddPersonActivity.this.runOnUiThread(new Runnable() 
                        public void run() 
                            VolleyHelper.progressDialog.dismiss();
                            WriteLog("Add Person Activity" +e.fillInStackTrace());
                            errorAlert("Add Person Activity" +e.fillInStackTrace());
                        
                    );


            

            
        
    );
    thread.start();

【问题讨论】:

【参考方案1】:

输入图像需要作为连续的字节块存储在内存中。我遇到了类似的情况,特别是因为 Android(至少我尝试过的版本)似乎并没有连续存储图像。 1)检查图像是否连续使用:inputImage.isContinuous()。它返回一个bool。应该是true。 2) 如果图像不连续,您可以通过inputImage.clone() 创建图像的clone 来创建图像的副本。在幕后,我们正在使用create 方法创建输入的深层副本,这应该保证新矩阵是连续的。

 //check image before continuing:
 if ( !inputImage.isContinuous() ) 
    //if the image is not continuous, create a deep copy:
    inputImage = inputImage.clone();
 

【讨论】:

以上是关于怎样使用OpenCV进行人脸识别的主要内容,如果未能解决你的问题,请参考以下文章

怎样使用OpenCV进行人脸识别

怎样使用OpenCV进行人脸识别

怎样使用OpenCV进行人脸识别

OpenCV中LBPH人脸识别器识别人脸实战(附Python源码)

如何开发Java动态人脸识别

eigenface 怎样进行人脸识别