0

複数の Haar 分類子を使用して、1 つのウィンドウで複数のオブジェクトを検出する OpenCV プログラムがあります。最初のオブジェクトが検出され、楕円が正常に描画されますが、2 つのセカンダリ オブジェクトが検出されると、検出されるインスタンスごとに円が描画されるわけではありません (オブジェクトが検出されたときにコンソールに出力しています)。

次のように 3 つの分類子を指定しています。

  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 )

次に、3 つのオブジェクトに対して 3 つのベクトルを作成します。

  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各オブジェクトの関連する名前を変更します。最初のオブジェクトは完全に機能しているのに、2 番目と 3 番目のオブジェクトはすべてを画面に描画していないにもかかわらず、複数の検出を出力しているのはなぜですか?

編集:

完全な検出および描画コード:

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

1 に答える 1

0

検出されたオブジェクトの位置の読み取り/解釈中に問題が発生します。

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

これは問題なく動作しますが、2 番目と 3 番目のオブジェクトの解釈で小さな間違いを犯しています。

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

および (3 番目の検出器の場合):

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

すべてがうまくいくはずです。

于 2014-11-07T13:23:51.367 に答える