У меня есть программа OpenCV, использующая несколько классификаторов Хаара для обнаружения нескольких объектов в одном окне. Первый объект обнаружен, и эллипс нарисован, как и должно быть, однако, когда два вторичных объекта обнаружены, круг не рисуется для каждого обнаруженного экземпляра (я выводлю на консоль, когда объект обнаружен).
Я указываю три классификатора, например, так:
String cascade_name = "frontalface.xml";
String nestcascade_name = "body.xml";
String nested_cascade_name_two = "HandCascade.xml";
Затем я загружаю классификаторы, используя:
cascade_one.load( cascade_name )
cascade_two.load( nested_cascade_name )
cascade_three.load( nested_cascade_name_two )
Затем я создаю три вектора для трех объектов:
std::vector<Rect> firstObject;
std::vector<Rect> secondObject;
std::vector<Rect> thirdObject;
Затем я использую следующий код, чтобы обнаружить и нарисовать объекты на экране:
cascade_one.detectMultiScale( frame_gray, firstObject, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t i = 0; i < firstObject.size(); i++ ) {
Point center( firstObject[i].x + firstObject[i].width*0.5, firstObject[i].y + firstObject[i].height*0.5 );
ellipse( frame, center, Size( firstObject[i].width*0.5, firstObject[i].height*0.5), 0, 0, 360, Scalar( 0, 255, 0 ), 4, 8, 0 ); //GREEN
std::cout << " " << cascade_name << " " << timeFound() << endl;
}
изменения cascade_one
firstObject
а также cascade_name
с соответствующими именами для каждого объекта. Почему первый объект работает отлично, а второй и третий выдают несколько обнаружений, несмотря на то, что они не отображаются на экране?
РЕДАКТИРОВАТЬ:
Полное обнаружение и отрисовка кода:
void detectAndDisplay( Mat frame ) {
std::vector<Rect> firstObject;
std::vector<Rect> secondObject;
std::vector<Rect> thirdObject;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect object
cascade_one.detectMultiScale( frame_gray, firstObject, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t i = 0; i < firstObject.size(); i++ ) {
Point center( firstObject[i].x + firstObject[i].width*0.5, firstObject[i].y + firstObject[i].height*0.5 );
ellipse( frame, center, Size( firstObject[i].width*0.5, firstObject[i].height*0.5), 0, 0, 360, Scalar( 0, 255, 0 ), 4, 8, 0 ); //GREEN
std::cout << " " << cascade_name << " " << timeFound() << endl;
}
//-- detect second object
cascade_two.detectMultiScale( frame_gray, secondObject, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t k = 0; k < secondObject.size(); k++ ) {
Point center( secondObject[k].x + secondObject[k].x + secondObject[k].width*0.5, secondObject[k].y + secondObject[k].y + secondObject[k].height*0.5 );
int radius = cvRound( (secondObject[k].width + secondObject[k].height)*0.25 );
circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 ); //BLUE
std::cout << " " << nested_cascade_name << " " << timeFound() << endl;
}
//-- detect third object
cascade_three.detectMultiScale( frame_gray, thirdObject, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t j = 0; j < thirdObject.size(); j++ ) {
Point center( thirdObject[j].x + thirdObject[j].x + thirdObject[j].width*0.5, thirdObject[j].y + thirdObject[j].y + thirdObject[j].height*0.5 );
int radius = cvRound( (thirdObject[j].width + thirdObject[j].height)*0.25 );
circle( frame, center, radius, Scalar( 0, 0, 255 ), 4, 8, 0 ); //RED
std::cout << " " << nested_cascade_name_two << " " << timeFound() << endl;
}
imshow( window_name, frame );
}
Ваша проблема возникает при чтении / интерпретации позиции обнаруженных объектов:
Point center( firstObject[i].x + firstObject[i].width*0.5, firstObject[i].y + firstObject[i].height*0.5 );
хотя это работает отлично, вы допустили небольшую ошибку при интерпретации второго и третьего объектов:
Point center( secondObject[k].x + secondObject[k].x + secondObject[k].width*0.5, secondObject[k].y + secondObject[k].y + secondObject[k].height*0.5 );
где secondObject [k] .x + secondObject [k] .x может «перемещать» обнаруженный объект из вашего изображения и не имеет особого смысла, если вы хотите отобразить объект в том месте, где он был обнаружен.
Если вы замените строку на
Point center( secondObject[k].x + secondObject[k].width*0.5, secondObject[k].y + secondObject[k].y + secondObject[k].height*0.5 );
и (для третьего детектора):
Point center( thirdObject[j].x + thirdObject[j].width*0.5, thirdObject[j].y + thirdObject[j].y + thirdObject[j].height*0.5 );
все должно быть хорошо.