【python-opencv】對象測量


 opencv 中輪廓特征包括:

 如面積,周長,質心,邊界框等

*弧長與面積測量

*多邊形擬合

*獲取輪廓的多邊形擬合結果

python-opencv API提供方法:

cv2.moments()用來計算圖像中的中心矩(最高到三階),

cv2.HuMoments()用於由中心矩計算Hu矩,

同時配合函數cv2.contourArea()函數計算輪廓面積

cv2.arcLength()來計算輪廓或曲線長度

*cv.approxPolyDP

-contour

-epsilon 越小越折  線越逼近真實形狀 

-close 是否為閉合區域 

函數cv2.boundingRect返回四個參數(x,y)為矩形左上角的坐標,(w,h)是矩形的寬和高。 函數cv2.rectangle是繪制矩形函數 

函數cv2.minAreaRect返回的是一個 Box2D 結構,

其中包含 :矩形左上角角點的坐標(x,y),矩形的寬和高(w,h),以及旋轉角度。

但是要繪制這個矩形需要矩形的 4 個角點,可以通過函數 cv2.boxPoints() 獲得,最后繪制得到旋轉邊界矩形。 

函數cv2.minEnclosingCircle可以幫我們找到一個對象的外切圓。它是所有能夠完全包括對象的圓中面積最小的一個。 
函數cv2.fitEllipse返回值其實就是旋轉邊界矩形的內切圓

 

*幾何矩計算

一幅M×N的數字圖像ƒ(i,j),其p+q階 幾何矩mpq 和 中心矩 μpq為:

 

p+q = 0 為0階矩

p+q = 1 為1階矩

p+q = 2 為2階矩

。。。

其中ƒ(i,j)為圖像在坐標點(i,j)處的灰度值。

 

 

 

多邊形擬合(應用:選擇圖片中幾何體形狀)

 

        """
        approxPolyDP(curve, epsilon, closed[, approxCurve]) -> approxCurve
        curve-擬合曲線
        epsilon-擬合曲線條數(int)
        closed-擬合曲線是否閉合(True or False)
        多邊形擬合
        """
        approxCurve = cv.approxPolyDP(contour,10,True)
        print(approxCurve.shape)
        #畫輪廓多邊形擬合數目>6的圖形輪廓為紅色
        if approxCurve.shape[0] > 6:
            cv.drawContours(dst,contours,i,(0,0,255),2)
        ##畫輪廓多邊形擬合數目=4的圖形輪廓為綠色
        elif approxCurve.shape[0] == 4:
            cv.drawContours(dst,contours,i,(0,255,0),2)
        # 畫輪廓多邊形擬合數目=3的圖形輪廓為藍
        elif approxCurve.shape[0] == 3:
            cv.drawContours(dst,contours,i,(255,0,0),2)
        # 畫其余數目的輪廓多邊形擬合的圖形輪廓為黃色
        else:
            cv.drawContours(dst,contours,i,(0,255,255),2)

 

 

求圖形幾何矩中心 並求最小外接矩形

源碼:

 1 def measure_object(img):
 2     #img轉為灰度圖gary
 3     gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
 4     #灰度圖gary轉為二值圖(黑白圖)--->輸出ret 閾值、binary 二值圖
 5     ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
 6     print("threshold value:",ret)
 7     cv.imshow("binary img", binary)
 8     # 找二值圖binary的輪廓,cv.RETR_EXTERNAL(只檢索外部輪廓)、cv.RETR_TREE(檢索全部輪廓)
 9     outImg, contours, hireachy = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
10     dst = cv.cvtColor(binary,cv.COLOR_GRAY2BGR)
11     #遍歷全部輪廓
12     for i, contour in enumerate(contours):
13         # 輪廓面積
14         area = cv.contourArea(contour)
15         # 輪廓外接矩形面積
16         x, y, w, h = cv.boundingRect(contour)
17         # 幾何矩
18         mm = cv.moments(contour)
19         # print(type(mm))   #mm是字典類型
20         #獲得中心矩
21         if mm['m00']:
22             cx = mm['m10'] / mm['m00']
23             cy = mm['m01'] / mm['m00']
24         else:
25             continue
26 
27         """
28         circle(img, center, radius, color[, thickness[, lineType[, shift]]]) -> img
29         #在原圖img上繪制圓(圓心np.int(cx), np.int(cy))
30         半徑 3 ,顏色(0,255,0)綠,線寬2(如果為負數則填充)
31         """
32         cv.circle(dst,(np.int(cx), np.int(cy)), 3, (0, 255, 255), -1)
33         # center, radius = cv.minEnclosingCircle((np.int(cx), np.int(cy)))
34         # cv.circle(img, center, radius, (0, 255, 255), 2)
35 
36         """
37         rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img
38         在原圖img上繪制外接矩形 ,左上角端點坐標(x, y),寬高(x + w, y + h)
39         顏色(0,0,255),線寬2(如果為負數則填充)
40         """
41         cv.rectangle(dst, (x, y), (x + w, y + h), (0, 0, 255), 2)
42 
43         """
44         繪制輪廓
45         drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) -> image
46         image-原圖上繪制輪廓
47         contours-全部輪廓
48         contourIdx-輪廓系數i
49         color-顏色
50         thickness-線寬
51         """
52         cv.drawContours(img,contours,i,(0,255,0),2)
53 
54         #打印出輪廓面積
55         # print("contourArea",area)
56         """
57         approxPolyDP(curve, epsilon, closed[, approxCurve]) -> approxCurve
58         curve-擬合曲線
59         epsilon-擬合曲線條數(int)
60         closed-擬合曲線是否閉合(True or False)
61         多邊形擬合
62         """
63         approxCurve = cv.approxPolyDP(contour,10,True)
64         print(approxCurve.shape)
65         #畫輪廓多邊形擬合數目>6的圖形輪廓為紅色
66         if approxCurve.shape[0] > 6:
67             cv.drawContours(dst,contours,i,(0,0,255),2)
68         ##畫輪廓多邊形擬合數目=4的圖形輪廓為綠色
69         elif approxCurve.shape[0] == 4:
70             cv.drawContours(dst,contours,i,(0,255,0),2)
71         # 畫輪廓多邊形擬合數目=3的圖形輪廓為藍
72         elif approxCurve.shape[0] == 3:
73             cv.drawContours(dst,contours,i,(255,0,0),2)
74         # 畫其余數目的輪廓多邊形擬合的圖形輪廓為黃色
75         else:
76             cv.drawContours(dst,contours,i,(0,255,255),2)
77 
78     cv.imshow("measure_object", dst)
79 
80 src = cv.imread('nums.jpg')
81 # src = cv.imread('shape.png')
82 cv.namedWindow('input_image',cv.WINDOW_AUTOSIZE)
83 cv.imshow('input_image',src)
84 
85 measure_object(src)
86 
87 cv.waitKey(0)
88 cv.destroyAllWindows()

 

(mcx,mcy),radius = cv.minEnclosingCircle(contour)
cv.circle(dst, (int(mcx),int(mcy)), int(radius), (120, 100, 230), 2)

 

補充知識點:

outImg, contours, hireachy = cv2.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) 

函數有3個參數Arguments(變量)

1、source image(源圖像)一般是 binary 二值圖像

2、contour retrieval mode(輪廓檢索模式) 一般選用  cv.RETR_EXTERNAL(只檢索外部輪廓)    cv.RETR_TREE(檢索全部輪廓)

3、contour approximation method(輪廓近似法)一般選用 cv.CHAIN_APPROX_SIMPLE

ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)

1、gray-源BGR圖像轉化的灰度圖像

2、像素閾值

3、cv.THRESH_BINARY_INV | cv.THRESH_OTSU -二值圖像轉化方法

 

 

參考文章:

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_table_of_contents_contours/py_table_of_contents_contours.html#

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM