0

I have a OpenCV program using multiple Haar Classifiers to detect multiple objects in a single window. The first object is detected and the ellipse is drawn as it should however when the two secondary objects are detected the circle is not drawn for every instance it is detected (I am outputting to the console when an object is detected).

I am specifying three classifiers like so:

  String cascade_name = "frontalface.xml";
  String nestcascade_name = "body.xml";
  String nested_cascade_name_two = "HandCascade.xml";

I am then loading the classifiers using:

cascade_one.load( cascade_name )
cascade_two.load( nested_cascade_name )
cascade_three.load( nested_cascade_name_two )

I then create three vectors for the three objects:

  std::vector<Rect> firstObject;
  std::vector<Rect> secondObject;
  std::vector<Rect> thirdObject;

I then use the following code to detect and draw the objects on the screen:

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

Changing cascade_one firstObject and cascade_name with the relevant names for each object. Why is the first object working perfectly but the second and third are outputting multiple detections despite not drawing them all on the screen?

EDIT:

Full detect and draw code:

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 );
  } 
Colin747
  • 4,955
  • 18
  • 70
  • 118
  • How many elements are in secondObject and thirdObject vectors? Can you please post the code for drawing them, too? If it doesnt work there might still be a bug in the code. Or even better: full code of all 3 detection steps and drawing steps. – Micka Nov 03 '14 at 16:48
  • I've included the full detect and draw code in my question as an edit. – Colin747 Nov 03 '14 at 23:18
  • Are there any 2nd/3rd objects detected and just not drawn or are there no detections at all? – Micka Nov 04 '14 at 10:57
  • They are detected but not always drawn – Colin747 Nov 04 '14 at 11:01
  • But the cout is printed? Can you print center and radius in addition to verify legal positions? – Micka Nov 04 '14 at 17:12
  • Both the `center` and `radius` are being printed, some examples: `2014-11-05T10:05:08 HandCascade.xml 650[455, 241]32` `2014-11-05T10:05:09 HandCascade.xml 651[1004, 324]36` `2014-11-05T10:05:09 HandCascade.xml 652[1004, 324]36` `2014-11-05T10:05:10 HandCascade.xml 653[999, 345]32` – Colin747 Nov 05 '14 at 10:21
  • Do they fit your image resolution? (X pos = 1004 or 999) and radius is > 0? – Micka Nov 05 '14 at 12:17
  • Is there any way to check the resolution of the window that is created by OpenCV or do I just have to go off the resolution of the camera? – Colin747 Nov 05 '14 at 13:33
  • When I mouse over the video window the X and Y co-ords displayed look like the window size is 640x480 – Colin747 Nov 05 '14 at 13:37
  • You could print yourImagwMat.cols and yourImageMat.rows. so it looks like you've detected objects outside of the image or your computation of "center" isnt doing right. – Micka Nov 05 '14 at 18:00
  • I guess the error is: secondObject[k].x + secondObject[k].x so you double your x coordinate which looks like a copy-paste error. Same for y and thirdObject. Or is there any intention to do that?!? – Micka Nov 05 '14 at 18:01
  • That seems to have solved it. Nothing seems to be printed that isn't drawn and none of the co-ords seem to be out of the range of the window size. Many thanks. – Colin747 Nov 06 '14 at 13:44
  • nice to hear that. have fun. – Micka Nov 06 '14 at 14:42
  • Would you like to add your comment as an answer? – Colin747 Nov 07 '14 at 11:51

1 Answers1

0

your problem occurs during reading/interpreting the detected objects position:

Point center( firstObject[i].x + firstObject[i].width*0.5, firstObject[i].y + firstObject[i].height*0.5 );

while this works fine, you've made a small mistake in the second and third objects interpretation:

Point center( secondObject[k].x + secondObject[k].x + secondObject[k].width*0.5, secondObject[k].y + secondObject[k].y + secondObject[k].height*0.5 );

where secondObject[k].x + secondObject[k].x might be "moving" the detected object out of your image and doesnt make much sense if you want to display the object at the location where it was detected.

If you replace the the line by

Point center( secondObject[k].x + secondObject[k].width*0.5, secondObject[k].y + secondObject[k].y + secondObject[k].height*0.5 );

and (for third detector):

Point center( thirdObject[j].x + thirdObject[j].width*0.5, thirdObject[j].y + thirdObject[j].y + thirdObject[j].height*0.5 );

everything should be fine.

Micka
  • 19,585
  • 4
  • 56
  • 74