opencv 求凸包convexHull()函数解析

一、概念

引自百度:凸包(Convex Hull)是一个计算几何(图形学)中的概念。
在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。X的凸包可以用X内所有点(X1,…Xn)的凸组合来构造.
在二维欧几里得空间中,凸包可想象为一条刚好包著所有点的橡皮圈。
用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。

二、opencv convexHull()函数

1.函数原型

CV_EXPORTS_W void convexHull( InputArray points, OutputArray hull,
                              bool clockwise = false, bool returnPoints = true );

2.参数说明

InputArray:输入的2D点集,可以存储在std::vector或Mat中;
OutputArray:输出凸包。它是存储索引的整数vector,或者是存储点的整数vector。在第一种情况下,凸包元素是原始数组中凸包点的基于0的索引(因为凸包点集是原始点集的子集)。在第二种情况下,凸包元素是凸包点本身。
clockwise:顺时针方向标志。如果它是真的,输出凸包是顺时针方向的。否则,它是逆时针方向的。假设的坐标系的X轴指向右边,Y轴指向上方。
returnPoints:返回点的操作标志。对于矩阵,当标志为真时,函数返回凸包点。否则,它返回凸包点的索引。当输出数组为std::vector时,该标志被忽略,并且输出依赖于vector的类型:std::vector意味着returnPoints=false, std::vector意味着returnPoints=true。

三、代码示例

 vvoid test_convexHull()
 {
    
    
     cv::Mat src;
     src = cv::imread("D:\\QtProject\\Opencv_Example\\convexHull\\convexHull.png", cv::IMREAD_GRAYSCALE);
     if (src.empty()) {
    
    
         cout << "Cannot load image" << endl;
         return;
     }
     cv::imshow("src", src);
     
     cv::Mat binary;
     cv::threshold(src, binary, 50, 255, cv::THRESH_BINARY_INV);

     cv::Mat k55 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(23, 23), cv::Point(-1, -1));
     cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, k55, cv::Point(-1, -1), 3);


     cv::namedWindow("binary",cv::WINDOW_NORMAL);
     cv::imshow("binary", binary);


     std::vector<std::vector<cv::Point> > defectContours;
     std::vector<cv::Vec4i> hierarchyDefect;
     cv::findContours(binary, defectContours, hierarchyDefect, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);

     cv::Mat contours = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));

     std::vector<std::vector<cv::Point> > hull(defectContours.size());
     for (int i = 0; i < defectContours.size(); i++)
     {
    
    
         cv::convexHull(cv::Mat(defectContours[i]), hull[i], false);
     }

     cv::Mat canvas;
     contours.copyTo(canvas);
     for (int i = 0; i < hull.size(); i++)
     {
    
    
         cv::drawContours(contours, defectContours, i, cv::Scalar(255,255,255), 1);
         cv::drawContours(contours, hull, i, cv::Scalar(255,255,0), 1);
     }

     cv::namedWindow("contours",cv::WINDOW_NORMAL);
     cv::imshow("contours", contours);

 }

四、效果

在这里插入图片描述
更多轮廓分析请看文章:
l轮廓特征分析大全

猜你喜欢

转载自blog.csdn.net/weixin_44901043/article/details/123242496#comments_21629074