廣州響應(yīng)式網(wǎng)站建設(shè)seo基礎(chǔ)
圖像輪廓
1.獲取圖像輪廓
cv2.findContours()
函數(shù)是 OpenCV 庫中用于檢測圖像中輪廓的函數(shù)。它可以檢測到圖像中所有連通區(qū)域的邊界,并返回這些輪廓的列表。從 OpenCV 3.4 版本開始,這個函數(shù)的返回值和參數(shù)有所變化,以下是詳細(xì)的參數(shù)說明:
方法:
contours, hierarchy = cv2.findContours( img, mode, method )
參數(shù)說明
-
img:輸入圖像,必須是二值圖像。圖像中的輪廓將基于此圖像進(jìn)行檢測。
-
mode:輪廓檢索模式,用于指定要檢索哪些輪廓??捎玫哪J接?#xff1a;
cv2.RETR_EXTERNAL
:只檢索最外層的輪廓。cv2.RETR_LIST
:檢索所有輪廓,但不建立任何父子關(guān)系。cv2.RETR_CCOMP
:檢索所有輪廓,并將它們組織成兩級層次結(jié)構(gòu)。cv2.RETR_TREE
:檢索所有輪廓,并重建完整的層次結(jié)構(gòu)。
-
method:輪廓近似方法,用于指定如何存儲輪廓點??捎玫姆椒ㄓ?#xff1a;
cv2.CHAIN_APPROX_NONE
:存儲所有輪廓點。cv2.CHAIN_APPROX_SIMPLE
:只存儲輪廓的拐點,這可以減少輪廓點的數(shù)量。
返回值
- contours:這是一個 Python 列表,其中包含了檢測到的輪廓。每個輪廓都是一個形狀為?
(n, 1, 2)
?的 numpy 數(shù)組,其中?n
?是輪廓點的數(shù)量。 - hierarchy:這是一個 numpy 數(shù)組,包含了輪廓的層次信息。層次信息可以用來了解輪廓之間的父子關(guān)系。
2.繪制圖像輪廓
????????在OpenCV中,cv2.drawContours()
函數(shù)用于在圖像上繪制輪廓。這個函數(shù)非常強(qiáng)大,因為它允許你指定輪廓的顏色、線條粗細(xì)以及其他參數(shù)。下面是這個函數(shù)的詳細(xì)參數(shù)說明:
方法:
cv2.drawContours(img, contours, contourIdx, color, thickness, lineType=None, hierarchy=None)
參數(shù)說明
-
img:目標(biāo)圖像,即你要在其上繪制輪廓的圖像。這個圖像應(yīng)該是一個可以修改的圖像數(shù)組。
-
contours:這是一個輪廓列表。輪廓可以是OpenCV中找到的任何輪廓,通常是一個形狀為
(N, 1, 2)
的numpy數(shù)組,其中N
是輪廓中的點數(shù)。 -
contourIdx:指定要繪制的輪廓的索引。如果傳遞的是-1,則繪制所有輪廓。
-
color:輪廓線的顏色。這應(yīng)該是一個具有三個元素的元組,表示BGR顏色(例如,紅色為(0, 0, 255))。
-
thickness:線條的粗細(xì)。如果設(shè)置為正數(shù),則線條的粗細(xì)為指定的像素數(shù);如果設(shè)置為
cv2.FILLED
或-1
,則輪廓將被填充。 -
lineType(可選):線條的類型。默認(rèn)是
cv2.LINE_8
,表示8連通性線。其他選項包括cv2.LINE_4
(4連通性線)和cv2.LINE_AA
(抗鋸齒線)。 -
hierarchy(可選):輪廓的層次結(jié)構(gòu)。這是一個與
contours
數(shù)組相對應(yīng)的數(shù)組,其中包含每個輪廓的層次信息。如果提供,可以用來繪制輪廓的父子關(guān)系。
實驗代碼
1.獲取圖像
import cv2# 讀取圖像
phone = cv2.imread('cat.png') # 讀取名為'cat.png'的圖像# 將圖像轉(zhuǎn)換為灰度圖像
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY) # 將彩色圖像轉(zhuǎn)換為灰度圖# 應(yīng)用閾值操作以創(chuàng)建二值圖像
ret, phone_binary = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY) # 使用閾值120將灰度圖轉(zhuǎn)換為二值圖
# cv2.imshow('1',phone_binary) # 顯示二值圖像
2.查找輪廓
# 查找輪廓
_, contours, hierarchy = cv2.findContours(phone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 在二值圖中查找輪廓
# 打印輪廓數(shù)量和層次結(jié)構(gòu)信息
print(hierarchy) # 打印輪廓的層次結(jié)構(gòu)信息
print(len(contours)) # 打印輪廓的數(shù)量
3.復(fù)制圖像用于繪制輪廓
# 復(fù)制圖像用于繪制輪廓
image_copy = phone.copy()
image_copy = cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=3) # 在圖像上繪制所有輪廓
# cv2.imshow('contours',image_copy) # 顯示繪制了輪廓的圖像
cv2.waitKey(0) # 等待按鍵
4.計算輪廓面積和周長
# 計算第一個和第二個輪廓的面積
area_0 = cv2.contourArea(contours[0])
area_1 = cv2.contourArea(contours[1])
print(area_0, area_1) # 打印面積# 計算第一個輪廓的周長
length = cv2.arcLength(contours[0], closed=True)
print(length) # 打印周長
5.查找輪廓
# 篩選面積大于10000的輪廓
a_list = []
for i in range(len(contours)):if cv2.contourArea(contours[i]) > 10000:a_list.append(contours[i])# 找到第七個輪廓的最小包圍圓
cnt = contours[6]
(x, y), r = cv2.minEnclosingCircle(cnt)
phone_circle = cv2.circle(phone, (int(x), int(y)), int(r), (0, 255, 0), 2) # 在圖像上繪制最小包圍圓
cv2.imshow('phone_circle', phone_circle) # 顯示繪制了最小包圍圓的圖像# 找到第七個輪廓的最小包圍矩形
x, y, w, h = cv2.boundingRect((cnt))
phone_rectangle = cv2.rectangle(phone, (x, y), (x + w, y + h), (0, 255, 0), 2) # 在圖像上繪制最小包圍矩形
cv2.imshow('phone_rectangle', phone_rectangle) # 顯示繪制了最小包圍矩形的圖像
6.輪廓近似
# 重新查找輪廓
image, contours, hierarchy = cv2.findContours(phone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)# 對最后一個輪廓進(jìn)行輪廓近似
epsilon = 0.001 * cv2.arcLength(contours[-1], True)
approx = cv2.approxPolyDP(contours[-1], epsilon, True)
phone_new = phone.copy()
image_contours = cv2.drawContours(phone_new, [approx], contourIdx=-1, color=(0, 255, 0), thickness=3) # 在圖像上繪制近似輪廓
cv2.imshow('image_contours', image_contours) # 顯示繪制了近似輪廓的圖像cv2.waitKey(0)
實驗分析
- 通過閾值操作,圖像中的輪廓被清晰地分離出來,這為后續(xù)的輪廓處理提供了便利。
- 輪廓的面積和周長的計算對于理解圖像中對象的大小和形狀特征非常重要。
- 最小包圍圓和最小包圍矩形的繪制有助于識別和定位圖像中的主要對象。
- 輪廓近似可以簡化輪廓的形狀,減少計算復(fù)雜度,同時保留輪廓的主要特征。
結(jié)論
????????本實驗通過使用OpenCV庫成功地完成了圖像處理的各個步驟,包括圖像的讀取、轉(zhuǎn)換、閾值操作、輪廓查找、面積和周長計算、最小包圍圓和矩形的繪制以及輪廓近似。這些技術(shù)在圖像識別、對象檢測和圖像分析等領(lǐng)域有著廣泛的應(yīng)用。