在 ROI 内查找轮廓

Find Contours inside ROI

我正在搜索这个问题,但没有收到任何具体答案。我已经找到了我的轮廓,也定义了我的投资回报率。

问题:如何才能仅在我的 ROI 内找到这些轮廓?

我一开始就定义了我的投资回报率。

代码如下:

    int main( int argc, char** argv )
{
    Mat img_prev, img_curr, result;
    int counter = 0;

        //string filename = "/home/zubair/Downloads/Contours/1.jpg";
        //VideoCapture cap(filename);

  //while(1)
  //{

  img_curr = imread(argv[1], CV_LOAD_IMAGE_COLOR); 
    //cap >> img_curr;
    //counter++;
    //img_curr.copyTo(img_prev);

    while(1)
       {
      // SetImageRoi    
      cv::Rect roi(1,250, 640, 200);
      cv::rectangle(img_curr,roi,cv::Scalar(255,255,255),1,8,0);


      //cv::Mat image_roi = img_curr(roi);  // note: this assignment does not copy data, frame and   image_roi now share data



   imshow ("current frame",img_curr);

   if(! img_curr.data )                              // Check for invalid input
    {
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    }

   //imshow("previous frame", img_prev);

   cvtColor( img_curr, src_gray, CV_BGR2GRAY );



//--------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------- to find the contours AND Detect edges using Threshold---------------------------------------------//
//--------------------------------------------------------------------------------------------------------------------------------------//


  Mat canny_output;
  Mat threshold_output;
  vector<vector<Point> > contours;
  vector<Vec4i> hierarchy;

  /// Detect edges using canny
  Canny(src_gray, canny_output, thresh, thresh*2, 3 );

  blur( src_gray, src_gray, Size(3,3) );

  ///threshold control
  threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );

  /// Find contours
  findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );

  /// Get the moments
      vector<Moments> mu(contours.size() );
      for( int i = 0; i < contours.size(); i++ )
         { mu[i] = moments( contours[i], false ); }


    cv::erode(threshold_output,threshold_output, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)));
    cv::dilate(threshold_output, threshold_output, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)));



  ///  Get the mass centers:
       vector<Point2f> mc( contours.size() );
       for( int i = 0; i < contours.size(); i++ )
          { mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }

  /// Approximate contours to polygons + get bounding rects and circles
  vector<vector<Point> > contours_poly( contours.size() );
  vector<Rect> boundRect( contours.size() );
  vector<Point2f>center( contours.size() );
  vector<float>radius( contours.size() );
    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], center[i], radius[i] );
        }


   Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
   bool is_inside = (roi & cv::Rect(0, 0, drawing.cols, drawing.rows)) == roi;

   //printf("\t Info: Area and Contour Length \n");
   for( int i = 0; i< contours.size(); i++ )
     {


      if(contourArea(contours[i]) > 2000 && contourArea(contours[i]) < 50000  )
         {

            printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength    ( contours[i], true ) );
            Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );

            drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point(0,0) );
            rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
            Point center_obstacle = (boundRect[i].br() + boundRect[i].tl())*0.5;
            circle(drawing,center_obstacle,3,Scalar(0,0,255));
            cout<<"     obstale     "<<i<<"     position is at     "<< center_obstacle.x <<"     and     "<< center_obstacle.y <<endl;
         }

      }



        createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh );
        createTrackbar( " Threshold:", "Source", &thresh, max_thresh);

    namedWindow( "Contours", WINDOW_AUTOSIZE );
    imshow( "Contours", drawing );

//--------------------------------------------------------------------------------------------------------------------------------------------



        waitKey(0);

}
      return 0;
  }

解决方案:我想在绘制轮廓之前给出一个条件,轮廓应该在我的 ROI 范围内。我不知道该怎么做。

我定义了一个判断Rect rect是否在Rect roi中的函数

bool isInside(const Rect& rect, const Rect& roi) {
    return (roi|rect) == roi;
}

这是测试示例:


//! 2018.01.18 09:37:20 CST
//! 2018.01.18 10:29:16 CST
#include <opencv2/opencv.hpp>
#include <vector>
#include <string>
using namespace std;
using namespace cv;

// To judge whether rect is in roi or not?
bool isInside(const Rect& rect, const Rect& roi) {
    return (roi|rect) == roi;
}

int main() {

    Mat img(600,600, CV_8UC3, Scalar::all(0));

    Rect roi(100, 100, 400, 400);
    Rect rect1(200, 200, 200, 200);
    Rect rect2(10,10, 200, 200);

    Scalar blue(255,0,0), green(0,255,0), red(0,0,255);

    string msg("Roi in blue; Inside in green, Outside in red!");
    cout<<msg<<endl;
    rectangle(img, roi, blue, 1);
    rectangle(img, rect1, isInside(rect1, roi)?green:red, 1);
    rectangle(img, rect2, isInside(rect2, roi)?green:red, 1);
    imshow(msg, img);
    waitKey();
}

好的,现在 return 回到您的程序,到 judge whether the contours is inside of roi or not,只是 compare their boundingRect with roi

您的代码:

bool is_inside = (roi & cv::Rect(0, 0, drawing.cols, drawing.rows)) == roi;

修改:

for( int i = 0; i< contours.size(); i++ )
{
    Rect rect = boundingRect(contours[i]);
    // bool is_inside = (roi|rect) == roi;
    if(!isInside(rect, roi)){
        cout <<"Not in side, continue to the next."<<endl;
        continue;
    }

    // ...

}

这是我的结果,把所有的轮廓都画成白色,然后把里面的(面积符合某个区域标准的)画成彩色: