OpenCV 人脸检测在同一图像上工作不一致
OpenCV face detection working inconsistently on same image
我正尝试在 Android 上使用 OpenCV 检测位图中的人脸。如果我 运行 我的检测函数 30 次,前 n 次没有找到人脸,其中 n 大约是 7-15。检测器在第 8 到第 16 次检测时开始寻找人脸,并在之后始终如一地工作。这是使用相同的图像,没有任何改变(故意)。
这是怎么回事?我缺少某种初始化步骤吗?为什么这是不一致的?
代码:
public ArrayList<Rect> detectFaces(Bitmap input) {
//Necessary for making the native detector happy
MatOfRect output = new MatOfRect();
//Convert our bitmap to a Mat so the detector can use it
Mat inputMat = new Mat(input.getWidth(), input.getHeight(), CvType.CV_8UC1);
bitmapToMat(input, inputMat);
Imgproc.cvtColor(inputMat, inputMat, Imgproc.COLOR_RGB2GRAY);
//Actually do the detection
mNativeDetector.detect(inputMat, output);
List<org.opencv.core.Rect> faceList = output.toList();
//Convert OpenCV Rects to Android Rects.
ArrayList<Rect> rectList = new ArrayList<Rect>();
for (org.opencv.core.Rect face : faceList){
rectList.add(OpenCvConversions.openCVToAndroidRect(face));
}
return rectList;
检测器初始化为 mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0);
,其中 mCascadeFile 是包含正面 haar 级联文件的文件对象。
呼叫方:
public void testFaces() throws IOException{
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.face);
int detectedFaces = 0;
for (int i=0; i<30; i++){
ArrayList<Rect> faces = mFaceDetector.detectFaces(bitmap);
detectedFaces += faces.size();
System.out.println("Detected faces: " + detectedFaces);
}
}
其中mFaceDetector
是mFaceDetector = new FaceDetectorOpenCV();
,一个加载系统库和面部级联并初始化DetectionBasedTracker的构造函数。
问题是您没有使用面部检测器 (CascadeClassifier) class,而是基于该检测器的面部跟踪器 (DetectionBasedTracker)。
我没有在官方文档中找到这个 class 也没有查看代码,所以我不能告诉你它是如何工作的,但是根据 this page,它有一个参数 minDetectionPeriod,这可能是您观察到的行为的原因。
我想它不会 return 轨道,除非它被检测到至少 minDetectionPeriod 次,以过滤零星的错误检测。
我正尝试在 Android 上使用 OpenCV 检测位图中的人脸。如果我 运行 我的检测函数 30 次,前 n 次没有找到人脸,其中 n 大约是 7-15。检测器在第 8 到第 16 次检测时开始寻找人脸,并在之后始终如一地工作。这是使用相同的图像,没有任何改变(故意)。
这是怎么回事?我缺少某种初始化步骤吗?为什么这是不一致的?
代码:
public ArrayList<Rect> detectFaces(Bitmap input) {
//Necessary for making the native detector happy
MatOfRect output = new MatOfRect();
//Convert our bitmap to a Mat so the detector can use it
Mat inputMat = new Mat(input.getWidth(), input.getHeight(), CvType.CV_8UC1);
bitmapToMat(input, inputMat);
Imgproc.cvtColor(inputMat, inputMat, Imgproc.COLOR_RGB2GRAY);
//Actually do the detection
mNativeDetector.detect(inputMat, output);
List<org.opencv.core.Rect> faceList = output.toList();
//Convert OpenCV Rects to Android Rects.
ArrayList<Rect> rectList = new ArrayList<Rect>();
for (org.opencv.core.Rect face : faceList){
rectList.add(OpenCvConversions.openCVToAndroidRect(face));
}
return rectList;
检测器初始化为 mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0);
,其中 mCascadeFile 是包含正面 haar 级联文件的文件对象。
呼叫方:
public void testFaces() throws IOException{
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.face);
int detectedFaces = 0;
for (int i=0; i<30; i++){
ArrayList<Rect> faces = mFaceDetector.detectFaces(bitmap);
detectedFaces += faces.size();
System.out.println("Detected faces: " + detectedFaces);
}
}
其中mFaceDetector
是mFaceDetector = new FaceDetectorOpenCV();
,一个加载系统库和面部级联并初始化DetectionBasedTracker的构造函数。
问题是您没有使用面部检测器 (CascadeClassifier) class,而是基于该检测器的面部跟踪器 (DetectionBasedTracker)。
我没有在官方文档中找到这个 class 也没有查看代码,所以我不能告诉你它是如何工作的,但是根据 this page,它有一个参数 minDetectionPeriod,这可能是您观察到的行为的原因。
我想它不会 return 轨道,除非它被检测到至少 minDetectionPeriod 次,以过滤零星的错误检测。