OpenCV(三十五):凸包检测

博客围绕OpenCV中的凸包检测技术展开,介绍了凸包检测的概念,即连接二维平面点集最外层点构成包含所有点的凸边形。还讲解了凸包检测函数convexHull()的参数含义,并给出了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.凸包检测介绍

      凸包检测是计算凸包的一种技术,凸包就是:给定二维平面上的点集,将最外层的点连接起来构成的凸边形,它是包含点集中所有的点。

2.凸包检测函数convexHull()

void cv::convexHull ( InputArray  points,

OutputArray hull,

boolclockwise = false,

bool   returnPoints = true

)

  • points:输入的2D点集
  • hull:输出凸包的顶点
  • clockwise: 方向标志,当参数为true时,凸包顺序为顺时针方向,否则为逆时针方向。returnPoints:输出数据的类型标志,当参数为true时第二个参数输出的结果是凸包顶点的坐标,否则第二个参数输出的结果是凸包顶点的索引。

3.示例代码:


//凸包检测
void Convex_hull_detection(Mat image){
    Mat gray,binary;
    cvtColor(image,gray,COLOR_BGR2GRAY);//灰度化
    threshold(gray,binary,40,255,THRESH_BINARY);//自适应二值化
    //开运算消除细小区域
    Mat k= getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));
    morphologyEx(binary,binary,MORPH_OPEN,k);
    //轮廓的发现与绘制
    vector<vector<Point>> contours;//轮廓
    vector<Vec4i> hierarchy;//存放轮廓结构变量
    findContours(binary,contours,hierarchy,0,2,Point());
   for(int n=0;n<contours.size();n++){
       //计算凸包
       vector<Point> hull;
       convexHull(contours[n],hull);
       //绘制凸包
       for(int i=0;i<hull.size();i++){
           //绘制凸包顶点
           circle(image,hull[i],4,Scalar(255,0,0,255),2,8,0);
           //连接凸包
           if(i==hull.size()-1){
               line(image,hull[i],hull[0],Scalar(0,0,255,255),2,8,0);
               break;
           }
           line(image,hull[i],hull[i-1],Scalar(0,0,255,255),2,8,0);
       }
   }
    imwrite("/sdcard/DCIM/hull.png",image);

}

凸包检测的结果: 

### OpenCV中的凸包检测与图像分割 #### 使用OpenCV进行凸包检测OpenCV中,`cv2.convexHull()` 是用于计算给定轮廓的凸包的主要函数。该函数接受一个轮廓作为输入并返回其对应的凸包点集[^1]。这些点可以用 `cv2.polylines()` 绘制出来以便可视化。 以下是实现凸包检测的一个简单示例: ```python import cv2 import numpy as np # 创建一个空白画布 image = np.zeros((500, 500, 3), dtype=np.uint8) # 定义一些随机点 points = np.array([[200, 10], [250, 50], [300, 10], [275, 100], [225, 90]], dtype=np.int32) # 计算凸包 hull = cv2.convexHull(points) # 将点和凸包绘制到图像上 for point in points: cv2.circle(image, (point[0], point[1]), 5, (0, 0, 255), -1) # 蓝色圆圈标记原始点 cv2.polylines(image, [hull], isClosed=True, color=(0, 255, 0), thickness=2) # 绿线连接凸包 # 显示结果 cv2.imshow('Convex Hull', image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 上述代码展示了如何通过一组二维坐标来找到它们的凸包,并将其显示在一个窗口中[^2]。 #### 基于OTSU阈值化与凸包检测的图像分割 对于更复杂的场景,比如粘连对象的分离,可以结合 OTSU 阈值法和凸包检测技术完成图像分割。下面提供了一个完整的流程实例: ```python import cv2 import numpy as np # 加载灰度图片 img_gray = cv2.imread('rice.jpg', cv2.IMREAD_GRAYSCALE) # 应用 Otsu 方法自动获取最佳阈值 _, img_binary = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 查找外部轮廓 contours, _ = cv2.findContours(img_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 初始化绘图变量 result_img = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR) # 对每个轮廓执行操作 for contour in contours: hull = cv2.convexHull(contour) # 获取当前轮廓的凸包 area = cv2.contourArea(hull) # 测量区域大小 if area > 50: # 过滤掉过小的对象 cv2.drawContours(result_img, [hull], -1, (0, 255, 0), 2) # 绘制绿色边界框 # 展示最终效果 cv2.imshow("Segmented Image", result_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 此脚本首先加载一张灰度图像,接着利用 Otsu 的自适应阈值得到二值化版本,最后遍历所有发现的轮廓并仅保留那些具有较大面积的目标[^3]。 #### 结论 凸包检测不仅能够帮助识别目标物周围的最小包围多边形,而且还能与其他算法相结合解决实际应用问题,例如物体计数或者形态分析等领域都有重要作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值