2014-05-04 125 views
1

我用C++工作和OpenCV如何获得的轮廓角OpenCV中

我检测图像中的轮廓大,因为我有它的黑色区域。 My image

在这种情况下,该区域只是水平的,但它可以在任何地方。

Mat resultGray; 
cvtColor(result,resultGray, COLOR_BGR2GRAY); 
medianBlur(resultGray,resultGray,3); 
Mat resultTh; 
Mat canny_output; 
    vector<vector<Point> > contours; 
    vector<Vec4i> hierarchy; 
Canny(resultGray, canny_output, 100, 100*2, 3); 

    findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 
    Vector<Point> best= contours[0]; 
    int max_area = -1; 
    for(int i = 0; i < contours.size(); i++) { 
      Scalar color = Scalar(0, 0, 0); 

      if(contourArea(contours[i])> max_area) 
      { 
       max_area=contourArea(contours[i]); 
       best=contours[i]; 
      } 
    } 
    Mat approxCurve; 
    approxPolyDP(Mat(best),approxCurve,0.01*arcLength(Mat(best),true),true); 

这样,我有大的轮廓和近似值(以approxCurve)。现在,我想获得这个近似的角点,并获得这个轮廓内的图像,但我不知道我该怎么做。

我正在使用这个How to remove black part from the image? 但是最后一部分我不会非常好地描述。

任何人都知道我该如何获得角落?这是另一种更简单的方式吗?

感谢您的时间,

回答

4

一个你能做到这一点更简单的方法是检查图像的像素,并找到非黑色像素的最小/最大坐标。

事情是这样的:

int maxx,maxy,minx,miny; 
maxx=maxy=-std::numeric_limits<int>::max(); 
minx=miny=std::numeric_limits<int>::min(); 
for(int y=0; y<img.rows; ++y) 
{ 
    for(int x=0; x<img.cols; ++x) 
    { 
     const cv::Vec3b &px = img.at<cv::Vec3b>(y,x); 
     if(px(0)==0 && px(1)==0 && px(2)==0) 
      continue; 
     if(x<minx) minx=x; 
     if(x>maxx) maxx=x; 
     if(y<miny) miny=y; 
     if(y>maxy) maxy=y; 
    } 
} 
cv::Mat subimg; 
img(cv::Rect(cv::Point(minx,miny),cv::Point(maxx,maxy))).copyTo(subimg); 

在我看来,这种方法是比较可靠的,因为你没有检测到任何轮廓,这可能会导致依赖于输入图像上的错误检测。

1

以一种非常有效的方式,您可以对原始图像进行采样,直到您找到一个像素,然后沿着一行和一列移动以找到第一个(0,0,0)像素。它将起作用,除非图像的好部分可以有(0,0,0)像素。如果是这种情况(例如:死像素),则可以添加一个检查该(0,0,0)像素的邻域的双重检查(它应该包含其他(0,0,0)像素。)