Распознавание лиц после вычитания фона с помощью openCv


Я пытаюсь улучшить распознавание лиц с помощью захвата камеры, поэтому я подумал, что было бы лучше, если бы перед процессом распознавания лиц я удалил фон с изображения, Я использую BackgroundSubtractorMOG и CascadeClassifier с lbpcascade_frontalface для распознавания лиц,

Мой вопрос: как я могу захватить изображение переднего плана, чтобы использовать его в качестве входного сигнала для распознавания лиц? вот что у меня есть до сих пор:

while (true) {
    capture.retrieve(image);

    mog.apply(image, fgMaskMOG, training?LEARNING_RATE:0);

    if (counter++ > LEARNING_LIMIT) {
        training = false;
    }

    // I think something should be done HERE to 'apply' the foreground mask 
    // to the original image before passing it to the classifier..

    MatOfRect faces = new MatOfRect();
    classifier.detectMultiScale(image, faces);

    // draw faces rect
    for (Rect rect : faces.toArray()) {
        Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 0, 0));
    }

    // show capture in JFrame
    frame.update(image);
    frameFg.update(fgMaskMOG);

    Thread.sleep(1000 / FPS);
}

Спасибо

2 2

2 ответа:

Если у вас есть входное изображение и маска переднего плана, это прямо вперед. В C++ я бы просто добавил (Только там, где вы разместили свой комментарий): image.copyTo(fgimage,fgMaskMOG);

Я не знаком с интерфейсом java, но это должно быть очень похоже. Только не забудьте правильно инициализировать fgimage и сбрасывать его каждый кадр.

Я могу ответить на C++, используя BackgroundSubtractorMOG2:

Вы можете либо использовать эрозию, либо передать более высокое пороговое значение в вычитатель фона MOG, чтобы удалить шум. Чтобы полностью избавиться от шума и ложных срабатываний, можно также размыть изображение маски и затем применить пороговое значение:

// Blur the mask image
blur(fgMaskMOG2, fgMaskMOG2, Size(5,5), Point(-1,-1));

// Remove the shadow parts and the noise
threshold(fgMaskMOG2, fgMaskMOG2, 128, 255, 0);
Теперь вы можете легко найти прямоугольник, ограничивающий область переднего плана, и передать эту область в каскадный классификатор:
// Find the foreground bounding rectangle
Mat fgPoints;
findNonZero(fgMaskMOG2, fgPoints);
Rect fgBoundRect = boundingRect(fgPoints);

// Crop the foreground ROI
Mat fgROI = image(fgBoundRect);

// Detect the faces
vector<Rect> faces;
face_cascade.detectMultiScale(fgROI, faces, 1.3, 3, 0|CV_HAAR_SCALE_IMAGE, Size(32, 32));

// Display the face ROIs
for(size_t i = 0; i < faces.size(); ++i) 
{
    Point center(fgBoundRect.x + faces[i].x + faces[i].width*0.5, fgBoundRect.y + faces[i].y + faces[i].height*0.5);
    circle(image, center, faces[i].width*0.5, Scalar(255, 255, 0), 4, 8, 0);
} 

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