怎样使用OpenCV进行人脸识别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎样使用OpenCV进行人脸识别相关的知识,希望对你有一定的参考价值。
参考技术A 1.环境搭建:见上一篇博客 整个项目的结构图: 2.编写DetectFaceDemo.java,代码如下: [java] view plaincopyprint? package com.njupt.zhb.test; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfRect; import org.opencv.core.Point; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.highgui.Highgui; import org.opencv.objdetect.CascadeClassifier; // // Detects faces in an image, draws boxes around them, and writes the results // to "faceDetection.png". // public class DetectFaceDemo public void run() System.out.println("\nRunning DetectFaceDemo"); System.out.println(getClass().getResource("lbpcascade_frontalface.xml").getPath()); // Create a face detector from the cascade file in the resources // directory. //CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("lbpcascade_frontalface.xml").getPath()); //Mat image = Highgui.imread(getClass().getResource("lena.png").getPath()); //注意:源程序的路径会多打印一个‘/’,因此总是出现如下错误 /* * Detected 0 faces Writing faceDetection.png libpng warning: Image * width is zero in IHDR libpng warning: Image height is zero in IHDR * libpng error: Invalid IHDR data */ //因此,我们将第一个字符去掉 String xmlfilePath=getClass().getResource("lbpcascade_frontalface.xml").getPath().substring(1); CascadeClassifier faceDetector = new CascadeClassifier(xmlfilePath); Mat image = Highgui.imread(getClass().getResource("we.jpg").getPath().substring(1)); // Detect faces in the image. // MatOfRect is a special container class for Rect. MatOfRect faceDetections = new MatOfRect(); faceDetector.detectMultiScale(image, faceDetections); System.out.println(String.format("Detected %s faces", faceDetections.toArray().length)); // Draw a bounding box around each face. for (Rect rect : faceDetections.toArray()) Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0)); // Save the visualized detection. String filename = "faceDetection.png"; System.out.println(String.format("Writing %s", filename)); Highgui.imwrite(filename, image); package com.njupt.zhb.test; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfRect; import org.opencv.core.Point; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.highgui.Highgui; import org.opencv.objdetect.CascadeClassifier; // // Detects faces in an image, draws boxes around them, and writes the results // to "faceDetection.png". // public class DetectFaceDemo public void run() System.out.println("\nRunning DetectFaceDemo"); System.out.println(getClass().getResource("lbpcascade_frontalface.xml").getPath()); // Create a face detector from the cascade file in the resources // directory. //CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("lbpcascade_frontalface.xml").getPath()); //Mat image = Highgui.imread(getClass().getResource("lena.png").getPath()); //注意:源程序的路径会多打印一个‘/’,因此总是出现如下错误 /* * Detected 0 faces Writing faceDetection.png libpng warning: Image * width is zero in IHDR libpng warning: Image height is zero in IHDR * libpng error: Invalid IHDR data */ //因此,我们将第一个字符去掉 String xmlfilePath=getClass().getResource("lbpcascade_frontalface.xml").getPath().substring(1); CascadeClassifier faceDetector = new CascadeClassifier(xmlfilePath); Mat image = Highgui.imread(getClass().getResource("we.jpg").getPath().substring(1)); // Detect faces in the image. // MatOfRect is a special container class for Rect. MatOfRect faceDetections = new MatOfRect(); faceDetector.detectMultiScale(image, faceDetections); System.out.println(String.format("Detected %s faces", faceDetections.toArray().length)); // Draw a bounding box around each face. for (Rect rect : faceDetections.toArray()) Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0)); // Save the visualized detection. String filename = "faceDetection.png"; System.out.println(String.format("Writing %s", filename)); Highgui.imwrite(filename, image); 3.编写测试类: [java] view plaincopyprint? package com.njupt.zhb.test; public class TestMain public static void main(String[] args) System.out.println("Hello, OpenCV"); // Load the native library. System.loadLibrary("opencv_java246"); new DetectFaceDemo().run(); //运行结果: //Hello, OpenCV // //Running DetectFaceDemo ///E:/eclipse_Jee/workspace/JavaOpenCV246/bin/com/njupt/zhb/test/lbpcascade_frontalface.xml //Detected 8 faces //Writing faceDetection.png package com.njupt.zhb.test; public class TestMain public static void main(String[] args) System.out.println("Hello, OpenCV"); // Load the native library. System.loadLibrary("opencv_java246"); new DetectFaceDemo().run(); //运行结果: //Hello, OpenCV // //Running DetectFaceDemo ///E:/eclipse_Jee/workspace/JavaOpenCV246/bin/com/njupt/zhb/test/lbpcascade_frontalface.xml //Detected 8 faces //Writing faceDetection.png使用 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进行人脸识别的主要内容,如果未能解决你的问题,请参考以下文章