opencv进阶学习笔记12:轮廓发现和对象测量
基礎版筆記目錄:
python3+opencv學習筆記匯總目錄(適合基礎入門學習)
進階版筆記目錄鏈接:
python+opencv進階版學習筆記目錄(適合有一定基礎)
輪廓發現
1輪廓發現介紹
基礎版講解:
opencv學習筆記20:圖像輪廓
2輪廓發現API
cv2.findContours()
cv2.drawContours()
通過cv2.findContours() 查找輪廓在哪里,再通過 cv2.drawContours()將查找的輪廓繪制出來。
contours,hierarchy=cv2.findContours(image,mode,method)
contours:輪廓
hierarchy:圖像的拓撲信息(輪廓層次)(存儲上一個輪廓,父輪廓…)
image:二值圖像
mode:輪廓檢索方式
method:輪廓的近似方法
r=cv2.drawContours(image, contours, contourIdx, color[, thickness])
r:目標圖像
image:原始圖像
contours: 所有的輸入輪廓邊緣數組
contourIdx :需要繪制的邊緣索引,如果全部繪制為-1。如果有多個目標,可以繪制第一個目標0,第二個目標1,第三個目標2.。。
color:繪制的顏色,為BGR格式的SCalar
thickness:可選,繪制的密度,即輪廓的畫筆粗細
前面是通過邊緣提取,然后再來尋找輪廓的。
改用
基于圖像二值化方法 來提取
差點意思,還是基于邊緣提取更好。
對象測量
對象測量:對找到的圖像輪廓,計算它弧長與面積,多邊形擬合,幾何矩計算
多邊形擬合API
獲取輪廓的多邊形擬合結果
cv2.approxPolyDP(contour,epsilon,close)
參數:
contour 輪廓
epsilon越小越折線越逼近真實形狀
close – 是否為閉合區域
輸出的是多邊形點集
import cv2 as cv import numpy as npdef measure_object(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)print("threshold value : %s"%ret)#打印閾值cv.imshow("binary image", binary)#顯示二值圖像dst = cv.cvtColor(binary, cv.COLOR_GRAY2BGR)contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):area = cv.contourArea(contour)# 求輪廓面積x, y, w, h = cv.boundingRect(contour)# 求輪廓外接矩形rate = min(w, h)/max(w, h)print("rectangle rate : %s"%rate)#寬高比mm = cv.moments(contour)# 求幾何矩,返回字典類型print(type(mm))# 求得圖形的重心坐標cx = mm['m10']/mm['m00']cy = mm['m01']/mm['m00']cv.circle(dst, (np.int(cx), np.int(cy)), 3, (0, 255, 255), -1)#繪制輪廓中心cv.rectangle(dst, (x, y), (x+w, y+h), (0, 0, 255), 2)#在原圖上,給輪廓繪制矩形print("contour area %s"%area)cv.imshow("measure-contours", dst)print("--------- Python OpenCV Tutorial ---------") src = cv.imread("shuzi.jpg") src=cv.resize(src,None,fx=0.5,fy=0.5) cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) cv.imshow("input image", src) measure_object(src) cv.waitKey(0) cv.destroyAllWindows()計算出啦每個數字的面積,寬高比,可以用于簡單數字識別
注意 原圖中數字為黑色, 需要反二值化 ,使數字為輪廓,因為輪廓為白色
注意事項:有些圖太小時,cx = mm['m10']/mm['m00'] cy = mm['m01']/mm['m00'] 出現分母為0,報錯。所以得首先把圖放大
如src=cv.resize(src,None,fx=1.5,fy=1.5)
算例2
import cv2 as cv import numpy as npdef measure_object(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)print("threshold value : %s"%ret)#打印閾值cv.imshow("binary image", binary)#顯示二值圖像dst = cv.cvtColor(binary, cv.COLOR_GRAY2BGR)contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):area = cv.contourArea(contour)# 求輪廓面積x, y, w, h = cv.boundingRect(contour)# 求輪廓外接矩形rate = min(w, h)/max(w, h)#print("rectangle rate : %s"%rate)mm = cv.moments(contour)# 求幾何矩,返回字典類型print(type(mm))# 求得圖形的重心坐標cx = mm['m10']/mm['m00']cy = mm['m01']/mm['m00']cv.circle(dst, (np.int(cx), np.int(cy)), 3, (0, 255, 255), -1)#繪制輪廓中心#cv.rectangle(dst, (x, y), (x+w, y+h), (0, 0, 255), 2)#print("contour area %s"%area)#輪廓多邊形擬合approxCurve = cv.approxPolyDP(contour,2, True)#print(approxCurve.shape)print(approxCurve.shape)#輪廓擬合if approxCurve.shape[0] > 6:cv.drawContours(dst, contours, i, (0, 255, 0), 2)#i表示第幾個輪廓if approxCurve.shape[0] == 4:cv.drawContours(dst, contours, i, (0, 0, 255), 2)if approxCurve.shape[0] == 3:cv.drawContours(dst, contours, i, (255, 0, 0), 2)cv.imshow("measure-contours", dst) print("--------- Python OpenCV Tutorial ---------") src = cv.imread("duobianxin.jpg") src=cv.resize(src,None,fx=1.5,fy=1.5) cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) cv.imshow("input image", src) measure_object(src) cv.waitKey(0)cv.destroyAllWindows()部分print(approxCurve.shape)數據如下
approxCurve.shape 有三維數據,第一維表示輪廓可以由幾條線繪制出來,如三角形由三條直線就可繪制。如if approxCurve.shape[0] == 3: cv.drawContours(dst, contours, i, (255, 0, 0), 2)
圖中藍色均有3條繪制
同樣要注意圖的大小
電氣專業的計算機萌新,寫博文不容易。如果你覺得本文對你有用,請點個贊支持下,謝謝。
總結
以上是生活随笔為你收集整理的opencv进阶学习笔记12:轮廓发现和对象测量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 空军一号质量怎么样 解析美国总统专机质量
- 下一篇: 夏天有什么美食可以选择呢?