Распознавание лиц после вычитания фона с помощью 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 ответа:
Если у вас есть входное изображение и маска переднего плана, это прямо вперед. В 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); }
Таким образом, вы будете уменьшите область поиска для каскадного классификатора, что не только ускорит его, но и уменьшит ложноположительные грани.