书名:计算机视觉40例从入门到深度学习:OpenCV-Python
作者:李立宗
出版社:电子工业出版社
出版时间:2022-07-01
ISBN:9787121436857
二、理论基础
2、凸缺陷
-
凸包与轮廓之间的部分称为凸缺陷。凸缺陷示意图如图8-4所示,图中的白色四角星是前景,显然,其边缘就是其轮廓,连接四个顶点构成的四边形是其凸包。
-
在图8-4中存在四个凸缺陷,这四个凸缺陷都是由凸包与轮廓之间的部分构成的。
图8-4 凸缺陷示意图 -
凸缺陷可用来处理手势识别等问题。
三、凸缺陷的四个特征值
- 起点:
该特征值用于说明当前凸缺陷的起点位置。需要注意的是,起点值用轮廓索引表示。
也就是说,起点一定是轮廓中的一个点,并且用其在轮廓中的序号来表示。
例如,图8-4中的点A是凸缺陷1的起点。 - 终点:
该特征值用于说明当前凸缺陷的终点位置。该值也是使用轮廓索引表示的。
例如,图8-4中的点B是凸缺陷1的终点。 - 轮廓上距离凸包最远的点。
例如,图8-4中的点C是凸缺陷1中的轮廓上距离凸包最远的点。 - 最远点到凸包的近似距离。
例如,图8-4中的距离D是凸缺陷1中的最远点到凸包的近似距离。
四、函数cv2.convexityDefects()
- 函数cv2.convexityDefects()用来获取凸缺陷
convexityDefects = cv2.convexityDefects(contour,convexhull) - 其中,返回值convexityDefects为凸缺陷点集。它是一个数组,每行包含的值是[起点,终点,轮廓上距离凸包最远的点,最远点到凸包的近似距离]。
- 需要说明的是,返回结果中[起点,终点,轮廓上距离凸包最远的点,最远点到凸包的近似距离]的前三个值是轮廓点的索引,所以需要从轮廓点集中找它们。
- 上述函数的参数如下:
● contour是轮廓。
● convexhull是凸包。
值得注意的是,用函数cv2.convexityDefects()计算凸缺陷时,要使用凸包作为参数。
在查找该凸包时,函数cv2.convexHull()所使用的参数returnPoints的值必须是False。
五、凸缺陷的实践意义
-
凸缺陷具有重要实践意义,在实践中发挥着非常重要的作用。
例如,利用凸缺陷检测各种物体是否存在残缺,如药片是否完整、瓶口是否缺损等。 -
在实践中,不是所有凸缺陷都是有意义的,比如,面积过小的凸缺陷可能没有实际意义。
-
需要将除指缝外的其他凸缺陷处理为噪声,具体可以采用如下方式:
● 若凸缺陷面积相对较小,则将其处理为噪声。
● 若凸缺陷最远点与起点、终点构成的角度大于90°,则将其处理为噪声。因为,人指缝间的角度通常是小于90°的。
● 若一个凸缺陷最远点到凸包的近似距离小,则将其处理为噪声。
六、程序
import cv2
# --------------读取并绘制原始图像------------------
img = cv2.imread('d:\\hand.bmp')
cv2.imshow("original",img)
# --------------提取轮廓------------------
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# --------------凸包------------------
cnt=contours[0]
hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)
print("defects",defects)
# --------------绘制凸包------------------
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
cv2.line(img,start,end,[0,0,255],2)
cv2.circle(img,far,5,[255,0,0],-1)
#----------------显示结果、释放图像--------------------------
cv2.imshow('result',img)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果
打印数据
网友评论