17.OpenCV的影像輪廓——輪廓特征
文章目錄
- 前言
- 一、輪廓的矩
- 二、輪廓的面積
- 三、輪廓的長度
- 四、輪廓的近似多邊形
- 五、輪廓的凸包
- 六、輪廓的直邊界矩形
- 七、輪廓的旋轉矩形
- 八、輪廓的最小外包圓
- 九、輪廓的擬合橢圓
- 十、輪廓的擬合直線
- 十一、輪廓的最小外包三角形
- 十二、OpenCV-Python資源下載
- 總結
前言
??影像輪廓是指由位于邊緣、連續的、具有相同顏色和強度的點構成的曲線,它可以用于形狀分析以及物件檢測和識別,
一、輪廓的矩
??輪廓的矩包含了輪廓的各種幾何特征,如面積、位置、角度、形狀等,cv2.moments()函式用于回傳輪廓的矩,其基本格式如下:
ret = cv2.moments(array[, binaryImage])
ret為回傳的輪廓的矩,是一個字典物件, 大多數矩的含義比較抽象, 但其中的零階矩(m00)表示輪廓的面積
array為表示輪廓的陣列
binaryImage值為True時,會將array物件中的所有非0值設定為1
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('shape2.jpg')
cv2.imshow('original', img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
img1 = cv2.drawContours(img1, contours, -1,(0,255,0),2)
cv2.imshow('Contours',img1)
m0 = cv2.moments(contours[0])
m1 = cv2.moments(contours[1])
print('輪廓0的矩:', m0)
print('輪廓1的矩:', m1)
print('輪廓0的面積:', m0['m00'])
print('輪廓1的面積:', m1['m00'])
cv2.waitKey(0)
cv2.destroyAllWindows()


二、輪廓的面積
??cv2.contourArea()函式用于回傳輪廓的面積,其基本格式如下:
ret = cv2.contourArea(contour[, oriented])
ret為回傳的面積
contour為輪廓
oriented為可選引數, 其引數值為True時, 回傳值的正與負表示表示輪廓是順時針還是逆時針, 引數值為False(默認值)時, 函式回傳值為絕對值
img = cv2.imread('shape2.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
m0 = cv2.contourArea(contours[0])
m1 = cv2.contourArea(contours[1])
print('輪廓0的面積:', m0)
print('輪廓1的面積:', m1)

三、輪廓的長度
??cv2.arcLength()函式用于回傳輪廓的長度,其基本格式如下:
ret = cv2.cv2.arcLength(contour, closed)
ret為回傳的長度
contour為輪廓
closed為布林值, 為True時表示輪廓是封閉的
img = cv2.imread('shape2.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
m0 = cv2.arcLength(contours[0], True)
m1 = cv2.arcLength(contours[1], True)
print('輪廓0的長度:', m0)
print('輪廓1的長度:', m1)

四、輪廓的近似多邊形
??cv2.approxPolyDP()函式用于回傳輪廓的近似多邊形,其基本格式如下:
ret = cv2.cv2.arcLength(contour, epsilon, closed)
ret為回傳的近似多邊形
contour為輪廓
epsilon為精度, 表示近似多邊形接近輪廓的最大距離
closed為布林值, 為True時表示輪廓是封閉的
img = cv2.imread('shape3.jpg')
cv2.imshow('original', img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
img1 = cv2.drawContours(img1, contours, -1, (0,0,255), 2)
cv2.imshow('Contours',img1)
arcl = cv2.arcLength(contours[0], True)
img2 = img1.copy()
app = cv2.approxPolyDP(contours[0], arcl*0.05, True)
img2 = cv2.drawContours(img2, [app], -1, (255,0,0), 2)
cv2.imshow('contours',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

五、輪廓的凸包
??cv2.convexHull()函式用于回傳輪廓的凸包,其基本格式如下:
hull = cv2.convexHull(contours[, clockwise[, returnPointss]])
hull為回傳的凸包, 是一個numpy.ndarray物件, 包含了凸包的關鍵點
contours為輪廓
clockwise為方向標記, 為True時, 凸包為順時針方向, 為False(默認值)時, 凸包為逆時針方向
returnPointss為True時(默認值)時, 回傳的hull中包含的是凸包關鍵點的坐標, 為False時, 回傳的是凸包關鍵點在輪廓中的索引
img = cv2.imread('shape3.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
img1 = cv2.drawContours(img1, contours, -1, (0,0,255), 2)
cv2.imshow('Contours',img1)
hull = cv2.convexHull(contours[0])
print('returnPoints = Treu 時回傳的凸包;\n',hull)
hull2 = cv2.convexHull(contours[0], returnPoints=False)
print('returnPoints = False時回傳的凸包;\n',hull2)
cv2.polylines(img1, [hull], True, (255,0,0),2)
cv2.imshow('ConvecHull',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()


六、輪廓的直邊界矩形
??輪廓的直邊界矩形是指可容納輪廓的矩形,且矩形的兩條邊必須是平行的,直邊界矩形不一定是面積最小的邊界矩形,
??cv2.boundingRect()函式用于回傳輪廓的直邊界矩形,其基本格式如下:
ret = cv2.boundingRect(contours)
ret為回傳的直邊界矩形, 它是一個四元組, 其格式為(矩形左上角x坐標, 矩形左上角y坐標, 矩形的寬度, 矩形的高度)
contours為用于計算直邊界矩形的輪廓
img = cv2.imread('shape4.jpg')
cv2.imshow('original', img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
img1 = cv2.drawContours(img1, contours, -1, (0,0,255), 2)
cv2.imshow('Contours',img1)
ret = cv2.boundingRect(contours[0])
print('直邊界矩形:\n', ret)
pt1 = (ret[0], ret[1])
pt2 = (ret[0] + ret[2], ret[1] + ret[3])
img2 = img1.copy()
img2 = cv2.rectangle(img2, pt1, pt2, (255,0,0), 1)
cv2.imshow('Rectangle', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()


七、輪廓的旋轉矩形
??輪廓的旋轉矩形是指可容納輪廓的面積最小的矩形,
??cv2.minAreaRect()函式用于回傳輪廓的旋轉矩形,其基本格式如下:
box = cv2.minAreaRect(contour)
box為回傳的旋轉矩陣, 它是一個三元組, 其格式為((矩形中心點x坐標, 矩形中心點y坐標), (矩形的寬度, 矩形的高度), 矩形的旋轉角度)
contour為用于計算矩形的輪廓
??cv2.minAreaRect()函式回傳的結果不能直接用于繪制旋轉矩形,可以使用cv2.boxPoints()函式將其轉換為矩形的頂點坐標,其基本格式如下:
points = cv2.boxPoints(box)
points為回傳的矩形頂點坐標, 坐標資料為浮點數
box為cv2.minAreaRect()函式回傳的矩形資料
img = cv2.imread('shape4.jpg')
cv2.imshow('original', img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
cv2.drawContours(img1, contours, -1, (0,0,255) ,2)
cv2.imshow('Contours',img1)
# 計算最小旋轉矩形
ret = cv2.minAreaRect(contours[0])
rect = cv2.boxPoints(ret)
rect = np.int0(rect)
img2 = img1.copy()
cv2.drawContours(img2, [rect], 0, (255,0,0), 2)
cv2.imshow('Rectangle', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

八、輪廓的最小外包圓
??cv2.minEnclosingCircle()函式用于回傳可容納輪廓的最小外包圓,其基本格式如下:
center, radius = cv2.minEnclosingCircle(contours)
center為圓心
radius為半徑
contours為用于計算最小外包圓的輪廓
img = cv2.imread('shape4.jpg')
cv2.imshow('original', img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
cv2.drawContours(img1, contours, -1, (0,0,255) ,2)
cv2.imshow('Contours',img1)
# 計算最小外包圓
(x, y), radius = cv2.minEnclosingCircle(contours[0])
center = (int(x),int(y))
radius = int(radius)
img2 = img1.copy()
cv2.circle(img2, center, radius, (255,0,0),2)
cv2.imshow('Circle',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

九、輪廓的擬合橢圓
??cv2.fitEllipse()函式用于回傳輪廓的擬合橢圓,其基本格式如下:
ellipse = cv2.fitEllipse(contours)
ellipse為回傳的橢圓
contours為用于計算擬合橢圓的輪廓
img = cv2.imread('shape4.jpg')
cv2.imshow('original', img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
cv2.drawContours(img1, contours, -1, (0,0,255) ,2)
cv2.imshow('Contours',img1)
# 計算擬合橢圓
ellipse = cv2.fitEllipse(contours[0])
img2 = img1.copy()
cv2.ellipse(img2, ellipse, (255,0,0),2)
cv2.imshow('Circle',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

十、輪廓的擬合直線
??cv2.fitLine()函式用于回傳輪廓的擬合直線,其基本格式如下:
line = cv2.fitLine(contours, distType, param, reps, aeps)
line為回傳的擬合直線
contours為用于計算擬合直線的輪廓
distType為距離引數型別, 決定如何計算擬合直線
param為距離引數, 與距離引數型別有關, 其設定為0時, 函式將自動選擇最優值
reps為計算擬合直線需要的徑向精度, 通常設定為0.01
aeps為計算擬合直線需要的軸向精度, 通常設定為0.01
??param距離引數型別:
| param | 說明 |
|---|---|
| cv2.DIST_USER | 用戶自定義距離 |
| cv2.DIST_L1 | 用2個點的坐標計算計算距離, 公式為|x1-x2|+|y1-y2| |
| cv2.DIST_L2 | 歐氏距離(兩個點的直線距離) |
| cv2.DIST_C | 用2個點的坐標計算計算距離, 公式為max(|x1-x2|,|y1-y2|) |
| cv2.DIST_L12 | 用1個點的坐標計算計算距離, 公式為2(sqrt(1+x*x/2)-1) |
| cv2.DIST_FAIR | 用1個點的坐標計算計算距離, 公式為c^2(|x|/c-log(1+|x|/c)), c=1.3998 |
| cv2.DIST_WELSCH | 用1個點的坐標計算計算距離, 公式為c^2/2(1-exp(-(x/c)^2), c=2.9846 |
| cv2.DIST_HUBER | 用1個點的坐標計算計算距離, 公式為|x|<c?x^2/2:c(|x|-c/2), c=1.345 |
img = cv2.imread('shape4.jpg')
cv2.imshow('original', img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
cv2.drawContours(img1, contours, -1, (0,0,255), 2)
cv2.imshow('Contours',img1)
#計算擬合直線
img2 = img1.copy()
rows, cols = img.shape[:2]
[vx, vy, x, y] = cv2.fitLine(contours[0], cv2.DIST_L1, 0, 0.01, 0.01)
lefty = int((-x * vy / vx) + y)
righty = int(((cols - x) * vy / vx) + y)
cv2.line(img2, (0, lefty), (cols-1, righty), (255,0,0), 2)
cv2.imshow('FitLine',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

十一、輪廓的最小外包三角形
??cv2.minEnclosingTriangle()函式用于回傳可容納輪廓的最小外包三角形,其基本格式如下:
retval, triangle = cv2.minEnclosingTriangle(contours)
retval為最小外包三角形的面積
triangle為最小外包三角形
contours為用于計算最小外包三角形的輪廓
img = cv2.imread('shape4.jpg')
cv2.imshow('original', img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img1 = np.zeros(img.shape, np.uint8) + 255
cv2.drawContours(img1, contours, -1, (0,0,255) ,2)
cv2.imshow('Contours',img1)
# 計算最小外包三角形
retval, triangle = cv2.minEnclosingTriangle(contours[0])
triangle = np.int0(triangle)
img2 = img1.copy()
cv2.polylines(img2, [triangle], True, (255,0,0),2)
cv2.imshow('Triangle',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

十二、OpenCV-Python資源下載
OpenCV-Python測驗用圖片、中文官方檔案、opencv-4.5.4原始碼
總結
??以上內容介紹了OpenCV-Python的輪廓特征,有關Python、資料科學、人工智能等文章后續會不定期發布,請大家多多關注,一鍵三連喲(●’?’●),
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/388037.html
標籤:其他
