日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【opencv】(6) 图像轮廓处理

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【opencv】(6) 图像轮廓处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

各位同學好,今天和大家分享一下opencv中如何獲取圖像輪廓,以及對輪廓的一些其他操作。內容有:

(1)輪廓檢測:cv2.findContours();(2)輪廓繪制:cv2.drawContours();(3)輪廓近似:cv2.approxPolyDP();(4)面積計算:cv2.contourArea();(5)周長計算:cv2.arcLength();(6)外接矩形:cv2.rectangle();(7)外接圓:cv2.circle()


在開始前,先導入需要用到的庫文件以及圖像數據,定義一個圖像顯示函數,方便后續繪圖。

import cv2
import numpy as np
# 獲取圖片所在文件夾
filepath = 'C:\\...\\opencv\\img'
# 獲取文件夾中的某一張圖片
img = cv2.imread(filepath+'\\test2.png')
# 定義繪圖函數
def cv_show(name,img):# 傳入自定義圖像名,即圖像變量cv2.imshow(name,img) # 圖片不會自動消失cv2.waitKey(0)# 手動關閉窗口cv2.destroyWindow()

1. 圖像輪廓

1.1 獲取圖像輪廓

方法: contours, hierarchy =?cv2.findContours(img, mode, method)

參數:

img輸入的圖像,最好是二值圖

mode輪廓檢索模式,如下

RETR_EXTERNAL:只檢索最外面的輪廓

RETR_LIST:檢索所有的輪廓,并將其保存到一條鏈表中

RETR_CCOMP:檢索所有的輪廓,并將它們組織為兩層:頂層是各部分的外部邊界,第二層是空洞的邊界

RETR_TREE:常用,檢索所有的輪廓,并重構嵌套輪廓的整個層次。保存了所有的輪廓,用哪個調用哪個

method:輪廓逼近方法,如下

CHAIN_APPROX_NONE:以Freeman鏈碼的方式輸出輪廓,所有其他方法輸出多邊形(頂點的序列)。正常畫出所有輪廓

CHAIN_APPROX_SIMPLE:壓縮水平的、垂直的、斜的部分,即函數只保留他們的終點坐標。壓縮得到更精簡的結果,例如一個矩形輪廓只需4個點來保存輪廓信息

返回值:

contours:列表,保存輪廓信息。每一個元素都是圖像的輪廓

hierarchy:數組,分層保存輪廓信息。元素數和輪廓數一致


1.2 繪制圖像輪廓

方法: cv2.drawContours(img, contours, contourIdx, color, thickness)

參數:

img:指明在哪幅圖像上繪制輪廓;image為三通道才能顯示輪廓

contours:圖像輪廓信息,列表形式

contours:指定繪制輪廓列表中的哪條輪廓。如果是-1,則繪制其中的所有輪廓。

color:代表繪制輪廓的線條顏色,根據BGR調整,若為(0,0,255)則為紅色。

thickness:線條粗細


1.3 代碼演示

首先將讀入的圖像變成灰度圖cv2.cvtColor(),再使用圖像閾值處理方法將灰度圖轉換成二值圖cv2.threshold(),像素值超過閾值127的變成255,低于127的像素值變成0,實現二值化。將二值化處理后的圖像thresh傳入輪廓檢測函數。圖像閾值處理方法見下文第4節:【opencv】(2) 圖像處理:邊界填充、圖像融合、圖像閾值、數值計算

#(1)圖像處理
# 將讀入的圖像變成灰度圖 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 圖像數值超過127取255,小于127的變成0
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
# ret接收閾值,thresh接收處理后的圖像
#(2)輪廓檢測
# 輸入圖像最好是二值圖
contours,hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# 返回值:contours輪廓信息;hierarchy層級,把結果保存在一個層級中
#(3)繪制輪廓
# 注意要將原圖(彩色圖)復制一份,不然原圖會在函數處理完之后改變
draw = img.copy()  #draw改變不會導致img改變
# 在draw畫板上繪制輪廓;畫第幾個輪廓,-1代表所有輪廓;BGR分別對應(0,0,255),用紅色線畫輪廓;線條寬2
res = cv2.drawContours(draw, contours,-1, (0, 0, 255), 2)
# 展示圖像
cv_show('res',res)

第1張為原始圖像,第2張為contourIdx=-1時繪制輪廓后的圖像 ,第3張為contourIdx=3時繪制的輪廓。contourIdx中保存了所有的輪廓信息。

???


?2. 輪廓特征

2.1 輪廓計算

輪廓計算有非常多種方法,這里只介紹兩個,計算輪廓周長和面積。

在圖像輪廓獲取函數中cv2.findContours(),我們獲取了輪廓信息返回值contours,在計算時,不能將輪廓全部放進去計算,計算時需要選出其中一個。下面使用輪廓信息中的第0個輪廓計算它的面積和周長。

# 獲取某一個輪廓用于計算
cnt = contours[0]
# ==1== 面積
cv2.contourArea(cnt)  # 8500.5
# ==2== 周長
cv2.arcLength(cnt,True)  # 437.948

2.2 輪廓近似

方法: cv2.approxPolyDP(curve, epsilon, closed)

參數:

curve: 需要進行近似的輪廓

epsilon: 判斷點到相對應的線段的距離的閾值,這是原始曲線與其近似值之間的最大距離。閾值越小,折線的形狀越接近曲線。

closed: 若為true,曲線第一個點與最后一個點連接形成閉合曲線,若為false,曲線不閉合。

下面使用的閾值是cv2.arcLength(cnt,True),即輪廓的周長。取輪廓周長的0.1倍來作為contours[0]輪廓的近似。

# 獲取圖像
img = cv2.imread(filepath+'\\test1.png')  # 獲取一張圖像
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  # 灰度圖
ret,thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 二值化
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)  # 輪廓提取
cnt = contours[0]  # 獲取其中一層輪廓
draw = img.copy()  # 繪制輪廓
res = cv2.drawContours(draw, [cnt], -1, (0,0,255), 2)  # 在draw圖像中繪制cnt輪廓
cv_show('res',res)  # 繪圖
# 輪廓近似
epsilon = 0.1*cv2.arcLength(cnt,True)  # 以周長的百分比作為閾值,指定的越小,得到的輪廓和原來的區別較小
approx = cv2.approxPolyDP(cnt, epsilon, True)  # 近似函數,cnt為輪廓,epsilon閾值。返回近似后的輪廓
# 繪圖展示
draw = img.copy()
res = cv2.drawContours(draw, [approx], -1, (255,0,0), 2)  # 將近似后的輪廓approx畫在原圖上,用藍色表示,線條粗2
cv_show('res',res)

第一張圖為圖像輪廓,第二張圖為輪廓近似后的結果

? ?


2.3 輪廓的外接矩形

首先在輪廓提取函數的返回值contours中,選取一個輪廓信息用于求它的外接矩形。

計算輪廓的垂直邊界最小矩形,矩形是與圖像上下邊界平行的

x, y, w, h = cv2.boundingRect(輪廓信息)

返回四個值。x,y是矩陣左上點的坐標;w,h是矩陣的寬和高。

外接矩形繪制函數

cv2.rectangle(img, pt1, pt2, color, thickness)

參數:

img:?原始圖片作為畫板

pt1: 長方形框左上角坐標 (x, y)

pt2: 長方形框右下角坐標 (x+w, y+h)

color: 線條顏色(B, G, R)

thickness: 線條粗細

在圖片img上畫長方形,坐標原點是圖片左上角,向右為x軸正方向,向下為y軸正方向
?

# 獲取輪廓信息
img = cv2.imread(filepath+'\\test1.png')  # 讀取圖像
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  # 灰度處理
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  # 二值化處理
contours,hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)  # 獲取輪廓信息
cnt = contours[0]  # 指定某一層輪廓
# 輪廓的外接矩形
x,y,w,h = cv2.boundingRect(cnt)  # 計算外接矩形,返回矩形的左上坐標點,和一長一寬
rectangle = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)  # 根據坐標繪制矩形,綠色線條
cv_show('rectangle',rectangle)

得到矩形的寬和高,接下來就可以計算輪廓面積和外接矩形面積的比值。

area = cv2.contourArea(cnt)  # 輪廓面積計算函數
x,y,w,h = cv2.boundingRect(cnt)  # 獲取坐標點和邊長
rect_area = w*h  # 計算外接矩形面積
extent = area/rect_area  # 計算比值
print('輪廓面積和外接矩形面積之比:',extent)

2.4 輪廓的外接圓

獲取輪廓的圓心坐標和半徑

(x,y), radius = cv2.minEnclosingCircle(輪廓信息)

輪廓外接圓函數

cv2.circle(img, center, radius, color, thickness, shift)

img:?輸入的圖片作為畫板

center:?圓心位置

radius: 圓的半徑

color: 圓的顏色

thickness: 正數表示圓形輪廓的粗細。負數表示要繪制實心圓。

shift:?圓心坐標點和半徑值的小數點位數

# 輪廓外接圓
# 返回圓心坐標和半徑
(x,y),radius = cv2.minEnclosingCircle(cnt)
# 圓心坐標
center = (int(x),int(y))
# 半徑
radius = int(radius)
# 繪制外接圓,輸入整型
circle = cv2.circle(img,center,radius,(255,0,0),2)
cv_show('circle',circle)

總結

以上是生活随笔為你收集整理的【opencv】(6) 图像轮廓处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。