【图像处理】——Python+opencv实现提取图像的几何特征(面积、周长、细长度、区间占空比、重心、不变矩等)
- 轉載請注明詳細地址
- 本文簡單介紹了圖像常見幾何特征的概念以及求解方法
- 本文介紹了Python和opencv求解幾何特征的常用方法
目錄
其他形狀外接輪廓的方法可以參考:《OpenCV-Python——第17.3章:輪廓形狀擬合(邊界矩形,最小外接圓...)及性質》
一、獲得輪廓
二、面積
1、cv2.connectedComponentsWithStats()
stats參數解析
2、cv2.contourArea()函數
三、周長
1、cv2.arcLength(contours[0],True)
四、細長度
1、繪制外接矩形(cv2.rectangle()函數)
2、得到矩形的角點坐標和長寬cv2.boundingRect()函數
3、求解最小外接矩形(cv2.minAreaRect()函數)
4、繪制最小外接矩形:cv2.boxPoints()函數和cv2.polylines()函數
step1 角點坐標獲得cv2.boxPoints()
step2 將角點坐標全部轉換為整數
step3 依次連接起來cv2.polylines()
5、細長度的計算
五、區間占空比
六、重心
七、圖像上添加文字cv2.putText()函數
八、完整代碼
一、獲得輪廓
在進行輪廓幾何特征的提取之前,首先要做的就是得到輪廓,得到輪廓常用的函數有:
cv2.findcontours()
具體可見:《【圖像處理】——Python+opencv實現二值圖像的輪廓邊界跟蹤以及輪廓面積周長的求解(findcontours函數和contourArea函數)》
二、面積
一般指的是輪廓內所包含的所有像素的個數,但是為了方便計算加快計算的速度,一般會采樣一種近似地方法去估算面積,常用的有將輪廓近似成一個多邊形,然后進行求解,在Python—opencv中,有兩種方式可以對輪廓面積進行求解
1、cv2.connectedComponentsWithStats()
具體看見:《【圖像處理】——實現二值圖像的輪廓邊界跟蹤以及輪廓面積周長的求解(connectedComponentsWithStats()函數和connectedComponents()函數)》
retval, labels, stats, centroids = connectedComponentsWithStats(image, labels=None, stats=None, centroids=None, connectivity=None, ltype=None)?這個函數返回值stats中的最后一個元素就是輪廓區域的面積,通過提取可以得到
stats參數解析
stats參數是一個numpy數組,每一行代表一個輪廓,每一行固定為5個參數,依次是:
??? CC_STAT_LEFT 組件的左上角點像素點坐標的X位置
??? CC_STAT_TOP 組件的左上角點像素點坐標的Y位置
??? CC_STAT_WIDTH 組件外接矩形的寬度,計算方式為用每一個輪廓中最右邊的點的x坐標減去最左邊的點的x坐標
??? CC_STAT_HEIGHT 組件外接矩形的高度,計算方式為用每一個輪廓中最下邊的點的y坐標減去最上邊的點的y坐標
??? CC_STAT_AREA 當前連通組件的面積(像素單位),這里統計的是輪廓所包含的像素點的個數,不是外接矩形的面積
所以stats的shape為:mx5,m是輪廓的個數,第一個輪廓是背景輪廓,前兩個參數為0,0
2、cv2.contourArea()函數
這個函數可以針對每一個輪廓求得近似的面積,返回的是一個常數
contours,layer_num = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) #面積1 area1 = cv2.contourArea(contours[0]) #面積2 _,labels,stats,centroids = cv2.connectedComponentsWithStats(binary) area2 = stats[1][4]三、周長
周長指的是輪廓的像素點總數,也常用各個像素點的中點連線的多邊形長度進行度量,若是對角線方向則為根號2個像素格,否則為1個像素格長度
常用的函數為:
length = cv2.arcLength(contours[0],True)1、cv2.arcLength(contours[0],True)
arcLength(contour, closed)參數解析:
contour:輪廓點集
closed:表明輪廓是否封閉與否,TRUE則表示封閉,FALSE則表示非封閉
#周長 length = cv2.arcLength(contours[0],True)四、細長度
細長度表征圖像中待識別區域的緊湊性,它的計算是由待識別區域的最小外接矩形得到,該最小外接矩形長軸和短軸的比值即為區域的細長度,表達式如下:
1、繪制外接矩形(cv2.rectangle()函數)
這個函數的原理就是取輪廓點集最上面的點、最下面的點、最左邊的點和最右邊的點作為外接矩形的四個點的坐標,這個矩形不一定是最小外接矩形,其邊與坐標軸平行或者垂直
img = rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)img:進行繪制矩形的圖像pt1:矩形左上角角點坐標,是一個元組pt2:矩形右下角角點坐標,是一個元組color:繪制矩形的顏色,一般通過RGB的表示方式(R.G,B)thickness:繪制矩形的線寬,如果是負數,則將輪廓區域進行填充linetype:線型 rect = cv2.rectangle(rgb1,(stats[1][0],stats[1][1]),(stats[1][0]+stats[1][2],stats[1][1]+stats[1][3]),(0,0,255),2)2、得到矩形的角點坐標和長寬cv2.boundingRect()函數
#得到外接矩形的左上角點坐標和長寬 x,y,h,w = cv2.boundingRect(contours[0])3、求解最小外接矩形(cv2.minAreaRect()函數)
實際上求解最小外接矩形的方法就是將圖像沿逆時針或者順時針按照一定的度數進行旋轉,每旋轉一次,求解一次輪廓的外接矩形的面積,記錄每次旋轉的度數、左上角點坐標、矩形長寬,根據三角函數可以得到旋轉后的角點坐標,等旋轉完成一周后,取面積最小的即為最小外接矩形
img = minAreaRect(points)points:就是輪廓的點集
返回的是:img = ((x,y),(h,w),α)
#返回的是一個元組,第一個元素是左上角點坐標組成的元組,第二個元素是矩形寬高組成的元組,第三個是旋轉的角度 min_rect = cv2.minAreaRect(contours[0])4、繪制最小外接矩形:cv2.boxPoints()函數和cv2.polylines()函數
要想在原圖像中繪制出最小外接矩形,則需要知道矩形的四個角點坐標,這四個角點坐標實際上就是在旋轉的時候記錄后進行根據記錄的角度和三角函數進行轉換過來的,知道后通過繪制多邊形的方法將點依次連接即可
step1 角點坐標獲得cv2.boxPoints()
box = cv2.boxPoints(min_rect)#返回的是一個numpy矩陣 min_rect:是一個元組返回的是由角點組成的numpy矩陣
step2 將角點坐標全部轉換為整數
box = np.int0(box)#將其轉換為整數,否則會報錯step3 依次連接起來cv2.polylines()
img = polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)參數解析:
img:繪制矩形的圖像
pts:裝有矩形角點的點陣(一般是由boxpoints()函數得到)
isClosed:指定繪制的矩形是否為封閉的,TRUE表示封閉
color:繪制矩形的線條的顏色,用元組表示
thickness:線寬
linetype:線型
返回參數:返回的是繪制后的圖像
min_rect_img = cv2.polylines(rgb2,[box],True,(0,255,0),2)5、細長度的計算
直接利用得到的數據即可獲得
#最小外接矩形 min_rect = cv2.minAreaRect(contours[0])#返回的是一個元組,第一個元素是左上角點坐標組成的元組,第二個元素是矩形寬高組成的元組,第三個是旋轉的角度 #細長度 min_rect_h = min_rect[1][0] min_rect_w = min_rect[1][1] e = min_rect_h/min_rect_w五、區間占空比
區間占空比指的是將輪廓區域的面積除以外接矩形的面積,這里的外接矩形一般指的是最小外接矩形
#區域占空比(輪廓區域面積除以最小外接矩形面積) ee = area1/min_rect_area六、重心
重心描述的是待識別區域的全局特性,反映的是區域內部像素點的分布。如果待識別區域是均勻的,密度設為1則區域的重心同時也是是區域的幾何中心,它可通過計算所有像素點的平均值得到
七、圖像上添加文字cv2.putText()函數
cv2.putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)img:需要添加文字的圖像
text:添加的文字內容,一定是字符串
org:相當于一個文本框的左上角點坐標
fontface:文字大小
fontscale:文字比例
color:文字顏色,以元組的形式表達
thickness:線寬
linetype:線型
text2 = "width:" + str(int(min_rect[1][1])) cv2.putText(rgb1,text1, (10, 30), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0)八、完整代碼
import cv2 import numpy as nprgb1 = cv2.imread('roi.png') rgb2 = cv2.imread('roi.png') rgb3 = cv2.imread('roi.png')img = cv2.imread('roi.png',0) ret,binary = cv2.threshold(img,100,255,cv2.THRESH_BINARY) contours,layer_num = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) #面積1 area1 = cv2.contourArea(contours[0]) #面積2 _,labels,stats,centroids = cv2.connectedComponentsWithStats(binary) area2 = stats[1][4]#周長 length = cv2.arcLength(contours[0],True)#得到外接矩形的左上角點坐標和長寬 x,y,w,h = cv2.boundingRect(contours[0])#外接矩形 rect = cv2.rectangle(rgb1,(stats[1][0],stats[1][1]),(stats[1][0]+stats[1][2],stats[1][1]+stats[1][3]),(0,0,255),2) rect_area = w*h#最小外接矩形 min_rect = cv2.minAreaRect(contours[0])#返回的是一個元組,第一個元素是左上角點坐標組成的元組,第二個元素是矩形寬高組成的元組,第三個是旋轉的角度 # print(min_rect)((530.0443725585938, 113.73445892333984), (40.497230529785156, 137.21890258789062), -86.68222045898438)#獲得最小外接矩形的四個角點坐標 box = cv2.boxPoints(min_rect)#返回的是一個numpy矩陣 min_rect_area = cv2.contourArea(box)#繪制最小外接矩形,通過多邊形繪制的方法進行繪制 box = np.int0(box)#將其轉換為整數,否則會報錯 min_rect_img = cv2.polylines(rgb2,[box],True,(0,255,0),2)#細長度 min_rect_h = min_rect[1][0] min_rect_w = min_rect[1][1] e = min_rect_h/min_rect_w#區域占空比(輪廓區域面積除以最小外接矩形面積) ee = area1/min_rect_area#質心 centroid = centroids[0]text1 = 'height:'+ str(int(min_rect[1][0])) text2 = "width:" + str(int(min_rect[1][1])) cv2.putText(rgb1,text1, (10, 30), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0) cv2.putText(rgb1,text2, (10, 60), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0) cv2.imshow('rect',rect) cv2.imshow('min_rect',min_rect_img) cv2.imshow('rgb',rgb3) cv2.waitKey(0)print(area1) print(area2) print(rect_area) print(min_rect_area) print(e) print(ee) print(centroid)總結
以上是生活随笔為你收集整理的【图像处理】——Python+opencv实现提取图像的几何特征(面积、周长、细长度、区间占空比、重心、不变矩等)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu 开机自动挂载硬盘
- 下一篇: Android 设置背景透明度