理論和代碼
1.凸面缺陷
OpenCV提供了現(xiàn)成的函數(shù)來做這個(gè)挠说,cv2.convexityDefects().
hull=cv2.convexHull(cnt,returnPoints=False)
defects=cv2.convexityDefects(cnt,hull)
注意:
我們要傳returnPoints = False來找凸形外殼。
它返回了一個(gè)數(shù)組,每行包含這些值:[start point, end point, farthest point, approximate distance to farthest point].我們可以用圖像來顯示他們。我們畫根線把start point和end point連起來。然后畫一個(gè)圓在最遠(yuǎn)點(diǎn)旗扑。記住最前三個(gè)返回值是cnt的索引,所以我們我們得從cnt里拿出這些值
import cv2
import numpy as np
img = cv2.imread('star.jpg')
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()
結(jié)果:
2.Point Polygon Test
這個(gè)函數(shù)找到圖像里的點(diǎn)和輪廓之間的最短距離慈省。它返回的距離當(dāng)點(diǎn)在輪廓外的時(shí)候是負(fù)值臀防,當(dāng)點(diǎn)在輪廓內(nèi)是正值,如果在輪廓上是0
比如边败,我們可以檢查(50袱衷, 50)這個(gè)點(diǎn):
dist=cv2.pointPolygonTest(cnt,(50,50),True)
在這個(gè)函數(shù)里,第三個(gè)參數(shù)是measureDist, 如果為True笑窜,是找?guī)Х?hào)的距離致燥。如果為False,會(huì)找點(diǎn)是否在內(nèi)排截,外嫌蚤,或輪廓上(會(huì)相應(yīng)返回+1, -1, 0)
注意:
如果你不想找距離,確保第三個(gè)參數(shù)是False断傲,因?yàn)橥阎ǎ@是個(gè)耗時(shí)的處理。所以认罩,用False會(huì)得到2-3倍的提速
3.匹配形狀
OpenCV提供一個(gè)函數(shù)cv2.matchShapes()來讓我們可以比較兩個(gè)形狀箱蝠,或者兩個(gè)輪廓來返回一個(gè)量表示相似度。結(jié)果越低,越相似抡锈,它是根據(jù)hu矩來計(jì)算的疾忍。不同的計(jì)算方法在文檔里有介紹。
import cv2
import numpy as npimg1 = cv2.imread('star.jpg',0)
img2 = cv2.imread('star2.jpg',0)ret, thresh = cv2.threshold(img1, 127, 255,0)
ret, thresh2 = cv2.threshold(img2, 127, 255,0)
contours,hierarchy = cv2.findContours(thresh,2,1)
cnt1 = contours[0]
contours,hierarchy = cv2.findContours(thresh2,2,1)
cnt2 = contours[0]ret = cv2.matchShapes(cnt1,cnt2,1,0.0)
print ret
嘗試匹配一下圖形:
得到的結(jié)果如下:
·用圖形A和自己比較床三,得到0.0
·用圖形A和B匹配一罩,得到0.001946
·用A匹配C = 0.326911