帝國cms做中英文網(wǎng)站網(wǎng)站設(shè)計(jì)需要什么
目錄
目標(biāo)
1. 特征矩
2、輪廓質(zhì)心
3. 輪廓面積
4. 輪廓周長
5. 輪廓近似
6. 輪廓凸包
7. 邊界矩形
7.1.直角矩形
7.2. 旋轉(zhuǎn)矩形
8. 最小閉合圈
9. 擬合一個橢圓
10. 擬合直線
目標(biāo)
????????在本文中,我們將學(xué)習(xí) - 如何找到輪廓的不同特征,例如面積,周長,質(zhì)心,邊界框等。 - 您將看到大量與輪廓有關(guān)的功能。
1. 特征矩
????????特征矩可以幫助您計(jì)算一些特征,例如物體的質(zhì)心,物體的面積等。請查看特征矩上的維基百科頁面。函數(shù) cv.moments() 提供了所有計(jì)算出的矩值的字典。見下文:
import numpy as np
import cv2 as cv
img = cv.imread('star.jpg',0)
ret,thresh = cv.threshold(img,127,255,0)
contours,hierarchy = cv.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv.moments(cnt)
print( M )
????????從這一刻起,您可以提取有用的數(shù)據(jù),例如面積,質(zhì)心等。
2、輪廓質(zhì)心
????????質(zhì)心由關(guān)系給出,cx=M10/M00?和 cy=M01/M00??梢园凑找韵虏襟E進(jìn)行,第一個示例為簡單的檢測單個輪廓,第二個示例能檢測圖片中的多個輪廓。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])print('輪廓的質(zhì)心坐標(biāo)為:(%d,%d) '%cx %cy)
import cv2
import numpy as np # 讀取圖像
image = cv2.imread('7.jpg') # 轉(zhuǎn)換為灰度圖像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 應(yīng)用閾值來獲取二值圖像
_, thresholded = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 查找輪廓
contours, _ = cv2.findContours(thresholded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 遍歷每個輪廓
for contour in contours: # 計(jì)算輪廓的矩 M = cv2.moments(contour) # 檢查矩是否存在(輪廓不為空) if M["m00"] != 0: # 計(jì)算質(zhì)心 cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) # 在圖像上繪制質(zhì)心 cv2.circle(image, (cX, cY), 5, (255, 0, 0), -1) cv2.putText(image, "centroid", (cX - 25, cY - 25), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2) # 顯示結(jié)果圖像
cv2.imshow('Image with Centroids', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. 輪廓面積
????????輪廓區(qū)域由函數(shù) cv.contourArea() 或從矩?M['m00']?
中給出。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )area = cv.contourArea(cnt)
4. 輪廓周長
????????也稱為弧長??梢允褂?cv.arcLength() 函數(shù)找到它。第二個參數(shù)指定形狀是閉合輪廓(True
)還是曲線。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )perimeter = cv.arcLength(cnt,True)
5. 輪廓近似
????????根據(jù)我們指定的精度,它可以將輪廓形狀近似為頂點(diǎn)數(shù)量較少的其他形狀。它是Douglas-Peucker算法的實(shí)現(xiàn)。檢查維基百科頁面上的算法和演示。
????????為了理解這一點(diǎn),假設(shè)您試圖在圖像中找到一個正方形,但是由于圖像中的某些問題,您沒有得到一個完美的正方形,而是一個“壞形狀”(如下圖所示)?,F(xiàn)在,您可以使用此功能來近似形狀。在這種情況下,第二個參數(shù)稱為epsilon,它是從輪廓到近似輪廓的最大距離。它是一個精度參數(shù)。需要正確選擇epsilon才能獲得正確的輸出。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )epsilon = 0.1*cv.arcLength(cnt,True)
approx = cv.approxPolyDP(cnt,epsilon,True)
????????在第二張圖片中,綠線顯示了ε=弧長的10%時的近似曲線。第三幅圖顯示了ε=弧長度的1%時的情況。第三個參數(shù)指定曲線是否閉合。?
6. 輪廓凸包
????????凸包外觀看起來與輪廓逼近相似,但不相似(在某些情況下兩者可能提供相同的結(jié)果)。在這里,cv.convexHull()函數(shù)檢查曲線是否存在凸凹缺陷并對其進(jìn)行校正。一般而言,凸曲線是始終凸出或至少平坦的曲線。如果在內(nèi)部凸出,則稱為凸度缺陷。例如,檢查下面的手的圖像。紅線顯示手的凸包。雙向箭頭標(biāo)記顯示凸度缺陷,這是凸包與輪廓線之間的局部最大偏差。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )hull = cv.convexHull(cnt)
????????但是,如果要查找凸度缺陷,則需要傳遞returnPoints = False
。為了理解它,我們將拍攝上面的矩形圖像。首先,我發(fā)現(xiàn)它的輪廓為cnt
。現(xiàn)在,我發(fā)現(xiàn)它的帶有returnPoints = True
的凸包,得到以下值:[[[234 202]],[[51 202]],[[51 79]],[[234 79]]]
,它們是四個角 矩形的點(diǎn)?,F(xiàn)在,如果對returnPoints = False
執(zhí)行相同的操作,則會得到以下結(jié)果:[[129],[67],[0],[142]]
。這些是輪廓中相應(yīng)點(diǎn)的索引。例如,檢查第一個值:cnt [129] = [[234,202]]
與第一個結(jié)果相同(對于其他結(jié)果依此類推)。
7. 邊界矩形
有兩種類型的邊界矩形。
7.1.直角矩形
????????它是一個矩形,不考慮物體的旋轉(zhuǎn)。所以邊界矩形的面積不是最小的。它是由函數(shù)cv.boundingRect()找到的。
????????令(x,y)
為矩形的左上角坐標(biāo),而(w,h)
為矩形的寬度和高度。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )x,y,w,h = cv.boundingRect(cnt)
cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
7.2. 旋轉(zhuǎn)矩形
????????這里,邊界矩形是用最小面積繪制的,所以它也考慮了旋轉(zhuǎn)。使用函數(shù)是 cv.minAreaRect()。它返回一個Box2D結(jié)構(gòu),其中包含以下細(xì)節(jié) -(中心(x,y),(寬度,高度),旋轉(zhuǎn)角度)。但要畫出這個矩形,我們需要矩形的四個角。它由函數(shù) cv.boxPoints() 獲得:
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )rect = cv.minAreaRect(cnt)
box = cv.boxPoints(rect)
box = np.int0(box)
cv.drawContours(img,[box],0,(0,0,255),2)
????????兩個矩形都顯示在一張單獨(dú)的圖像中。綠色矩形顯示正常的邊界矩形。紅色矩形是旋轉(zhuǎn)后的矩形。
8. 最小閉合圈
????????接下來,使用函數(shù) cv.minEnclosingCircle() 查找對象的圓周。它是一個以最小面積完全覆蓋物體的圓。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )(x,y),radius = cv.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv.circle(img,center,radius,(0,255,0),2)
?
9. 擬合一個橢圓
????????下一個是把一個橢圓擬合到一個物體上。它返回內(nèi)接橢圓的旋轉(zhuǎn)矩形。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )ellipse = cv.fitEllipse(cnt)
cv.ellipse(img,ellipse,(0,255,0),2)
?
10. 擬合直線
????????同樣,我們可以將一條直線擬合到一組點(diǎn)。下圖包含一組白點(diǎn)。我們可以近似一條直線。
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',0)ret,thresh = cv.threshold(img,127,255,0)contours,hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]M = cv.moments(cnt)
print( M )rows,cols = img.shape[:2]
[vx,vy,x,y] = cv.fitLine(cnt, cv.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)
12. 長寬比
????????它是對象邊界矩形的寬度與高度的比值。
x,y,w,h = cv.boundingRect(cnt)
aspect_ratio = float(w)/h
12. 范圍
????????范圍是輪廓區(qū)域與邊界矩形區(qū)域的比值。
area = cv.contourArea(cnt)
x,y,w,h = cv.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area
13. 堅(jiān)實(shí)度
????????堅(jiān)實(shí)度是等高線面積與其凸包面積之比。
area = cv.contourArea(cnt)
hull = cv.convexHull(cnt)
hull_area = cv.contourArea(hull)
solidity = float(area)/hull_area
14. 等效直徑
????????等效直徑是面積與輪廓面積相同的圓的直徑。
area = cv.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)
15. 取向
????????取向是物體指向的角度。以下方法還給出了主軸和副軸的長度。
(x,y),(MA,ma),angle = cv.fitEllipse(cnt)
16. 掩碼和像素點(diǎn)
????????在某些情況下,我們可能需要構(gòu)成該對象的所有點(diǎn)??梢园凑找韵虏襟E完成:
mask = np.zeros(imgray.shape,np.uint8)
cv.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv.findNonZero(mask)
????????這里提供了兩個方法,一個使用Numpy函數(shù),另一個使用OpenCV函數(shù)(最后的注釋行)。結(jié)果也是一樣的,只是略有不同。Numpy給出的坐標(biāo)是(行、列)
格式,而OpenCV給出的坐標(biāo)是(x,y)
格式。所以基本上答案是可以互換的。注意,row = x, column = y
。
17. 最大值,最小值和它們的位置
????????我們可以使用掩碼圖像找到這些參數(shù)。
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(imgray,mask = mask)
18. 平均顏色或平均強(qiáng)度
????????在這里,我們可以找到對象的平均顏色?;蛘呖梢允腔叶饶J较挛矬w的平均強(qiáng)度。我們再次使用相同的掩碼進(jìn)行此操作。
mean_val = cv.mean(im,mask = mask)
19. 極端點(diǎn)
????????極點(diǎn)是指對象的最頂部,最底部,最右側(cè)和最左側(cè)的點(diǎn)。
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])
????????例如,如果我將其應(yīng)用于印度地圖,則會得到以下結(jié)果:?