基于OpenCV的圖像邊緣檢測(cè)與輪廓分析
一、邊緣檢測(cè)方法
1. Sobel算子邊緣檢測(cè)
Sobel算子通過(guò)計(jì)算圖像灰度函數(shù)的梯度來(lái)檢測(cè)邊緣,分別計(jì)算水平和垂直方向的梯度,然后合并得到完整邊緣圖像。
import cv2 pic = cv2.imread(r"picture_1.jpg", 0) pic_x_64 = cv2.Sobel(pic, cv2.CV_64F, dx=1, dy=0) pic_x_full = cv2.convertScaleAbs(pic_x_64) pic_y_64 = cv2.Sobel(pic, cv2.CV_64F, dx=0, dy=1) pic_y_full = cv2.convertScaleAbs(pic_y_64) pic_xy_sobel_full = cv2.addWeighted(pic_x_full, 1, pic_y_full, 1, 0)
參數(shù)分析:
cv2.CV_64F:輸出圖像的深度,64位浮點(diǎn)數(shù)類型dx=1, dy=0:計(jì)算x方向(水平)梯度dx=0, dy=1:計(jì)算y方向(垂直)梯度cv2.convertScaleAbs():將負(fù)梯度值轉(zhuǎn)換為絕對(duì)值并縮放
2. Scharr算子邊緣檢測(cè)
Scharr算子是Sobel算子的改進(jìn)版本,對(duì)邊緣的響應(yīng)更敏感,能檢測(cè)到更細(xì)微的邊緣變化。
pic = cv2.imread(r"picture_1.jpg", cv2.IMREAD_GRAYSCALE) pic_x_64 = cv2.Scharr(pic, cv2.CV_64F, dx=1, dy=0) pic_x_full = cv2.convertScaleAbs(pic_x_64) pic_y_64 = cv2.Scharr(pic, cv2.CV_64F, dx=0, dy=1) pic_y_full = cv2.convertScaleAbs(pic_y_64) pic_xy_scharr_full = cv2.addWeighted(pic_x_full, 1, pic_y_full, 1, 0)
3. Laplacian邊緣檢測(cè)
Laplacian算子基于二階導(dǎo)數(shù),能同時(shí)檢測(cè)圖像的兩個(gè)方向的邊緣,對(duì)噪聲更敏感但能檢測(cè)到更精細(xì)的邊緣。
pic = cv2.imread(r"picture_1.jpg", cv2.IMREAD_GRAYSCALE) pic_lap = cv2.Laplacian(pic, cv2.CV_64F, ksize=3) pic_lap_full = cv2.convertScaleAbs(pic_lap)
參數(shù)分析:
ksize=3:拉普拉斯核的大小,必須為正奇數(shù)
4. Canny邊緣檢測(cè)
Canny邊緣檢測(cè)是多階段算法,包括高斯濾波、梯度計(jì)算、非極大值抑制和雙閾值檢測(cè),是效果最好的邊緣檢測(cè)算法之一。
pic = cv2.imread(r"picture_1.jpg", cv2.IMREAD_GRAYSCALE) pic_canny = cv2.Canny(pic, 100, 150)
參數(shù)分析:
100:低閾值,低于此值的邊緣被丟棄150:高閾值,高于此值的邊緣被保留為強(qiáng)邊緣
二、圖像輪廓分析
1. 輪廓提取基礎(chǔ)
輪廓提取需要先將圖像轉(zhuǎn)換為二值圖像,然后使用findContours函數(shù)查找輪廓。
# 灰度圖處理 phone = cv2.imread(r"picture_1.jpg") phone = cv2.resize(phone, dsize=None, fx=0.4, fy=0.4) phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY) # 閾值處理為二值圖像 ret, phone_binary = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY) # 查找輪廓 _, contours, hierarchy = cv2.findContours(phone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) print(len(contours))
參數(shù)分析:
cv2.THRESH_BINARY:閾值化類型,大于閾值設(shè)為255,小于設(shè)為0cv2.RETR_TREE:輪廓檢索模式,檢索所有輪廓并重建完整的層次結(jié)構(gòu)cv2.CHAIN_APPROX_NONE:輪廓近似方法,存儲(chǔ)所有輪廓點(diǎn)

2. 輪廓繪制方法
image_copy = phone.copy()
cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=2)
# 逐個(gè)繪制輪廓的替代方法
for i in range(len(contours)):
image_copy = cv2.drawContours(image=image_copy, contours=contours, contourIdx=i, color=(0, 255, 0), thickness=3)
cv2.imshow('Contours_show', image_copy)
cv2.waitKey(0)
參數(shù)分析:
contourIdx=-1:繪制所有輪廓,指定索引則繪制單個(gè)輪廓

3. 輪廓特征計(jì)算
# 輪廓面積計(jì)算
area_0 = cv2.contourArea(contours[0])
area_1 = cv2.contourArea(contours[1])
# 輪廓周長(zhǎng)計(jì)算
length = cv2.arcLength(contours[0], closed=True)
# 根據(jù)面積篩選輪廓
a_list = []
for i in contours:
if cv2.contourArea(i) > 10000:
a_list.append(i)
4. 輪廓定位與排序
# 根據(jù)面積排序獲取最大輪廓 sortcnt = sorted(contours, key=cv2.contourArea, reverse=True)[0] image_contours = cv2.drawContours(image_copy, [sortcnt], contourIdx=-1, color=(0, 0, 255), thickness=3)
5. 輪廓幾何特征
cnt = contours[8] # 最小外接圓 (x, y), r = cv2.minEnclosingCircle(cnt) phone_circle = cv2.circle(phone, center=(int(x), int(y)), radius=int(r), color=(0, 255, 0), thickness=2) # 最小外接矩形 x, y, w, h = cv2.boundingRect(cnt) phone_rectangle = cv2.rectangle(phone, pt1=(x, y), pt2=(x + w, y + h), color=(0, 255, 0), thickness=2)

三、輪廓近似與簡(jiǎn)化
輪廓近似可以減少輪廓點(diǎn)的數(shù)量,同時(shí)保持輪廓的基本形狀,常用于減少計(jì)算復(fù)雜度和數(shù)據(jù)存儲(chǔ)。
phone = cv2.imread('phone.png')
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)
ret, phone_thresh = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY)
# 兼容不同OpenCV版本的輪廓查找
contours = cv2.findContours(phone_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2]
# 輪廓近似
epsilon = 0.01 * cv2.arcLength(contours[0], closed=True)
approx = cv2.approxPolyDP(contours[0], epsilon, closed=True)
print(contours[0].shape) # 原始輪廓點(diǎn)數(shù)
print(approx.shape) # 近似后輪廓點(diǎn)數(shù)
# 繪制近似輪廓
phone_new = phone.copy()
image_contours = cv2.drawContours(phone_new, [approx], contourIdx=-1, color=(0, 255, 0), thickness=3)
參數(shù)分析:
epsilon:近似精度參數(shù),通常取輪廓周長(zhǎng)的百分比closed=True:指示輪廓是封閉的

到此這篇關(guān)于基于OpenCV的圖像邊緣檢測(cè)與輪廓分析的文章就介紹到這了,更多相關(guān)OpenCV 圖像邊緣檢測(cè)與輪廓內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)Excel條件格式自動(dòng)化設(shè)置
在處理大量 Excel 數(shù)據(jù)時(shí),條件格式無(wú)疑是提升數(shù)據(jù)可讀性和洞察力的強(qiáng)大工具,本文將深入探討如何利用 Python 及其 Spire.XLS for Python 庫(kù),實(shí)現(xiàn) Excel 條件格式的自動(dòng)化設(shè)置,感興趣的小伙伴可以了解下2026-01-01
python如何打印楊輝三角及輸出第m行第k個(gè)數(shù)
這篇文章主要介紹了python如何打印楊輝三角及輸出第m行第k個(gè)數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
Python中SyntaxError: invalid syntax報(bào)錯(cuò)解決
在編寫Python代碼時(shí),常見的SyntaxError錯(cuò)誤通常由括號(hào)不匹配、關(guān)鍵字拼寫錯(cuò)誤或不正確的縮進(jìn)引起,本文詳細(xì)介紹了錯(cuò)誤原因及多種解決方案,包括檢查括號(hào)、關(guān)鍵字,以及使用IDE的語(yǔ)法檢查功能等,感興趣的可以了解一下2024-09-09
Python桌面應(yīng)用開發(fā)實(shí)戰(zhàn)之PyQt的安裝使用
這篇文章主要給大家介紹了關(guān)于Python桌面應(yīng)用開發(fā)實(shí)戰(zhàn)之PyQt的安裝使用,PyQt是一個(gè)功能強(qiáng)大的Python庫(kù),用于創(chuàng)建圖形用戶界面(GUI)應(yīng)用程序,需要的朋友可以參考下2023-08-08
python實(shí)現(xiàn)智能語(yǔ)音天氣預(yù)報(bào)
今天小編就為大家分享一篇python實(shí)現(xiàn)智能語(yǔ)音天氣預(yù)報(bào),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12

