opencv19:轮廓凸包,距离与匹配
目標(biāo)
在本章中,將學(xué)習(xí)
- 凸起缺陷檢測
- 尋找點(diǎn)到多邊形的最短距離
- 匹配不同的形狀
理論和代碼
凸性缺陷(Convexity Defects)
上一節(jié)學(xué)習(xí)了如何尋找輪廓, 凸包上的任何偏差都可以被認(rèn)為是有凸性缺陷。
OpenCV中有一個(gè)函數(shù)來尋找凸包,cv2.convexityDefects()。
注意
必須在發(fā)現(xiàn)凸包時(shí),傳遞returnPoints= False, 返回的是cnt中點(diǎn)的下標(biāo),如果是True時(shí)候,返回的是點(diǎn)的坐標(biāo)。
cv2.convexityDefects返回一個(gè)數(shù)組,其中每行包含這些值[起點(diǎn)、終點(diǎn)、最遠(yuǎn)點(diǎn)、到最遠(yuǎn)點(diǎn)的近似距離]。可以用圖像把它形象化。畫一條連接起點(diǎn)和終點(diǎn)的線,然后在最遠(yuǎn)處畫一個(gè)圓。記住,返回的前三個(gè)值是cnt的索引。必須從cnt中獲取這些值。
import cv2 import numpy as np img = cv2.imread('star.png') img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(img_gray, 127, 255,0) contours,hierarchy = cv2.findContours(thresh,2,1) 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(img,start,end,[0,255,0],2)cv2.circle(img,far,5,[0,0,255],-1) cv2.imshow('img',img) cv2.waitKey(0) cv2.destroyAllWindows()點(diǎn)到多邊形測試
cv2.pointPolygonTest函數(shù)找出圖像中一點(diǎn)到輪廓線的最短距離。它返回的是符號(hào)距離距離(signed distance),點(diǎn)在輪廓線外時(shí)為負(fù),點(diǎn)在輪廓線內(nèi)時(shí)為正,點(diǎn)在輪廓線上時(shí)為零。
可以檢查點(diǎn)(50,50)如下:
dist = cv2.pointPolygonTest(cnt,(50,50),True) # -38.8329756778952在函數(shù)中,第三個(gè)參數(shù)是measureDist。如果它是True,它會(huì)找到有符號(hào)的距離。如果為False,則查找該點(diǎn)是在輪廓線內(nèi)部還是外部(分別返回 1、-1和0)
注意
如果不想知道具體距離,請(qǐng)確保第三個(gè)參數(shù)為False,因?yàn)橛?jì)算距離是一個(gè)耗時(shí)的過程, 設(shè)置為False可使速度提高2-3倍。
形狀匹配
OpenCV附帶一個(gè)函數(shù)cv2.matchShapes(),該函數(shù)能夠比較兩個(gè)形狀或兩個(gè)輪廓,并返回一個(gè)顯示相似性的度量。結(jié)果越低,匹配越好。它是根據(jù)矩值(hu-moment)計(jì)算出來的。不同的測量方法在文檔中有解釋。
# 形狀匹配 import cv2 import numpy as npimg1 = cv2.imread('star.png', 0) img2 = cv2.imread('star2.png', 0) img3 = cv2.imread('approx.png', 0) ret, thresh = cv2.threshold(img1, 127, 250, 0) ret2, thresh2 = cv2.threshold(img2, 127, 250, 0) ret3, thresh3 = cv2.threshold(img3, 127, 250, 0)contours1, hierarchy1 = cv2.findContours(thresh, 2, 1) cnt1 = contours1[0]contours2, hierarchy2 = cv2.findContours(thresh2, 2, 1) cnt2 = contours2[0]contours3, hierarchy3 = cv2.findContours(thresh3, 2, 1) cnt3 = contours3[0]ret1 = cv2.matchShapes(cnt1, cnt2, 1, 0.0) print(ret1) # 0.0101502123705427ret2 = cv2.matchShapes(cnt2, cnt3, 1, 0.0) print(ret2) # 0.9202466744178138嘗試過匹配下面給出的不同形狀的形狀:
得到以下結(jié)果:
- 匹配的圖像A與本身= 0.0
- 匹配圖像A與圖像B =0.0101502123705427
- 匹配圖像A與圖像C = 0.9202466744178138
可以看到,即使是圖像旋轉(zhuǎn)也不會(huì)對(duì)其匹配度產(chǎn)生比較大的影響
說明
Hu Moments(或者相反Hu moment invariants)是一種使用不變的圖像轉(zhuǎn)換的中央矩計(jì)算的一組7個(gè)數(shù)字。前6個(gè)moments被證明是不變的變換,縮放和旋轉(zhuǎn)和反轉(zhuǎn)。第7個(gè)moment表示符號(hào)變化。
附加資源
- https://docs.opencv.org/4.1.2/d5/d45/tutorial_py_contours_more_functions.html
- https://www.jianshu.com/p/42eb9b3957d5
- https://www.cnblogs.com/jclian91/p/9728488.html
- https://learnopencv.com/shape-matching-using-hu-moments-c-python/
總結(jié)
以上是生活随笔為你收集整理的opencv19:轮廓凸包,距离与匹配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iphone11返回上一级手势怎么设置_
- 下一篇: POI 处理word 文档中 文本框模板