0

私は OpenCV プロジェクトを開発しています。

現在、特定の ROI (Regoin Of Interest) の輪郭を検出する作業を行っています。私が達成したいのは、すべての小さな輪郭を排除することです。つまり、これらの小さな輪郭をまったく溺れさせたくないということです。

これまでのところ、この仕事をするためにこのアルゴリズムをコーディングした場合:

コード:

vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(mBlur, contours, hierarchy, CV_RETR_EXTERNAL,  CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    //----------------------------------------------------------------------------->
    //Contours Vectors
    vector<vector<Point> > contours_poly(contours.size());
    vector<Rect> boundRect (contours.size());
    vector<Point2f> ContArea(contours.size());
    Mat drawing = Mat::zeros( range_out.size(), CV_8UC3 );
    //----------------------------------------------------------------------------->
    //Detecting Contours
    for( int i = 0; i < contours.size(); i++ )
     {  

        ContArea.clear();
        ContArea.push_back(Point2f(boundRect[i].x, boundRect[i].y));
        ContArea.push_back(Point2f(boundRect[i].x + boundRect[i].width, boundRect[i].y));
        ContArea.push_back(Point2f(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height));
        ContArea.push_back(Point2f(boundRect[i].x, boundRect[i].y + boundRect[i].height));

        double area = contourArea(ContArea);

        if(area > 2000)
        {
           approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
           boundRect[i] = boundingRect( Mat(contours_poly[i]));


           cout<<"The area of Contour: "<<i<< " is: " <<area<<endl;

        }
     }



    /// Draw polygonal contour + bonding rects


   //////////////////////////////////////////////////////////////////////////////////

    for( int i = 0; i< contours.size(); i++ )
    {

        Scalar color = Scalar(255,255,255);
        drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
        fillPoly(drawing, contours, Scalar(255,0,0));

    }

ここでの問題は、画像に存在する領域の一部がこれよりもはるかに大きいことを知っていても、if(area > 2000) ステートメントが実行されないように見えることです。

私は多くの異なる解決策を試してきましたが、これが私にとって最も適切な解決策のようです。

主な質問:

指定されたコードで私が望むものを達成することは可能ですか....?もしそうなら、誰かが私がこのどこで間違っているのかを見ることができますか?

4

1 に答える 1

1

ROI のサイズに基づいて削除する場合は、次のように実行できます ( opencv の境界ボックスの例に基づいて)。

vector< vector< Point > > contours_poly( contours.size() );
vector< Rect > boundRect (contours.size() );
vector< Point2f > centeres ( contours.size() );
vector< float > radiuses ( contours.size() );

// finding the approximate rectangle and circle of contours
for( int i = 0; i < contours.size(); i++ )
  {
    approxPolyDP( Mat ( contours[i] ), contours_poly[i], 3, true );
    boundRect[i] = boundingRect( Mat ( contours_poly[i] ) );
    minEnclosingCircle( ( Mat ) contours_poly[i], centeres[i], radiuses[i] );
  }

上記のコード スニペットは、等高線のおおよその四角形 ( boundRect) と、おおよその円 ( centersradiuses) を提供します。この後、コールできる必要がcontourArea();あり、それが特定のしきい値よりも小さい場合は、それを排除できます。


特定の長さの輪郭を削除したいだけの場合は、その長さを計算し、同様の質問への回答を見て、関数を使用できるようですarcLength()。私は次のように思います:double perimeter = arcLength ( Mat ( contours[i] ), true );.

于 2013-03-26T08:44:23.700 に答える