文章目錄
- 目錄說明
- contours_begin
- 目標
- 什么是輪廓?
- 如何畫等高線?
- 輪廓逼近法
- contour_features
- 目標
- 1.Moments 時刻
- 2. Contour Area 輪廓面積
- 3. Contour Perimeter 輪廓周長
- 4. Contour Approximation 輪廓近似
- 5. Convex Hull 凸包
- 6. Checking Convexity 檢查凸性
- 7. Bounding Rectangle 邊界矩形
- 7.a. Straight Bounding Rectangle 直邊界矩形
- 7.b. Rotated Rectangle 旋轉的矩形
- 8. Minimum Enclosing Circle 最小外圈
- 9. Fitting an Ellipse 擬合橢圓
- 10. Fitting a Line 擬合直線
- contour_properties
- 1. Aspect Ratio 縱橫比
- 2.Extent 范圍
- 3.Solidity 堅固度
- 4. Equivalent Diameter 等效直徑
- 5. Orientation 方向
- 6. Mask and Pixel Points 蒙版和像素點
- 7. Maximum Value, Minimum Value and their locations 最大值,最小值和它們的位置
- 8. Mean Color or Mean Intensity 平均顏色或平均強度
- 9. Extreme Points 極端點
- contours_more_functions
- 目標
- 理論與代碼
- 1.凸性缺陷
- 2.點多邊形檢驗
- 3.匹配的形狀
- contours_hierarchy
- 目標
- 理論
- 什么是層級?
- OpenCV中的層次表示
- 輪廓線檢索模式
- 1. RETR_LIST
- 2. RETR_EXTERNAL
- 3. RETR_CCOMP
- 4. RETR_TREE
源碼目錄:opencv-4.6.0\doc\py_tutorials\py_imgproc\py_contours
目錄說明
-
tutorial_py_contours_begin
Learn to find and draw Contours
學習查找和繪制輪廓 -
tutorial_py_contour_features
Learn to find different features of contours like area, perimeter, bounding rectangle etc.
學習尋找不同的輪廓特征,如面積,周長,邊界矩形等。 -
tutorial_py_contour_properties
Learn to find different properties of contours like Solidity, Mean Intensity etc.
學習找到不同的屬性的輪廓,如固體,平均強度等。 -
tutorial_py_contours_more_functions
Learn to find convexity defects, pointPolygonTest, match different shapes etc.
學習查找凹凸缺陷,pointPolygonTest,匹配不同形狀等。 -
tutorial_py_contours_hierarchy
Learn about Contour Hierarchy
了解輪廓層次
contours_begin
目標
- 了解輪廓是什么。
- 學習尋找輪廓,繪制輪廓等
- 你會看到這些函數:cv.findContours(), cv.drawContours()
什么是輪廓?
輪廓可以簡單地解釋為連接所有連續點(沿著邊界)的曲線,具有相同的顏色或強度。輪廓是形狀分析和目標檢測與識別的有用工具。
- 為了更好的精度,使用二值圖像。因此,在找到輪廓之前,應用閾值或canny邊緣檢測。
- 自OpenCV 3.2, findContours()不再修改源圖像。
- 在OpenCV中,尋找輪廓就像從黑色背景中尋找白色物體一樣。記住,要找到的對象應該是白色的,背景應該是黑色的。
讓我們看看如何找到二值圖像的輪廓:
import numpy as np
import cv2 as cvim = cv.imread('test.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
在 cv.findContours() 函數中有三個參數,第一個是源圖像,第二個是輪廓檢索方式,第三個是輪廓逼近方法。它輸出輪廓和層次結構。Contours是圖像中所有輪廓的Python列表。每個單獨的輪廓是物體邊界點的(x,y)坐標的Numpy數組。
我們將在后面詳細討論第二個和第三個參數以及層次結構。在此之前,代碼示例中給出的值將適用于所有圖像。
如何畫等高線?
使用cv.drawContours函數繪制輪廓.它也可以用來繪制任何形狀,只要你有它的邊界點。它的第一個參數是源圖像,第二個參數是應該作為Python列表傳遞的輪廓,第三個參數是輪廓的索引(在繪制單個輪廓時很有用)。要繪制所有輪廓,傳遞-1),剩下的參數是顏色,厚度等。
- 繪制圖像中的所有輪廓:
drawContours(img, contours, -1, (0,255,0), 3) - 要畫一個單獨的輪廓,如第四個輪廓:
drawContours(img, contours, 3, (0,255,0), 3) - 但大多數時候,下面的方法將是有用的:
cnt = contours[4]
cv.drawContours(img, [cnt], 0, (0,255,0), 3)
最后兩個方法是相同的,但當你繼續,你會發現最后一個更有用。
輪廓逼近法
cv.findContours函數的第三個參數它實際上表示什么?
上面我們說過,輪廓是具有相同強度的形狀的邊界。它存儲形狀邊界的(x,y)坐標。但是它能存儲所有的坐標嗎?這是由輪廓近似法確定的。
如果你傳遞了cv.CHAIN_APPROX_NONE,存儲所有邊界點。但實際上我們需要所有的點嗎?例如,你找到了一條直線的輪廓。是否需要直線上的所有點來表示這條直線?不,我們只需要這條線的兩個端點。這就是cv.CHAIN_APPROX_SIMPLE。它去除所有冗余點并壓縮輪廓,從而節省內存。
下面的矩形圖演示了這種技術。只需在輪廓數組中的所有坐標上畫一個圓(用藍色繪制)。第一張圖片顯示了我用cv.CHAIN_APPROX_NONE得到的(734點)和第二張圖像顯示了cv.CHAIN_APPROX_SIMPLE(只有4點)。看,它節省了多少內存!
效果圖:
完整代碼:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltim = cv.imread('black-white.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
contours_all, hierarchy_all = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
print(len(contours), len(contours[0]))
print(len(contours_all), len(contours_all[0]))
img1 = im.copy()
img2 = im.copy()
for pos in contours[0]:cv.circle(img1, pos[0], 3, (0,255,0), -1)
for pos in contours_all[0]:cv.circle(img2, pos[0], 3, (0,255,0), -1)plt.subplot(221),plt.imshow(im),plt.title('Original')
plt.subplot(222),plt.imshow(img1),plt.title('cv.CHAIN_APPROX_SIMPLE')
plt.subplot(223),plt.imshow(img2),plt.title('cv.CHAIN_APPROX_NONE')plt.show()
contour_features
目標
在本文中,我們將學習
- 查找輪廓的不同特征,如面積,周長,質心,邊界框等
- 你會看到很多與輪廓相關的函數。
1.Moments 時刻
圖像矩幫助你計算一些特征,如物體的質心,物體的面積等。查看維基百科頁面Image Moments
函數 cv.moments() 給出了計算出的所有矩值的字典。見下文:
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',