OpenCV-Python教程:19.輪廓屬性

1圖像矩

幫你計(jì)算一些屬性,比如重心,面積等。

函數(shù)cv2.moments()會(huì)給你一個(gè)字典,包含所有矩值

import cv2

import numpy as np

img = cv2.imread('star.jpg',0)

ret,thresh = cv2.threshold(img,127,255,0)

contours,hierarchy = cv2.findContours(thresh, 1, 2)

cnt = contours[0]

M = cv2.moments(cnt)

print M

你可以從這個(gè)里面得到有用的數(shù)據(jù)比如面積,重心等。重心可以用下面的式子得到:

cx=int(M['m10']/M['m00'])

cy=int(M['m01']/M['m00'])

2.輪廓面積

輪廓面積由函數(shù)cv2.contourArea()得到或者從矩里得到M['m00']

area=cv2.contourArea(cnt)

3.輪廓周長(zhǎng)

可以用cv2.arcLength()函數(shù)得到。第二個(gè)參數(shù)指定形狀是否是閉合的輪廓(如果傳True)?;蛘咧皇且粋€(gè)曲線。

perimeter=cv2.arcLength(cnt,True)

4.輪廓近似

這會(huì)把輪廓形狀近似成別的邊數(shù)少的形狀,邊數(shù)由我們指定的精確度決定。這是Douglas-Peucker算法的實(shí)現(xiàn)。

要理解這個(gè),假設(shè)你試圖找一個(gè)圖像里的方塊,但是由于圖像里的一些問題,你得不到一個(gè)完美的方塊,只能得到一個(gè)“壞方塊”?,F(xiàn)在你可以使用這個(gè)函數(shù)來(lái)近似,第二個(gè)參數(shù)叫epsilon,是從輪廓到近似輪廓的最大距離。是一個(gè)準(zhǔn)確率參數(shù),好的epsilon的選擇可以得到正確的輸出。

epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)

在下面第二個(gè)圖像里,綠線顯示了epsilon = 10% of arc length 的近似曲線。第三個(gè)圖像顯示了epsilon = 1% of the arc length。第三個(gè)參數(shù)指定曲線是否閉合。

5.凸形外殼

凸形外殼和輪廓近似類似,但是還不一樣(某些情況下兩個(gè)甚至提供了同樣的結(jié)果)。這兒,cv2.convexHull()函數(shù)檢查凸面曲線缺陷并修復(fù)它。一般來(lái)說(shuō),凸面曲線總是外凸的,至少是平的,如果它內(nèi)凹了,這就叫凸面缺陷。比如下面這張圖,紅線顯示了手的凸形外殼。雙向箭頭顯示了凸面缺陷,是輪廓外殼的最大偏差。


hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]]

參數(shù)詳情:

·points 是我們傳入的輪廓
·hull 是輸出,一般我們不用傳
·clockwise: 方向標(biāo)示,如果是True,輸出凸形外殼是順時(shí)針方向的。否則,是逆時(shí)針的。
·returnPoints:默認(rèn)是True。然后會(huì)返回外殼的點(diǎn)的坐標(biāo)。如果為False,它會(huì)返回輪廓對(duì)應(yīng)外殼點(diǎn)的索引。

所以要獲得凸形外殼,下面

hull=cv2.convexHull(cnt)

但是如果你想找到凸面缺陷,你需要傳入returnPoints = False。我們拿上面的矩形圖形來(lái)說(shuō),首先我找到他的輪廓cnt,現(xiàn)在用returnPoints = True來(lái)找他的凸形外殼,我得到下面的值:[[[234 202]], [[51 202]], [51 79]], [[234 79]]] ?是四個(gè)角的點(diǎn)。如果你用returnPoints = False,我會(huì)得到下面的結(jié)果:[[129], [67], [0], [142]]. ?這是輪廓里對(duì)應(yīng)點(diǎn)的索引,比如cnt[129] = [234, 202]],這和前面結(jié)果一樣。

6.檢查凸面

有一個(gè)函數(shù)用來(lái)檢查是否曲線是凸面, cv2.isContourConvex().它返回True或False。

k=cv2.isContourConvex(cnt)

7.邊界矩形

有兩種邊界矩形

7.a.正邊界矩形

這個(gè)矩形不考慮對(duì)象的旋轉(zhuǎn),所以邊界矩形的面積不是最小的,函數(shù)是cv2.boundingRect()。

假設(shè)矩形左上角的坐標(biāo)是(x,y), (w, h)是它的寬和高

x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

7.b.渲染矩形

這個(gè)邊界矩形是用最小面積畫出來(lái)的,所以要考慮旋轉(zhuǎn)。函數(shù)是cv2.minAreaRect()。它返回一個(gè)Box2D結(jié)構(gòu),包含了(左上角(x,y),(width, height),旋轉(zhuǎn)角度)。但是要畫這個(gè)矩形我們需要4個(gè)角。這四個(gè)角用函數(shù)cv2.boxPoints()得到

rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
im = cv2.drawContours(im,[box],0,(0,0,255),2)

8.最小閉包圓

我們找一個(gè)目標(biāo)的外接圓可以用函數(shù)cv2.minEnclosingCircle().這個(gè)圓用最小面積完全包圍目標(biāo)。

(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)

9.橢圓

用一個(gè)橢圓來(lái)匹配目標(biāo)。它返回一個(gè)旋轉(zhuǎn)了的矩形的內(nèi)接橢圓

ellipse=cv2.fitEllipse(cnt)
im=cv2.ellipse(im,ellipse,(0,255,0),2)

10. 直線

類似的我們可以匹配一根直線,下面的圖像包含一系列的白色點(diǎn),我們可以給它一條近似的直線。

rows,cols = img.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
img = cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)


END

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容