opencv findContours、drawContours、minAreaRect查找图像的轮廓、最小外接矩形 drawContours minAreaRect

findContours

findContours( InputOutputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset=Point());

image——canny算子提取边缘后的二值化图像

contours——提取出的边缘,每一个边缘存储在vector中,是点的序列,vector<vector<Point>> contours

hierarchy——储存了边缘的拓扑结构,元素的数量等于contour的数量,元素类型是vec4i,即一个又包含4个int变量的向量。

                         比如说第i个元素hierarchy[i],hierarchy[i][0]代表同一层级下的前一个contour,hierarchy[i][1]代表同一层级下的后一个contour,hierarchy[i][2]代表第一个子contour,hierarchy[i][3]代表父contour。vector<Vec4i> hierarchy

mode——模式选择。

CV_RETR_EXTERNAL:只保存外部边缘

CV_RETR_LIST:提取所有边缘但是忽略其层次结构

CV_RETR_CCOMP:提取所有轮廓,并且将其组织为两层的 hierarchy: 顶层为连通域的外围边界,次层为洞的内层边界。

CV_RETR_TREE:提取所有轮廓,并且重构嵌套轮廓的全部 hierarchy


drawContours

void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )

函数参数详解:

其中第一个参数image表示目标图像,

第二个参数contours表示输入的轮廓组,每一组轮廓由点vector构成,

第三个参数contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓,

第四个参数color为轮廓的颜色,

第五个参数thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部,

第六个参数lineType为线型,

第七个参数为轮廓结构信息,

第八个参数为maxLevel

minAreaRect

主要求得包含点集最小面积的矩形,,这个矩形是可以有偏转角度的,可以与图像的边界不平行

class CV_EXPORTS RotatedRect
{
public:
    //! various constructors
    RotatedRect();
    RotatedRect(const Point2f& center, const Size2f& size, float angle);
    RotatedRect(const CvBox2D& box);

    //! returns 4 vertices of the rectangle
    void points(Point2f pts[]) const;
    //! returns the minimal up-right rectangle containing the rotated rectangle
    Rect boundingRect() const;
    //! conversion to the old-style CvBox2D structure
    operator CvBox2D() const;

    Point2f center; //< the rectangle mass center
    Size2f size;    //< width and height of the rectangle
    float angle;    //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
};
vector<vector<Point> > contours;
 vector<Vec4i> hierarchy;
 
  /// 阈值化检测边界
  threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
  /// 寻找轮廓
  findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
 
  /// 对每个找到的轮廓创建可倾斜的边界框和椭圆
  vector<RotatedRect> minRect( contours.size() );
  vector<RotatedRect> minEllipse( contours.size() );
 
  for( int i = 0; i < contours.size(); i++ )
     { minRect[i] = minAreaRect( Mat(contours[i]) );
       if( contours[i].size() > 5 )
         { minEllipse[i] = fitEllipse( Mat(contours[i]) ); }
     }



参考:

1.https://blog.csdn.net/dcrmg/article/details/51987348

2.http://www.cnblogs.com/skyfsm/p/6890863.html

3.https://blog.csdn.net/qq_18343569/article/details/48000179

4.https://blog.csdn.net/qq_18343569/article/details/47982167

猜你喜欢

转载自blog.csdn.net/qq_42189368/article/details/80851960