简体   繁体   中英

OpenCV face detection working inconsistently on same image

I am trying to detect faces in bitmaps using OpenCV on Android. If I run my detection function 30 times, no face is found the first n times, where n is around 7-15. The detector begins to find the face on the 8th-16th detection, and works consistently after that. This is using the same image, changing nothing (deliberately).

What is going on? Is there some sort of initialization step I'm missing? Why is this inconsistent?

Code:

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;

Detector was initialized with mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0); where mCascadeFile is a File object containing the frontal face haar cascade file.

Called from:

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

Where mFaceDetector is mFaceDetector = new FaceDetectorOpenCV(); , a constructor which loads system libraries and the face cascade and initializes the DetectionBasedTracker as above.

The problem is that your are not using the face detector (CascadeClassifier) class, but a face tracker (DetectionBasedTracker) based on that detector.

I didn't find this class in the official documentation and did not look into the code, so i can't tell you exactly how it works, but according to this page , it has a parameter minDetectionPeriod, that is probably the cause of the behaviour you are observing.

I suppose that it doesn't return a track unless it has been detected a least minDetectionPeriod times, in order to filter sporadic false detections.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM