OpenCV輪廓檢測全面解析:從基礎到高級應用

一、概述

? ? ? ?輪廓檢測是計算機視覺中的基礎技術,用于識別和提取圖像中物體的邊界。與邊緣檢測不同,輪廓檢測更關注將邊緣像素連接成有意義的整體,形成封閉的邊界。

輪廓檢測的核心價值
- 物體識別:通過輪廓可以識別圖像中的獨立物體
- 形狀分析:輪廓包含了物體的形狀特征信息
- 測量計算:基于輪廓可進行面積、周長等測量
- 圖像分割:是許多分割算法的基礎步驟

二、OpenCV輪廓檢測基礎

1.cv2.findContours

2. cv2.drawContours()

3.示例代碼


#查找輪廓的API:image,contours,hierarchy = cv2.findContours(img, mode, method)#
# 參數:img:需要實現輪廓檢測的原圖# mode:輪廓的檢索模式,主要有四種方式:
#      CV2.RETR_EXTERNAL:只檢測外輪廓,所有子輪廓被忽略并
#      CV2.RETR_LIST:檢測的輪廓不建立等級關系,所有輪廊屬于同一等級
#      CV2.RETR_CCOMP:返回所有的輪廓,只建立兩個級的輪。一個對象的外輪為第1級組織結構。
#          而對象內部中空洞的輪廊為第2級組織結構,空洞中的任何對象的輪又是第 1級組織結構。
#      cV2.RETR_TREE:返回所有的輪廓,建立一個完整的組織結構的輪廓。# method:輪廓的近似方法,主要有以下兩種:
#      CV2.CHAIN APPROX NONE:在儲所有的輪點。
#      CV2.CHAIN_APPROX_SIMPLE:壓縮模式,只保留該方向的終點坐標,例如一個矩形輪廊只需4 個點來保存輪信息。
# 返回:image:返回處理的原圖# contours:包含圖像中所有輪廊的list對象。其中每一個獨立的輪廊信息以邊界點坐標(x,y)的形式儲存在numpy數組中。# hierarchy:輪廊的層次結構。一個包含4個值的數組:[Next,Previous,First child, Parent]
#     Next:與當前輪廓處于同一層級的下一條輪
#     Previous:與當前輪廓處于同一層級的上一條輪
#     First child:當前輪廓的第一條子輪康
#     Parent:當前輪廓的父輪廓并
# 注意:做輪廊檢測前需要將圖片讀取為二值數據,即像素值只為0和255.import cv2
phone = cv2.imread('phone.png')
phone_grey=cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
cv2.imshow('phone_b',phone_grey)
cv2.waitKey(0)ret,phone_binary=cv2.threshold(phone_grey,120,255,cv2.THRESH_BINARY)
cv2.imshow('phone_binary',phone_binary)
cv2.waitKey(0)_,contours,hierarchy = cv2.findContours(phone_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)# # 輪廓的繪制
# # cv2.drawContours(image, contours, contourIdx, color, thickness=None,
# #                  lineType=None, hierarchy=None, maxLevel=None, offset=None)
# # 參數含義如下:
# # image:要在其上繪制輪廓的輸入圖像。
# # contours:輪廓列表,通常由cv2.findContours()函數返回。
# # contourIdx:要繪制的輪廓的索引。如果為負數,則繪制所有輪廓。 -1
# # color:輪廓的顏色,以BGR格式表示。例如,(0, 255, 0)表示綠色。
# # thickness:輪廓線的粗細。默認值為1。
# # lineType:輪廓線的類型。默認值為cv2.LINE_8。
# # hierarchy:輪廓層次結構。通常由cv2.findContours()函數返回。
# # maxLevel:繪制的最大輪廓層級。默認值為None,表示繪制所有層級。
# # offset:輪廓點的偏移量。默認值為None。
image_copy=phone.copy()
image_copy=cv2.drawContours(image=image_copy,contours=contours,contourIdx=-1,color=(0,255,0),thickness=2)
cv2.imshow('Contours',image_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()

?三、輪廓特征提取與分析

1. 基本特征計算


面積

??
周長



?

import cv2phone = cv2.imread('phone.png')
phone_grey=cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
cv2.imshow('phone_b',phone_grey)
cv2.waitKey(0)ret,phone_binary=cv2.threshold(phone_grey,120,255,cv2.THRESH_BINARY)
cv2.imshow('phone_binary',phone_binary)
cv2.waitKey(0)_,contours,hierarchy = cv2.findContours(phone_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)# #輪廓特征
# cv2.contourArea(contour[, oriented]) → retval      面積
# contour:頂點構成的二維向量組(如輪廓列表contours中的一個輪廓)
# oriented:定向區域標志,默認值為 False,返回面積的絕對值,Ture 時則根據輪廓方向返回帶符號的數值area_0 = cv2.contourArea(contours[0])
print(area_0)
area_1 = cv2.contourArea(contours[1])
print(area_1)# arcLength(InputArray curve, bool closed)              周長
# curve,輸入的二維點集(輪廓頂點),可以是 vector 或 Mat 類型。
# closed,用于指示曲線是否封閉。
length = cv2.arcLength(contours[0],closed=True)
print(length)
# 根據面積顯示特定輪廓
a_list=[]
# for i in range(len(contours)):
#     if cv2.contourArea(contours[i])>10000:
#         a_list.append(contours[i])
for i in contours:if cv2.contourArea(i)>10000:a_list.append(i)
image_copy = phone.copy()
image_copy = cv2.drawContours(image=image_copy, contours=a_list, contourIdx=-1,color=(0,255,0),thickness=3)
cv2.imshow('Contours_show_10000', image_copy)
cv2.waitKey(0)

2. 輪廓近似

# 輪廓的近似
# approx = cv2.approxPolyDP(curve, epsilon, closed)
# 參數說明:
# curve:輸入輪廓。
# epsilon:近似精度,即兩個輪廓之間最大的歐式距離。該參數越小,得到的近似結果越接近實際輪廓;反之,得到的近似結果會更加粗略。
# closed:布爾類型的參數,表示是否封閉輪廓。如果是 True,表示輸入輪廓是封閉的,近似結果也會是封閉的;否則表示輸入輪廓不是封閉的,近似結果也不會是封閉的。
# 返回值:approx:近似結果,是一個ndarray數組,為1個近似后的輪廓,包含了被近似出來的輪廓上的點的坐標
import cv2phone = cv2.imread('phone.png')
phone_gray = cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY) #轉換為灰度圖
ret,phone_thresh = cv2.threshold(phone_gray,120,255,cv2.THRESH_BINARY)  #二值化image, contours, hierarchy = cv2.findContours(phone_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)#獲取輪廓
# #計算所有輪廓面積并存儲在列表中
contours_with_area=[(cnt,cv2.contourArea(cnt)) for cnt in contours]
#根據輪廓面積降序排列
sorted_contours=sorted(contours_with_area,key=lambda x:x[1],reverse=True)
#如果你只需要降序后的輪廓,可以直接提取出來
aa=sorted_contours[0][0]
print(aa)epsilon = 0.01 * cv2.arcLength(aa,True)        #設置近似精度
approx = cv2.approxPolyDP(aa, epsilon, True)   #對輪廓進行近似
print(approx.shape)
phone_new = phone.copy()
image_contours = cv2.drawContours(phone_new,[approx],contourIdx=-1,color=(0,255,0),thickness=3)#繪制輪廓
cv2.imshow('phone',phone)
cv2.waitKey(0)
cv2.imshow('image_contours',image_contours)
cv2.waitKey(0)
# # $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
# # 外接圓、外接矩形,...
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)
cv2.waitKey(0)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)
cv2.waitKey(0)

3. 輪廓匹配


# 形狀匹配(值越小匹配越好)
match_value = cv2.matchShapes(cnt1, cnt2, cv2.CONTOURS_MATCH_I1, 0)# 模板匹配
template = cv2.imread('template.png',0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res >= threshold)

總結

? ? ? ?OpenCV的輪廓檢測功能強大而靈活,從簡單的物體識別到復雜的形狀分析都能勝任。掌握輪廓檢測技術需要注意以下幾點:
1. 良好的預處理是成功的關鍵
2. 根據應用場景選擇合適的輪廓檢索模式
3. 合理利用輪廓特征進行篩選和分析
4. 高級應用常需要結合其他圖像處理技術

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/74820.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74820.shtml
英文地址,請注明出處:http://en.pswp.cn/web/74820.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Jenkins學習(B站教程)

文章目錄 1.持續集成CI2.持續交付CD3.持續部署4.持續集成的操作流程5.jenkins簡介6.后續安裝部署,見視頻 bilibili視頻 Jenkins是一個開源的、提供友好操作界面的持續集成(CI)工具,起源于Hudson(Hudson是商用的),主要用…

ARM-UART

時鐘選擇PLCK,超時3ms自動發送,設置發送8位的緩沖區,且發送中斷 設置觸發深度,達到8字節將緩沖區數據發憷 中斷處理函數

Rust所有權詳解

文章目錄 Rust所有權所有權規則作用域 內存和分配移動與克隆棧空間堆空間 關于函數的所有權機制作為參數作為返回值 引用與租借垂懸引用 Rust所有權 C/C中我們對于堆內存通常需要自己手動管理,手動申請和釋放,即便有了智能指針,對于效率的影…

【在線OJ項目測試報告】

朋友們、伙計們,我們又見面了,本期來給大家帶來關于在線OJ項目的測試報告,如果看完之后對你有一定的啟發,那么請留下你的三連,祝大家心想事成! C 語 言 專 欄:C語言:從入門到精通 數…

【HFP】藍牙HFP應用層核心技術研究

免提配置文件(Hands-Free Profile, HFP)作為實現設備間音頻通信的關鍵協議,廣泛應用于車載系統、藍牙耳機等場景。本文將基于最新技術規范,深入剖析HFP應用層的功能要求、協議映射及編解碼器支持,為藍牙開發工程師提供詳盡的技術指南。 一、HFP應用層功能全景圖 HFP定義…

橫掃SQL面試——PV、UV問題

📊 橫掃SQL面試:UV/PV問題 🌟 什么是UV/PV? 在數據領域,UV(Unique Visitor,獨立訪客) 和 PV(Page View,頁面訪問量) 是最基礎也最重要的指標&…

【C++】第八節—string類(上)——詳解+代碼示例

hello,又見面了! 云邊有個稻草人-CSDN博客 C_云邊有個稻草人的博客-CSDN博客——C專欄(質量分高達97!) 菜鳥進化中。。。 目錄 一、為什么要學習string類? 1.1 C語言中的字符串 1.2 面試題(暫不做講解) …

如何判斷JVM中類和其他類是不是同一個類

如何判斷JVM中的類是否為同一個類 在Java虛擬機(JVM)中,判斷兩個類是否相同需要同時滿足以下三個條件: 1. 類全限定名必須相同 包括包名類名的完整路徑必須完全一致例如:java.lang.String和com.example.String被視為不同類 2. 加載該類的…

ifconfig 使用詳解

目錄 一、基本語法二、常見用途及示例1. 查看所有網絡接口信息2. 啟用/禁用網絡接口3. 配置 IP 地址和子網掩碼4. 修改 MAC 地址5. 啟用混雜模式(Promiscuous Mode)6. 設置 MTU(最大傳輸單元) 三、其他選項四、常見問題1. 新系統中…

1. 標準庫的強依賴(核心原因)

1. 標準庫的強依賴(核心原因) 容器操作(如 std::vector 擴容) 當標準庫容器(如 std::vector)需要重新分配內存時,它會嘗試移動現有元素到新內存,而非拷貝(為了性能&…

【MySQL】常用SQL--持續更新ing

一、配置信息類 1.查看版本 select version; 或 select version(); 2.查看配置 show global variables where variable_name in (basedir,binlog_format,datadir,expire_logs_days,innodb_buffer_pool_size,innodb_log_buffer_size,innodb_log_file_size,innodb_log_files_i…

Day82 | 靈神 | 快慢指針 重排鏈表

Day82 | 靈神 | 快慢指針 重排鏈表 143.重排鏈表 143. 重排鏈表 - 力扣(LeetCode) 思路: 筆者直接給跪了,這個難度真是mid嗎 直接去看靈神的視頻 環形鏈表II【基礎算法精講 07】_嗶哩嗶哩_bilibili 1.簡單來說就是&#xf…

常見的微信個人號二次開發功能

一、常見開發功能 1. 好友管理 好友列表維護 添加/刪除好友 修改好友信息(備注、標簽等) 分組管理 創建/編輯/刪除標簽 好友分類與篩選 2. 消息管理 信息發送 支持多類型內容:文本、圖片、視頻、文件、小程序、名片、URL鏈接等 附加功…

Android打包及上架應用市場問題處理

一、Gradle 配置參數含義: compileSdkVersion: 29 表示項目編譯時使用的 Android SDK 版本為 API 29(Android 10),僅影響編譯階段的行為(如代碼語法檢查、資源處理等),不直接影響運行時兼容性。…

Docker 從入門到進階 (Win 環境) + Docker 常用命令

目錄 引言 一、準備工作 1.1 系統要求 1.2 啟用虛擬化 二、安裝Docker 2.1 安裝WSL 2 2.2 安裝Docker Desktop 2.3檢查是否安裝成功 三、配置Docker 3.1 打開Docker配置中心 四、下載和管理Docker鏡像 4.1 拉取鏡像 4.2 查看已下載的鏡像 4.3 運行容器 4.4 查看正…

計算機視覺5——運動估計和光流估計

一、運動估計 (一)運動場(Motion Field) 定義與物理意義 運動場是三維場景中物體或相機運動在二維圖像平面上的投影,表現為圖像中每個像素點的運動速度矢量。其本質是場景點三維運動(平移、旋轉、縮放等&a…

介質訪問控制——信道劃分

什么是介質訪問 介質訪問(Medium Access)? 是計算機網絡中一種規則,用來解決 ??“多臺設備如何共享同一根網線/信道傳輸數據”? 的問題。你可以理解為: 想象一條只能容一輛車通過的獨木橋(網絡中的網線、Wi-Fi信道…

ERP系統五大生產模式概述

制造業中,選擇合適的生產模式是企業高效運營的關鍵。 以下是ERP系統支持的五大核心生產模式及其特點總結: 1. MTS(按庫存生產) - 定義:先生產后銷售,基于需求預測提前備貨。 - 適用場景:需求穩定、標準化程度高的產品(如日用品、家電)。 - 優點:交貨快、生產…

ubantu操作筆記

安裝ssh服務 1.1 基本安裝 sudo apt update sudo apt install openssh-server -y sudo systemctl start ssh sudo systemctl enable ssh 1.2 配置遠程root登陸 # 0. 設置root密碼 sudo passwd root # 1. 安裝vim依賴 sudo apt-get install vim -y # 2. 編輯配置文件 s…

2-vim編輯器的安裝和使用

一.常用工具介紹 前言: 我們想要編寫c語言代碼,可以使用linux系統提供的工具才能進行代碼的編輯。代碼編寫后,我們還需要驗證代碼的書寫正確。這就需要借助編譯器來進行驗證。linux系統為我們提供了比較好的開發工具。 vim編輯器&#xff…