OpenCV在一个窗口中检测多个对象 - 未被绘制

时间:2014-11-03 16:23:54

标签: c++ opencv computer-vision haar-classifier

我有一个OpenCV程序,使用多个Haar分类器在一个窗口中检测多个对象。检测到第一个对象并绘制椭圆,但是当检测到两个辅助对象时,不会为检测到的每个实例绘制圆(当检测到对象时我输出到控制台)。

我正在指定三个分类器:

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

1 个答案:

答案 0 :(得分:0)

在读取/解释检测到的对象位置时出现问题:

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

一切都应该没问题。