OpenCV+python:轮廓发现与对象测量
生活随笔
收集整理的這篇文章主要介紹了
OpenCV+python:轮廓发现与对象测量
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1,輪廓發(fā)現(xiàn)
當通過閾值分割提取到圖像中的目標物體后,就需要通過邊緣檢測來提取目標物體的輪廓,使用這兩種方法基本能夠確定物體的邊緣或者前景。接下來,通常需要做的是擬合這些邊緣的前景,如擬合出包含前景或者邊緣像素點的最小外包矩形、圓、凸包等幾何形狀,為計算它們的面積或者模板匹配等操作打下堅實的基礎。
一個輪廓代表一系列的點(像素),這一系列的點構(gòu)成一個有序的點集,所以可以把一個輪廓理解為一個有序的點集。
輪廓發(fā)現(xiàn)是基于圖像邊緣提取的基礎,尋找對象輪廓的方法,所以邊緣提取的閾值選定會影響最終輪廓的發(fā)現(xiàn)。
2,對象測量
opencv 中輪廓特征包括:如面積,周長,質(zhì)心,邊界框等。
3,輪廓發(fā)現(xiàn)源代碼:
import cv2 as cv
import numpy as npdef edge_demo(image):blurred = cv.GaussianBlur(image, (9, 9), 5)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.imshow("binary image", binary)#直接二值化的圖像#binary = edge_demo(image) #過邊緣處理后的圖像#可以是直接二值化的圖像也可以是經(jīng)過邊緣處理后的圖像(兩種方法視情況而定)#cloneImage, contours, heriachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)contours, hierarchy = cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE) cv.drawContours(image,contours,-1,(0,0,255),3) cv.imshow("detect contours", image)src = cv.imread("F:/images/coin.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
contours_demo(src)
cv.waitKey(0)cv.destroyAllWindows()
運行結(jié)果:
注意:對于cv.findContours:opencv2返回兩個值:contours:hierarchy。注:opencv3會返回三個值,分別是img, countours, hierarchy
4,對象測量源代碼:
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, hierarchy = 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))#字典型數(shù)據(jù)cx = mm['m10']/mm['m00']#原點的零階矩cy = mm['m01']/mm['m00']cv.circle(dst, (np.int(cx), np.int(cy)), 3, (0, 0, 255), -1)##畫出中心點,-1表示填充#cv.rectangle(dst, (x, y), (x+w, y+h), (0, 0, 255), 2)#繪制輪廓的外接矩形print("contour area %s"%area)approxCurve = cv.approxPolyDP(contour,4,True) #多邊形逼近 4是與閾值的間隔大小,越小越易找出,True是是否找閉合圖像"""cv.contourArea(contour) #獲取每個輪廓面積cv.boundingRect(contour) #獲取輪廓的外接矩形cv.moments(contour) #求取輪廓的幾何距cv.arcLength(contour,True) #求取輪廓的周長,指定閉合approxPolyDP(curve, epsilon, closed, approxCurve=None)第一個參數(shù)curve:輸入的點集,直接使用輪廓點集contour第二個參數(shù)epsilon:指定的精度,也即是原始曲線與近似曲線之間的最大距離。第三個參數(shù)closed:若為true,則說明近似曲線是閉合的,反之,若為false,則斷開。第四個參數(shù)approxCurve:輸出的點集,當前點集是能最小包容指定點集的。畫出來即是一個多邊形;print(approxCurve) #打印每個輪廓的特征點print(approxCurve.shape) #打印該點集的shape,第一個數(shù)是代表了點的個數(shù),也就是邊長連接逼近數(shù)"""print(approxCurve.shape)if approxCurve.shape[0] > 6:cv.drawContours(dst, contours, i, (0, 255, 0), 2)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)cv.imshow("measure-contours", dst)src = cv.imread("F:/images/contours.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
measure_object(src)
cv.waitKey(0)cv.destroyAllWindows()
運行結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的OpenCV+python:轮廓发现与对象测量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。