凸包
凸包是指完全包含原有轮廓,并且仅有轮廓上的点所构成的多边形
凸包的每一处都是凸的,在凸包内任意三个连续点的内角小于180度
函数形式:
hull = cv2.convexHull( points [, clockwise[ , returnPoints]])
hull为凸包角点
clockwise布尔型值,凸包角点按顺时针方向排列;该值为False时逆时针排列
returnPoints 布尔型值,默认为True,该函数返回凸包角点的x,y轴坐标,当为False时,函数返回轮廓中凸包角点的索引
1 import cv2 2 o = cv2.imread("hand.bmp") 3 cv2.imshow("original" , o) 4 gray = cv2.cvtColor(o , cv2.COLOR_BGR2GRAY) 5 ret , binary = cv2.threshold(gray , 127 , 255 , cv2.THRESH_BINARY) 6 contours , hierarchy = cv2.findContours(binary , cv2.RETR_LIST , 7 cv2.CHAIN_APPROX_SIMPLE) 8 hull = cv2.convexHull(contours[0]) 9 cv2.polylines(o , [hull] , True , (0,255,0) , 2) 10 cv2.imshow("result" , o) 11 cv2.waitKey() 12 cv2.destroyAllWindows()
绿色的多边形即为凸包,在多边形和手之间的部分为凸缺陷,其可以用来处理手势识别等问题
凸缺陷获取函数
convexityDefects = cv2.convexityDefects( contour , convexHull )
convexityDefects为凸缺点集,包含[ 起点, 终点 , 轮廓上距离凸包最远的点, 最远点到凸包的近似距离]
contour为轮廓
convexHull为凸包
1 import cv2 2 img = cv2.imread("hand.bmp") 3 cv2.imshow("original" , img) 4 gray = cv2.cvtColor(img , cv2.COLOR_BGR2GRAY) 5 ret , binary = cv2.threshold(gray , 127 , 255 ,0) 6 contours , hierarchy = cv2.findContours(binary , cv2.RETR_LIST , 7 cv2.CHAIN_APPROX_SIMPLE) 8 # 9 cnt = contours[0] 10 hull = cv2.convexHull(cnt , returnPoints = False) 11 defects = cv2.convexityDefects(cnt , hull) 12 print("defects = " ,defects) 13 # 14 for i in range(defects.shape[0]): 15 s,e,f,d = defects[i , 0] 16 start = tuple(cnt[s][0]) 17 end = tuple(cnt[e][0]) 18 far = tuple(cnt[f][0]) 19 cv2.line(img , start , end , [0,0,255] , 2) 20 cv2.circle(img , far , 5 , [ 255,0,0] ,-1) 21 # 22 cv2.imshow("result" , img) 23 cv2.waitKey() 24 cv2.destroyAllWindows()
将起点和终点相连,在最远点画一个圆圈
defects = [[[ 305 311 306 114]] [[ 311 385 342 13666]] [[ 385 389 386 395]] [[ 389 489 435 20327]] [[ 0 102 51 21878]] [[ 103 184 150 13876]] [[ 185 233 220 4168]] [[ 233 238 235 256]] [[ 238 240 239 247]] [[ 240 294 255 2715]] [[ 294 302 295 281]] [[ 302 304 303 217]]]