Python?OpenCV實(shí)現(xiàn)圖像形狀檢測(cè)
圖像形狀檢測(cè)是計(jì)算機(jī)視覺領(lǐng)域中的一項(xiàng)關(guān)鍵技術(shù),廣泛應(yīng)用于工業(yè)自動(dòng)化、機(jī)器人視覺、醫(yī)學(xué)圖像處理等多個(gè)領(lǐng)域。本文將詳細(xì)介紹如何使用Python和OpenCV庫實(shí)現(xiàn)圖像形狀檢測(cè),通過簡(jiǎn)潔明了的步驟和代碼示例,幫助你快速掌握這一技能。
一、環(huán)境準(zhǔn)備
在開始之前,確保你的電腦上已經(jīng)安裝了Python和OpenCV庫。你可以通過以下命令來安裝OpenCV庫:
pip install opencv-python
同時(shí),確保你能夠編寫和運(yùn)行Python代碼,并熟悉基本的圖像處理概念。
二、讀取和預(yù)處理圖像
讀取圖像
使用OpenCV的cv2.imread()函數(shù)讀取圖像文件。例如,讀取一張包含不同形狀的圖像:
import cv2 # 讀取圖像 img = cv2.imread('shapes.png')
灰度化
將彩色圖像轉(zhuǎn)換為灰度圖像,以簡(jiǎn)化后續(xù)處理。使用cv2.cvtColor()函數(shù):
# 轉(zhuǎn)換為灰度圖像 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
濾波去噪
使用高斯模糊來去除圖像中的噪聲。高斯模糊是一種常用的圖像處理技術(shù),可以平滑圖像并減少噪聲干擾。使用cv2.GaussianBlur()函數(shù):
# 高斯模糊 blurred_img = cv2.GaussianBlur(gray_img, (5, 5), 0)
三、邊緣檢測(cè)
邊緣檢測(cè)是形狀檢測(cè)的重要步驟,它可以幫助我們找到圖像中的輪廓。使用Canny邊緣檢測(cè)算法,該算法是一種常用的邊緣檢測(cè)算法,具有良好的邊緣檢測(cè)效果。使用cv2.Canny()函數(shù):
# Canny邊緣檢測(cè) edges = cv2.Canny(blurred_img, 50, 150)
四、查找輪廓
使用cv2.findContours()函數(shù)查找圖像中的輪廓。該函數(shù)會(huì)返回輪廓點(diǎn)集、層次結(jié)構(gòu)和輪廓的近似方法。我們主要關(guān)注輪廓點(diǎn)集:
# 查找輪廓 contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
五、繪制輪廓
為了可視化檢測(cè)到的輪廓,我們可以使用cv2.drawContours()函數(shù)在原圖像上繪制輪廓:
# 繪制輪廓 contour_img = img.copy() cv2.drawContours(contour_img, contours, -1, (0, 255, 0), 2)
六、形狀分類
根據(jù)輪廓的頂點(diǎn)數(shù)目、面積、周長(zhǎng)等特征,我們可以對(duì)檢測(cè)到的形狀進(jìn)行分類。以下是一個(gè)簡(jiǎn)單的形狀分類示例:
for contour in contours: # 計(jì)算輪廓面積 area = cv2.contourArea(contour) # 計(jì)算輪廓周長(zhǎng) perimeter = cv2.arcLength(contour, True) # 近似輪廓為多邊形 epsilon = 0.02 * perimeter approx = cv2.approxPolyDP(contour, epsilon, True) # 獲取輪廓頂點(diǎn)數(shù)目 num_vertices = len(approx) # 根據(jù)頂點(diǎn)數(shù)目判斷形狀 shape = 'Unknown' if num_vertices == 3: shape = 'Triangle' elif num_vertices == 4: # 判斷是否為正方形或矩形 x, y, w, h = cv2.boundingRect(approx) aspect_ratio = w / float(h) if 0.95 < aspect_ratio < 1.05: shape = 'Square' else: shape = 'Rectangle' elif num_vertices == 5: shape = 'Pentagon' elif num_vertices == 6: shape = 'Hexagon' else: # 對(duì)于頂點(diǎn)數(shù)目大于6的形狀,可以根據(jù)周長(zhǎng)面積比等特征進(jìn)一步分類 # 例如,圓形可以通過周長(zhǎng)面積比接近某個(gè)閾值來判斷 if 4 * 3.14 * (area / 3.14) ** 0.5 / perimeter > 0.8 and 4 * 3.14 * (area / 3.14) ** 0.5 / perimeter < 1.2: shape = 'Circle' else: shape = 'Other Polygon' # 在圖像上標(biāo)注形狀名稱和頂點(diǎn)數(shù)目 M = cv2.moments(contour) if M['m00'] != 0: cX = int(M['m10'] / M['m00']) cY = int(M['m01'] / M['m00']) else: cX, cY = 0, 0 cv2.putText(contour_img, f'{shape} ({num_vertices} vertices)', (cX - 50, cY - 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2) cv2.drawContours(contour_img, [approx], -1, (0, 0, 255), 2)
七、顯示結(jié)果
最后,使用cv2.imshow()函數(shù)顯示處理后的圖像:
# 顯示結(jié)果圖像 cv2.imshow('Shape Detection', contour_img) cv2.waitKey(0) cv2.destroyAllWindows()
八、完整代碼示例
以下是完整的代碼示例,將上述步驟整合在一起:
import cv2 # 讀取圖像 img = cv2.imread('shapes.png') # 轉(zhuǎn)換為灰度圖像 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯模糊 blurred_img = cv2.GaussianBlur(gray_img, (5, 5), 0) # Canny邊緣檢測(cè) edges = cv2.Canny(blurred_img, 50, 150) # 查找輪廓 contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 繪制輪廓并分類形狀 contour_img = img.copy() for contour in contours: # 計(jì)算輪廓面積 area = cv2.contourArea(contour) # 計(jì)算輪廓周長(zhǎng) perimeter = cv2.arcLength(contour, True) # 近似輪廓為多邊形 epsilon = 0.02 * perimeter approx = cv2.approxPolyDP(contour, epsilon, True) # 獲取輪廓頂點(diǎn)數(shù)目 num_vertices = len(approx) # 根據(jù)頂點(diǎn)數(shù)目判斷形狀 shape = 'Unknown' if num_vertices == 3: shape = 'Triangle' elif num_vertices == 4: # 判斷是否為正方形或矩形 x, y, w, h = cv2.boundingRect(approx) aspect_ratio = w / float(h) if 0.95 < aspect_ratio < 1.05: shape = 'Square' else: shape = 'Rectangle' elif num_vertices == 5: shape = 'Pentagon' elif num_vertices == 6: shape = 'Hexagon' else: # 對(duì)于頂點(diǎn)數(shù)目大于6的形狀,可以根據(jù)周長(zhǎng)面積比等特征進(jìn)一步分類 # 例如,圓形可以通過周長(zhǎng)面積比接近某個(gè)閾值來判斷 if 4 * 3.14 * (area / 3.14) ** 0.5 / perimeter > 0.8 and 4 * 3.14 * (area / 3.14) ** 0.5 / perimeter < 1.2: shape = 'Circle' else: shape = 'Other Polygon' # 在圖像上標(biāo)注形狀名稱和頂點(diǎn)數(shù)目 M = cv2.moments(contour) if M['m00'] != 0: cX = int(M['m10'] / M['m00']) cY = int(M['m01'] / M['m00']) else: cX, cY = 0, 0 # 繪制形狀名稱和頂點(diǎn)數(shù)目 cv2.putText(contour_img, f'{shape} ({num_vertices} vertices)', (cX - 50, cY - 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2) # 繪制輪廓(近似多邊形) cv2.drawContours(contour_img, [approx], -1, (0, 0, 255), 2) # 顯示結(jié)果圖像 cv2.imshow('Shape Detection', contour_img) cv2.waitKey(0) cv2.destroyAllWindows()
九、總結(jié)
本文介紹了如何使用Python和OpenCV庫實(shí)現(xiàn)圖像形狀檢測(cè)。通過環(huán)境準(zhǔn)備、圖像預(yù)處理、邊緣檢測(cè)、輪廓查找、繪制輪廓及形狀分類等步驟,展示了完整的圖像形狀檢測(cè)流程。利用高斯模糊、Canny邊緣檢測(cè)和輪廓近似等技術(shù),實(shí)現(xiàn)了對(duì)圖像中不同形狀的有效檢測(cè)與分類。通過示例代碼,讀者可以快速掌握?qǐng)D像形狀檢測(cè)的基本方法和技巧,為工業(yè)自動(dòng)化、機(jī)器人視覺等領(lǐng)域的實(shí)際應(yīng)用提供有力支持。
到此這篇關(guān)于Python OpenCV實(shí)現(xiàn)圖像形狀檢測(cè)的文章就介紹到這了,更多相關(guān)Python OpenCV形狀檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python使用json序列化datetime類型實(shí)例解析
這篇文章主要介紹了python使用json序列化datetime類型實(shí)例解析,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02Python中如何實(shí)現(xiàn)真正的按位取反運(yùn)算
按位取反是位運(yùn)算符,而位運(yùn)算符是應(yīng)用在兩個(gè)數(shù)的運(yùn)算上,會(huì)對(duì)數(shù)字的二進(jìn)制所有位數(shù)進(jìn)行從低到高的運(yùn)算,下面這篇文章主要給大家介紹了關(guān)于Python中如何實(shí)現(xiàn)真正的按位取反運(yùn)算的相關(guān)資料,需要的朋友可以參考下2023-02-02關(guān)于Python dict存中文字符dumps()的問題
這篇文章主要介紹了關(guān)于Python dict存中文字符dumps()的問題,本文給大家分享問題及解決方案,給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10Django-xadmin后臺(tái)導(dǎo)入json數(shù)據(jù)及后臺(tái)顯示信息圖標(biāo)和主題更改方式
這篇文章主要介紹了Django-xadmin后臺(tái)導(dǎo)入json數(shù)據(jù)及后臺(tái)顯示信息圖標(biāo)和主題更改方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03python的三目運(yùn)算符和not in運(yùn)算符使用示例
這篇文章主要介紹了python的三目運(yùn)算符和not in運(yùn)算符使用示例,需要的朋友可以參考下2014-03-03