OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法...
函數中的代碼是部分代碼,詳細代碼在最后
1 cv2.boundingRect
作用:矩形邊框(boundingRect),用于計算圖像一系列點的外部矩形邊界。
cv2.boundingRect(array) -> retval
參數:
array - 灰度圖像(gray-scale image)或 2D點集( 2D point set )?
返回值:元組
元組(x, y, w, h ) 矩形左上點坐標,w, h 是矩陣的寬、高,例如?(161, 153, 531, 446)
代碼示例:
contours, hierarchy = cv2.findContours(re_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for c in contours:# find bounding box coordinates# 現計算出一個簡單的邊界框x, y, w, h = cv2.boundingRect(c)# 畫出矩形cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2)
?
?
2 cv2.minAreaRect
作用:minAreaRect - min Area Rect 最小區域矩形;計算指定點集的最小區域的邊界矩形,矩形可能會發生旋轉?possibly rotated,以保證區域面積最小。
cv2.minAreaRect(points) -> retval
參數:
points - 2D點的矢量(?vector of 2D points )
返回值:元組
?元組((最小外接矩形的中心坐標),(寬,高),旋轉角度)----->? ? ((x, y), (w, h),?θ )
關于旋轉角度的注意事項:
1)旋轉角度是水平軸(x軸)逆時針旋轉,與碰到的矩形第一條邊的夾角。
2)“ 第一條邊 " 定義為 寬width,另一條邊定義為高 height。這里的寬、高不是按照長短來定義的。
3)在 opencv 中,坐標系原點在圖像左上角,將其延伸到整個二維空間,可以發現 “x軸鏡像對稱”,角度則?逆時針旋轉為負、順時針旋轉為正。故θ∈(-90度,0];(笛卡爾坐標系中,逆時針為正、順時針為負)
4)旋轉角度為角度值,而非弧度制。
?
?
如 ((458.70343017578125, 381.97894287109375), (202.513916015625, 634.2526245117188), -45.707313537597656)
但繪制這個矩形,一般需要知道矩形的 4 個頂點坐標;通常是通過函數 cv2.boxPoints()獲取。
2.1 附1 : cv2.boxPoints
作用:查找旋轉矩形的 4 個頂點(用于繪制旋轉矩形的輔助函數)。
cv2.boxPoints(box) -> points參數:
box - 旋轉的矩形
返回值:列表list
points - 矩形 4 個頂點組成的列表 list
返回值示例:
[[614.9866 675.9137 ][161. 232.99997][302.4203 88.04419][756.40686 530.9579 ]]?
?
2.2 附2:int0
int0 有兩種相近的描述,
第一種,int0 意味是?64位整數。字符代碼'l'。與?Python int兼容,參考文檔https://kite.com/python/docs/numpy.int0
int0 ( *args, **kwargs )第二種,等價于intp,在?數組類型和類型之間的轉換?文檔中,有intp,釋義為 “?用于索引的整數(與C?ssize_t相同;通常為int32或int64)”
有人說不建議使用int0, 因為它等同內容不完全一致,如 int32,int64.
相關參考:
locating corner position using opencv
What are np.int0 and np.uint0 supposed to be?
numpy 的 int0
數據類型 -->?數組類型和類型之間的轉換
What is numpy method int0?
代碼示例:
contours, hierarchy = cv2.findContours(re_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for c in contours:# find minimum area# 計算包圍目標的最小矩形區域rect = cv2.minAreaRect(c)# calculate coordinate of the minimum area rectangle# 計算矩形的 4 點坐標,返回結果為float數據類型box = cv2.boxPoints(rect)# normalize coordinates to integers# 將float類型轉為 int,在這里最好寫成int32 / int64# 若為int0,有時候出錯都不知道錯在那 box =np.int0(box)# 注:OpenCV沒有函數能直接從輪廓信息中計算出最小矩形頂點的坐標。所以需要計算出最小矩形區域,# 然后計算這個矩形的頂點。由于計算出來的頂點坐標是浮點型,但是所得像素的坐標值是整數(不能獲取像素的一部分),# 所以需要做一個轉換# draw contourscv2.drawContours(img, [box], 0, (0, 0, 255), 3) # 畫出該矩形
?
3 cv2.minEnclosingCircle
作用:使用迭代算法(?iterative algorithm)查找包含2D點集的最小區域的圓(Finds a circle of the minimum area enclosing a 2D point set)。
cv2.minEnclosingCircle(points) -> center, radius
參數:
points - 2D點矢量(vector of 2D points)
返回值:
center - 圓心? (x, y)
radius - 半徑? r
如:((426.0, 415.5), 321.7628173828125)
代碼示例:
# calculate center and radius of minimum enclosing circle # 會返回一個二元組, # 第一個元素為圓心的坐標組成的元組,第二個元素為圓的半徑值。 (x, y), radius = cv2.minEnclosingCircle(c) # 轉為整數 cast to integers center = (int(x), int(y)) radius = int(radius) # 繪圓 draw the circle img = cv2.circle(img, center, radius, (0, 255, 0), 2)
或者
cen, rad = cv2.minEnclosingCircle(c) cen = tuple(np.int0(cen)) rad = np.int32(rad) img = cv2.circle(img, cen, rad, (0, 255, 0), 2)
?
運行
注意:
cv2.circle() 函數使用時,圓心參數不能是數列array,必須是元組tuple
繪制圓cv2.circle() 函數的使用方法。
3.1 附1:cv.circle()
作用:畫圓環或實心圓
cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]]) -> img參數:
img - 目標圖像
center - int 圓心,必須是元組tuple形式、不能是列表 list,必須是整型int、不能是浮點型float;
radius - int 半徑,必須是整型int、不接受浮點型float。
color - 圓的顏色
thickness - int thickness = 1 圓輪廓的厚度(正數 positive),若為負值(Negative values),意味全填充的實心圓。
lineType - int lineType = 8 圓輪廓的線性,
- 8 (or omitted) - 8-connected line.
- 4 - 4-connected line.
- CV_AA - antialiased line.
shift - int shift = 0 help幫助文檔直譯?圓心、半徑值的小數位(Number of fractional bits in the coordinates of the center and in the radius value),事實上,當執行代碼時,貌似又不是這個意思?。
以上若不是整數int,則會報錯?TypeError: integer argument expected, got float?
?示例代碼如下
(x, y), radius = cv2.minEnclosingCircle(c) center = (int(x), int(y)) radius = int(radius) img = cv2.circle(img, center, radius, (0, 255, 0), thickness=2,lineType=8,# shift=0)# shift=1)# shift=2)# shift=3)# shift=4)# shift=5)shift=6)分別運行,其結果:
?
?
?
需要注意的是不同的圖,其運行代碼后的識別效果是不同的,我當時用 ppt 制備?閃電 lighning 時并沒有在意圖片格式,就造成了運行代碼后的識別結果與別人的不一致,后來將圖片保存成黑底白圖,和別人的圖像一致了。
說明:
1)在運行代碼時圖片沒有紅色邊框,為了說明每一個圖,后加上的紅色圖像邊框。
2)a、b圖的大小不一樣,其運行后識別的結果不一樣。
3)b、d圖的背底和圖案顏色正好相反,其由于函數 cv2.threshold()的參數一致,所以其結果也不一致。
4)c、d圖的是有無背底,其運行后識別結果也有所區別。
以上只是說明同一個代碼,針對圖的稍微差別,其識別結果也會存在差別。以后注意這方面內容就行。暫不深究。
4 cv2.rectangle
作用:繪制一個矩形輪廓或一個填充矩形。
cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img
參數:
img - 待rectangle函數處理的圖像
pt1 - 矩形的頂點
pt2 - 矩形的另一個頂點(但該頂點與pt2頂點相對)
color - 矩形的顏色或亮度(灰度圖像)
thickness - 矩形邊框的粗細,若為負值,則矩形為全填充的。int?thickness=1。?
lineType -?Type of the line. See #LineTypes。int?lineType=8。
shift -?Number of fractional bits in the point coordinates.。int?shift=0。
返回值:
img - 被rectangle處理過的圖像。
該函數還可以直接輸入矩形來替代pt1、pt2 對角點,代碼如下:
cv2.rectangle(img, rec, color[, thickness[, lineType[, shift]]]) -> img
參數:
rec - 矩形,
代碼示例:
# 計算出一個簡單的邊界框, # 參數c為圖像輪廓findContours返回值 x, y, w, h = cv2.boundingRect(c) # 繪制矩形 # 將輪廓信息轉換成(x, y)坐標,并加上矩形的高度和寬度 cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2)
運行結果:
?
5 全代碼分析
將上述函數中代碼整理,所有的代碼如下
import cv2 import numpy as npimg = cv2.imread('lightning.png',cv2.IMREAD_UNCHANGED) # img = cv2.pyrUp(img) img_gray = cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY)ret, re_img = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(re_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for c in contours:# 查找矩形邊界 find bounding box coordinates# 計算出簡單的邊界框,返回頂點坐標、寬、高x,y,w,h = cv2.boundingRect(c)# 它將輪廓信息轉換程(x,y)坐標,并加上矩形的高度和寬度cv2.rectangle(img,(x,y),(x+w, y+h),(0,255,0),2)# find minimum area# 計算出包圍目標的最小矩形區域rect = cv2.minAreaRect(c)# calculate coordinates of the minimum area rectangle# 計算矩形的 4 個坐標點,float形式box = cv2.boxPoints(rect)# normalize coordinates to integers# 將坐標值整數化box = np.int0(box)# draw contours# opencv沒有函數能直接從輪廓信息中計算出最小矩形頂點的坐標。# 所以需要計算出最小矩形區域,然后計算這個矩形的頂點。# 計算出的頂點坐標都是浮點型,而所有像素的坐標值都是整數,# 所以需要做轉換整數,然后畫出這個矩形cv2.drawContours(img, [box], 0, (0,0,255), 3)# calculate center and radius of minimum enclosing circle# 大多數繪圖函數把繪圖顏色和密度thickness放在最后兩個參數里# 最后檢查的邊界輪廓為最小閉圓# minEnclosingCircle函數返回一個二元組,# 第一個元數為圓心,第二個元素為半徑(x,y), radius = cv2.minEnclosingCircle(c)# cast to integerscenter = (int(x),int(y))radius = int(radius)# draw the circleimg = cv2.circle(img,center,radius,(0,255,0),2, lineType=8, shift=6)cv2.drawContours(img,contours, -1, (255,0,0), 1) cv2.imshow("contours",img) cv2.waitKey()
運行:
?
?
參考:
輪廓特征——官網
笛卡爾坐標系
python opencv minAreaRect 生成最小外接矩形
OpenCV 中boundingRect、minAreaRect、minEnclosingCircle用法
OpenCV的基本繪圖函數
openCV檢測物體邊緣
OpenCv學習筆記3--輪廓檢測,多邊形 直線 圓檢測
python-opencv boundingRect使用注意
簡單的驗證碼識別(opecv)(基于c/c++的示例代碼)
opencv的一些函數——contours
opencv圖像輪廓
此外還有??Opencv 圖像金字塔pyrDown和pyrUp函數
【OpenCV筆記 06】OpenCV中繪制基本幾何圖形【矩形rectangle()、橢圓ellipse() 、圓circle() 】——基于c/c++的,但可以參考
?
?
轉載于:https://www.cnblogs.com/gengyi/p/10317664.html
總結
以上是生活随笔為你收集整理的OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 赢的自己才赢的江湖是什么歌呢
- 下一篇: 求一个qq女生网名带符号英文!