日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv进阶学习笔记12:轮廓发现和对象测量

發布時間:2024/9/30 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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:可選,繪制的密度,即輪廓的畫筆粗細

import cv2 as cv import numpy as np#邊緣提取 def edge_demo(image):blurred = cv.GaussianBlur(image, (3, 3), 0)#去噪gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)# X Gradientxgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0)# Y Gradientygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1)#edge#edge_output = cv.Canny(xgrad, ygrad, 50, 150)edge_output = cv.Canny(gray, 30, 100)cv.imshow("Canny Edge", edge_output)return edge_outputdef contours_demo(image):"""dst = cv.GaussianBlur(image, (3, 3), 0)gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)#cv.THRESH_OTSU自動尋找閾值cv.imshow("binary image", binary)"""binary = edge_demo(image)#邊緣提取后的二值圖像contours, heriachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):cv.drawContours(image, contours, i, (0, 0, 255), 2)cv.imshow("detect contours", image) print("--------- Python OpenCV Tutorial ---------") src = cv.imread("daqiu.jpg") cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) cv.imshow("input image", src) contours_demo(src) cv.waitKey(0) cv.destroyAllWindows()

前面是通過邊緣提取,然后再來尋找輪廓的。

改用
基于圖像二值化方法 來提取

def contours_demo(image):dst = cv.GaussianBlur(image, (3, 3), 0)gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)#cv.THRESH_OTSU自動尋找閾值cv.imshow("binary image", binary)#binary = edge_demo(image)#邊緣提取后的二值圖像contours, heriachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):cv.drawContours(image, contours, i, (0, 0, 255), 2)cv.imshow("detect contours", image)

差點意思,還是基于邊緣提取更好。

對象測量

對象測量:對找到的圖像輪廓,計算它弧長與面積,多邊形擬合,幾何矩計算

多邊形擬合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:轮廓发现和对象测量的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。