圖像輪廓的獲取可參考博文十七
一、相關原理
1,弧長和面積
對于弧長和面積,計算出來的輪廓單位都是像素
2,多邊形擬合
每一個輪廓都是一系列的點,然后通過多邊形進行擬合,無限的接近真實形狀
相關API:cv.approxPolyDP(contour,4, True)
其中參數一:contour幾何的輪廓
參數二:epsilon表示折線的大小,越小表示越接近真實形狀
參數三:close表示是否為閉合區域,一般默認為True
3,幾何矩計算
前景像素f(x,y)
原點矩:
p+q=0稱為零階矩,p+q=1稱為一階矩
中心距:
中心距已經是中心化之后的值,一般都是從一階矩開始的
圖像的重心坐標:
M10表示一階(1+0=1)
二、將幾何圖像通過矩形框框出,并求出矩形面積
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)outImage, 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)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\number.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
measure_object(src)
cv.waitKey(0)cv.destroyAllWindows()
效果圖如下:
三、識別圓、矩形、三角形并使用不同的顏色進行區分標記輪廓,并出去輪廓面積
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)outImage, 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,4, True)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)print("--------- Python OpenCV Tutorial ---------")
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\by.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
measure_object(src)
cv.waitKey(0)cv.destroyAllWindows()
效果圖如下: