前言
简易的直线和圆的检测较为简单,当我们面对多边形例如手掌或海星的时候,明显圆和直线就无从下手了。对于形状较为复杂的物体,可以利用凸包近似表示。凸包是图形学中常见的概念,将二维平面上的点集最外层的点连接起来构成凸多边形称为凸包。虽然凸包检测也是对轮廓进行多边形逼近,但是逼近的结果一定是凸多边形。
一.convexHull说明
convexHull(InputArray points, OutPutArray hull, bool clockwise = false, bool returnPoints = true)
points: 输入的二维点集或轮廓坐标.
hull: 输出凸包的顶点
clockwise方向标志。当参数值为Ture时,凸包顺序为顺时针方向,当参数取值为False时为逆时针
returnPoints 输出数据的类型标志。当参数为True时,第二个参数输出的结果是凸包顶点坐标;当参数取值为Flase时间,第二个参数输出的结果是凸包顶点的索引。
二.凸包检测流程
2.1 输入图像(三通道或单通道)
2.2 图像二值化(三通道2单通道再二值化)
2.3 开运算消除细小区域
2.4 轮廓发现
----2.4.1 计算凸包
----2.4.2 绘制凸包
----2.4.3 绘制凸包顶点
----2.4.4 连接凸包
2.5 展示图像
三 demo:
示例图像:
大家可以根据自己的手,选择合适的参数进行凸包检测
import cv2 img = cv2.imread('0.jpg') # 读入图像 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 图像灰度化 dst_img = cv2.equalizeHist(gray_img)# 应用直方图均衡化 gaussian_img = cv2.GaussianBlur(dst_img, (11, 11), 0)# 高斯滤波降噪 ret, thresh_img = cv2.threshold(gaussian_img, 90, 255, cv2.THRESH_BINARY) # 二值化,取阈值为235 dst_thresh_img = cv2.bitwise_not(thresh_img) # 二值图像取反 # kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1)) # 设置核 opening_img = cv2.morphologyEx(dst_thresh_img, cv2.MORPH_OPEN, kernel) # 开运算 _, contours, hierarchy = cv2.findContours(opening_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnt = contours[0] for c in range(len(contours)): # 是否为凸包 ret = cv2.isContourConvex(contours[c]) # 凸包检测 points = cv2.convexHull(contours[c]) total = len(points) for i in range(len(points)): x1, y1 = points[i % total][0] x2, y2 = points[(i+1) % total][0] cv2.circle(img, (x1, y1), 4, (255, 0, 0), 2, 8, 0) cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2, 8, 0) # 显示 cv2.imshow("contours", img) cv2.waitKey(0) cv2.destroyAllWindows()