2015-01-20 1 views
0

Я пытаюсь обнаружить лица в растровых изображениях с помощью OpenCV на Android. Если я буду запускать свою функцию обнаружения 30 раз, ни одно лицо не будет найдено в первые n раз, где n будет около 7-15. Детектор начинает находить лицо на 8-м-16-м обнаружении и последовательно работает после этого. Это использует одно и то же изображение, ничего не меняя (намеренно).Обнаружение лица OpenCV работает непоследовательно на одном и том же изображении

Что происходит? Есть какой-то шаг инициализации, который я пропускаю? Почему это непоследовательно?

Код:

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 является объектом File, содержащий фронтальную поверхность Хаара каскадный файл.

Вызывается из:

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, как указано выше.

+0

Не кажется очевидным, что что-либо может привести к этому на основе образца кода, который вы предоставили. Это кажется синхронным по своей природе, и если вы каждый раз предоставляете одинаковое растровое изображение, тогда нет никаких причин, по которым он не будет работать в первый раз. Возможно, вам потребуется проанализировать дополнительный код, чем тот, который вы указали здесь. –

+0

На самом деле нет дополнительного кода? Я обновляю свой вопрос с помощью теста, из которого я вызываю detectFaces. – sqshemet

+0

Не существует ли IOExceptions, наложенных на эти первые записи? И это происходит в одном потоке? –

ответ

0

Проблема заключается в том, что на вашем детекторе не используется класс детектора лица (CascadeClassifier), а на его детекторе - детектор лица (DetectionBasedTracker).

Я не нашел этот класс в официальной документации и не просмотрел код, поэтому не могу точно сказать, как это работает, но согласно this page, он имеет параметр minDetectionPeriod, то есть, вероятно, причину поведения, которое вы наблюдаете.

Я полагаю, что он не возвращает трек, если он не был обнаружен как минимум minDetectionPeriod раз, чтобы фильтровать спорадические ложные срабатывания.

+0

Интересно. В то время как DetectionBasedTracker у меня как часть OpenCV, похоже, работает совсем по-другому, чем тот, который был зарегистрирован там (ни один из тех же параметров или методов), который все еще может быть проблемой. Я не совсем уверен, что это неправильный ответ для моего конкретного приложения (повторное распознавание лиц в видео, по большей части), но я это рассмотрю. – sqshemet