赞
踩
逼近多边形是轮廓的高度近似,但是有时候,我们希望使用一个多边形凸包来简化它,凸包和逼近多边形很想,但是是最外层凸起的多边形。凸包指完全包含原有轮廓,并且仅由轮廓上的点所构成的多边形,凸包每一处都是凸的,
边缘与凸包之间的部分被称为图缺陷,可以用来处理手势识别的问题。
hull = cv2.convexHull( points[, clockwise[, returnPoints]] )
看来懂一点PS 还时有用的。。。
凸包与轮廓之间的部分就是凸缺陷,使用convexityDefects = cv2.convexityDefects( contour, convexhull )
来获取。返回值时凸缺陷点集,是一个数组,每一行包括的值是 [起点,终点,轮廓上距离凸包最远的点,最远点到凸包的近似距离] .另外前三个值都是轮廓点的索引,要到轮廓点中再寻找。参数就是轮廓和凸包。
我那个图不好理解,,,,凸缺陷的点就是两个凸包角点连线,然后轮廓上距离这条线最远的点就是凸缺陷的点
需要注意的是,用 cv2.convexityDefects()计算凸缺陷时,要使用凸包作为参数。在查找该 凸包时,所使用函数cv2.convexHull()的参数 returnPoints 的值必须是 False。
o = cv2.imread('20.jpg') gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnt = contours[0] hull = cv2.convexHull(cnt,returnPoints = False) defects = cv2.convexityDefects(cnt,hull) 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(o,start,end,[0,0,255],2) cv2.circle(o,far,5,[255,0,0],-1) cv2.imshow('result',o) cv2.waitKey(0) cv2.destroyAllWindows()
retval = cv2.isContourConvex( contour )
返回值是布尔值,True表示轮廓是凸的,contour 是判断的轮廓
可以看到逼近多边形就不是凸型的
retval = cv2.pointPolygonTest( contour, pt, measureDist )
用来计算点到多边形轮廓的最短距离(也就是垂线距离),又叫点和多边形的关系测试。
A 点再轮廓外,返回的距离时负值。
用矩比较是一种非常有效的办法,但是现在的shape 模块更厉害就是,,,模块中的形状场景算法可以更高效的比较形状
使用 距离 作为形状比较的度量标准,这是因为形状之间的差异值和距离有相似之处。。。深奥的咱也不懂。。
retval = cv2.createShapeContextDistanceExtractor( [, nAngularBins[, nRadialBins[, innerRadius[, outerRadius[, iterations[, comparer[, transformer]]]]]]] )
使用这个函数计算形状场景距离,使用 形状上下文算法,在每个点上附加一个“形状上下文”描述符,让每个点都能够捕获剩余点相对于它的分布特征,从而提供全局鉴别特征。。。哈哈
返回结果可以通过retval=cv2.ShapeDistanceExtractor.computeDistance(contour1, contour2)
计算两个不同形状之间的距离,参数是两个不同的轮廓。
o1 = cv2.imread('18-1.jpg') cv2.imshow("original1",o1) gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY) ret, binary1 = cv2.threshold(gray1,127,255,cv2.THRESH_BINARY) contours1, hierarchy = cv2.findContours(binary1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnt1 = contours1[0] o2 = cv2.imread('18-2.jpg') cv2.imshow("original2",o2) gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY) ret, binary2 = cv2.threshold(gray2,127,255,cv2.THRESH_BINARY) contours2, hierarchy = cv2.findContours(binary2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnt2 = contours2[0] o3 = cv2.imread('20.jpg') cv2.imshow("original3",o3) gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY) ret, binary3 = cv2.threshold(gray3,127,255,cv2.THRESH_BINARY) contours3, hierarchy = cv2.findContours(binary3, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnt3 = contours3[0] sd = cv2.createShapeContextDistanceExtractor() # 构造距离提取算子,, d1 = sd.computeDistance(cnt1,cnt1) print("与自身的距离 d1=", d1) d2 = sd.computeDistance(cnt1,cnt2) print("与旋转缩放后的自身图像的距离 d2=", d2) d3 = sd.computeDistance(cnt1,cnt3) print("与不相似对象的距离 d3=", d3) cv2.waitKey() cv2.destroyAllWindows() 与自身的距离 d1= 0.0 与旋转缩放后的自身图像的距离 d2= 0.45604294538497925 # 差距很明显,还是matchShapes好啊,就一句话就行,这还要多一句。。 与不相似对象的距离 d3= 24022.529296875
然后还有一个啥 豪斯多夫距离,,,函数换成cv2.createHausdorffDistanceExtractor() 其他一样,至于计算方法,呵呵
轮廓自身的一些属性特征及轮廓所包围对象的特征对于描述图像具有重要意义。所以到底有啥用。。
就是宽度/高度
轮廓面积(对象面积) / 矩形边界面积
轮廓面积(对象面积) / 凸包面积
该值是与轮廓面积相等的圆形的直径
这里圆形的面积与那箭头面积一致。额,视觉欺骗
获取某对象的掩模图像及其对应的点,cv2.drawContours() 的轮廓宽度参数 thickness 设置为-1,可以获取特定对象的实心轮廓,及特定对象的掩模。。另外还可以获取轮廓像素点的具体位置信息。轮廓是图像内非零的像素点,可以通过numpy 函数和opencv 函数获得。
o = cv2.imread('19.jpg') gray = cv2.cvtColor(o,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] mask1 = np.zeros(gray.shape,np.uint8) cv2.drawContours(mask1,[cnt],0,255,2) # 绘制空心轮廓。 pixelpoints1 = np.transpose(np.nonzero(mask1)) print("pixelpoints1.shape=",pixelpoints1.shape) print("pixelpoints1=\n",pixelpoints1) cv2.imshow("mask1",mask1) mask2 = np.zeros(gray.shape,np.uint8) cv2.drawContours(mask2,[cnt],0,255,-1) pixelpoints2 = np.transpose(np.nonzero(mask2)) # 绘制实心轮廓 print("pixelpoints2.shape=",pixelpoints2.shape) print("pixelpoints2=\n",pixelpoints2) cv2.imshow("mask2",mask2) cv2.waitKey() cv2.destroyAllWindows() pixelpoints1.shape= (1569, 2) pixelpoints1= [[206 279] [206 280] [207 278] ... [284 281] [285 279] [285 280]] pixelpoints2.shape= (3280, 2) pixelpoints2= [[207 279] [208 279] [208 280] ... [283 279] [283 280] [284 279]]
idx = cv2.findNonZero( src )
查找非零元素的索引,idx 返回值,表示非零元素的索引位置,注意返回的索引中,每个元素对应的是(列号,行号) 的格式。,src 表示要查找非零元素的图像。mask1 = np.zeros(gray.shape,np.uint8) cv2.drawContours(mask1,[cnt],0,255,2) pixelpoints1 = cv2.findNonZero(mask1) # 就这里不同 print("pixelpoints1.shape=",pixelpoints1.shape) print("pixelpoints1=\n",pixelpoints1) cv2.imshow("mask1",mask1) mask2 = np.zeros(gray.shape,np.uint8) cv2.drawContours(mask2,[cnt],0,255,-1) pixelpoints2 = cv2.findNonZero(mask2) print("pixelpoints2.shape=",pixelpoints2.shape) print("pixelpoints2=\n",pixelpoints2) cv2.imshow("mask2",mask2) cv2.waitKey() cv2.destroyAllWindows() pixelpoints1.shape= (1569, 1, 2) pixelpoints1= [[[279 206]] # 跟上面的结果是到过来的。 [[280 206]] [[278 207]] ... [[281 284]] [[279 285]] [[280 285]]] pixelpoints2.shape= (3280, 1, 2) pixelpoints2= [[[279 207]] [[279 208]] [[280 208]] ... [[279 283]] [[280 283]] [[279 284]]]
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask)
用于再指定对象内查找最大值,最小值及其位置。参数是单通道图像,和掩模,通过使用掩模图像,可以得到掩模指定区域内额最值信息。
注意这个函数处理的是灰度图像,对于彩图,需要提取各个通道图像,为每个通道独立计算。
mean_val = cv2.mean(im,mask = mask)
计算一个对象的平均颜色或平均深度,返回值是返回的平均值,参数就是图像和掩模
# 跟上面那个基本一样,就换一句话。。。
meanVal = cv2.mean(o,mask = mask) # mask 是一个区域,所以必须是单通道的
print("meanVal=\n",meanVal)
meanVal=
(250.5229333855288, 7.352221569778822, 7.29030469106805, 0.0) # cv2.mean 可以计算各个通道的均值,对应RGBA
获取某个对象的极值点,例如最左端,最右端,最上端,最下端四个点。
o = cv2.imread('19.jpg') cv2.imshow("original",o) gray = cv2.cvtColor(o,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] leftmost = tuple(cnt[cnt[:,:,0].argmin()][0]) rightmost = tuple(cnt[cnt[:,:,0].argmax()][0]) # 四个点的计算方式 topmost = tuple(cnt[cnt[:,:,1].argmin()][0]) bottommost = tuple(cnt[cnt[:,:,1].argmax()][0]) print("leftmost=",leftmost) print("rightmost=",rightmost) print("topmost=",topmost) print("bottommost=",bottommost) font=cv2.FONT_HERSHEY_SIMPLEX cv2.putText(o,'A',leftmost, font, 1,(0,0,255),2) cv2.putText(o,'B',rightmost, font, 1,(0,0,255),2) cv2.putText(o,'C',topmost, font, 1,(0,0,255),2) cv2.putText(o,'D',bottommost, font, 1,(0,0,255),2) cv2.imshow("result",o) cv2.waitKey() cv2.destroyAllWindows() leftmost= (151, 239) rightmost= (335, 246) topmost= (279, 207) bottommost= (279, 284)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。