OpenCV 圖像輪廓檢測

目錄

一、輪廓檢測基礎概念

二、核心 API 詳解:cv2.findContours ()

參數說明:

返回值說明:

三、輪廓檢測實戰步驟

1. 圖像預處理(灰度化與二值化)

2. 查找輪廓

3. 繪制輪廓

四、輪廓的常用屬性與操作

1. 輪廓面積與周長

2. 輪廓篩選與排序

3. 輪廓的外接形狀

4. 輪廓近似

五、總結


在計算機視覺領域,輪廓檢測是一項基礎且重要的技術,它能夠幫助我們識別圖像中的物體邊界,為后續的圖像分析、目標識別等任務提供關鍵信息。本文將基于 OpenCV 庫,詳細介紹輪廓檢測的原理、常用 API 及實戰應用。


一、輪廓檢測基礎概念

輪廓可以理解為圖像中具有相同顏色或灰度的連續點組成的曲線,它是物體邊界的有效表達方式。在進行輪廓檢測前,有一個重要的前提:需要將圖片處理為二值圖像(像素值只為 0 和 255),這是因為輪廓檢測主要基于圖像的邊緣信息,二值化處理能簡化后續的檢測過程。


二、核心 API 詳解:cv2.findContours ()

OpenCV 提供了?cv2.findContours()?函數用于檢測圖像輪廓,其語法格式如下:

參數說明:

  1. img:需要進行輪廓檢測的輸入圖像(必須是二值圖像)

  2. mode:輪廓的檢索模式,常用的有以下四種:

    • cv2.RETR_EXTERNAL:只檢測外輪廓,忽略所有子輪廓
    • cv2.RETR_LIST:檢測所有輪廓,但不建立等級關系
    • cv2.RETR_CCOMP:返回所有輪廓,僅建立兩級層次結構(外輪廓為第 1 級,內部中空輪廓為第 2 級)
    • cv2.RETR_TREE:返回所有輪廓,建立完整的層級組織結構
  3. method:輪廓的近似方法:

    • cv2.CHAIN_APPROX_NONE:存儲所有的輪廓點
    • cv2.CHAIN_APPROX_SIMPLE:壓縮模式,只保留輪廓方向的終點坐標(如矩形僅保留 4 個頂點)

返回值說明:

  • image:處理后的圖像(與輸入圖像相關)
  • contours:包含所有輪廓的列表,每個輪廓是由邊界點坐標 (x,y) 組成的 numpy 數組
  • hierarchy:輪廓的層次結構,每個元素是包含 4 個值的數組?[Next, Previous, First Child, Parent],分別表示:
    • Next:同一層級的下一條輪廓
    • Previous:同一層級的上一條輪廓
    • First Child:當前輪廓的第一條子輪廓
    • Parent:當前輪廓的父輪廓

注意:在新版 OpenCV(如 4.x 版本)中,該函數返回值為 (contours, hierarchy),可使用?contours = cv2.findContours(...)[-2]?兼容不同版本。


三、輪廓檢測實戰步驟

1. 圖像預處理(灰度化與二值化)

輪廓檢測前必須進行預處理,將彩色圖像轉為灰度圖,再進一步轉為二值圖:

import cv2# 讀取原圖
phone = cv2.imread('phone.png')
# 轉為灰度圖
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)
# 二值化處理(閾值 120,最大值 255,二值化方式)
ret, phone_binary = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY)# 顯示處理結果
cv2.imshow('phone_gray', phone_gray)
cv2.imshow('phone_binary', phone_binary)
cv2.waitKey(0)

2. 查找輪廓

使用?cv2.findContours()?函數檢測輪廓:

# 查找輪廓(建立完整層級,壓縮輪廓點)
_, contours, hierarchy = cv2.findContours(phone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 打印輪廓信息
print("輪廓層次結構:", hierarchy)
print("輪廓數量:", len(contours))
輪廓層次結構: [[[ 6 -1  1 -1][ 2 -1 -1  0][ 3  1 -1  0][ 4  2 -1  0][ 5  3 -1  0][-1  4 -1  0][ 7  0 -1 -1][ 8  6 -1 -1][-1  7 -1 -1]]]
輪廓數量: 9

3. 繪制輪廓

通過?cv2.drawContours()?函數可以將檢測到的輪廓繪制在圖像上:

# 函數語法
# cv2.drawContours(image, contours, contourIdx, color, thickness)# 復制原圖避免修改原圖
image_copy = phone.copy()
# 繪制所有輪廓(contourIdx=-1),綠色(0,255,0),線寬 2
cv2.drawContours(image_copy, contours, -1, (0,255,0), 2)
cv2.imshow('contours_result', image_copy)
cv2.waitKey(0)


四、輪廓的常用屬性與操作

1. 輪廓面積與周長

  • 輪廓面積:使用?cv2.contourArea()?計算
  • 輪廓周長:使用?cv2.arcLength()?計算(參數?closed=True?表示閉合輪廓)
# 計算第一個輪廓的面積
area_0 = cv2.contourArea(contours[0])
print("第一個輪廓的面積:", area_0)# 計算第一個輪廓的周長
length = cv2.arcLength(contours[0], closed=True)
print("第一個輪廓的周長:", length)
第一個輪廓的面積: 50716.5
第一個輪廓的周長: 952.4377244710922

2. 輪廓篩選與排序

可以根據輪廓面積等屬性篩選特定輪廓,或對輪廓進行排序:

# 篩選面積大于 10000 的輪廓
large_contours = []
for cnt in contours:if cv2.contourArea(cnt) > 10000:large_contours.append(cnt)# 繪制篩選后的輪廓
image_copy = phone.copy()
cv2.drawContours(image_copy, large_contours, -1, (0,255,0), 3)
cv2.imshow('contours_larger_10000', image_copy)
cv2.waitKey(0)# 按面積降序排序,取最大面積的輪廓
largest_cnt = sorted(contours, key=cv2.contourArea, reverse=True)[0]
image_copy = phone.copy()
cv2.drawContours(image_copy, [largest_cnt], -1, (0,255,0), 3)
cv2.imshow('largest_contour', image_copy)
cv2.waitKey(0)

3. 輪廓的外接形狀

可以計算輪廓的外接圓和最小外接矩形:

# 以外接圓為例(選取第三個輪廓)
cnt = contours[2]
# 計算外接圓
(x, y), r = cv2.minEnclosingCircle(cnt)
# 繪制外接圓
phone_circle = cv2.circle(phone, (int(x), int(y)), int(r), (0,255,0), 2)
cv2.imshow('contour_circle', phone_circle)
cv2.waitKey(0)# 計算最小外接矩形
x, y, w, h = cv2.boundingRect(cnt)
# 繪制矩形
phone_rect = cv2.rectangle(phone, (x, y), (x+w, y+h), (0,255,0), 2)
cv2.imshow('contour_rectangle', phone_rect)
cv2.waitKey(0)

4. 輪廓近似

使用?cv2.approxPolyDP()?函數可以對輪廓進行近似處理,簡化輪廓形狀:

# 函數語法
# approx = cv2.approxPolyDP(curve, epsilon, closed)# 計算近似精度(取輪廓周長的 0.01 倍)
epsilon = 0.01 * cv2.arcLength(contours[0], True)
# 對第一個輪廓進行近似
approx = cv2.approxPolyDP(contours[0], epsilon, True)# 對比原始輪廓與近似輪廓的點數量
print("原始輪廓點數量:", contours[0].shape[0])
print("近似輪廓點數量:", approx.shape[0])# 繪制近似輪廓
phone_new = phone.copy()
cv2.drawContours(phone_new, [approx], -1, (0,255,0), 3)
cv2.imshow('contour_approx', phone_new)
cv2.waitKey(0)
原始輪廓點數量: 235
近似輪廓點數量: 8

其中,epsilon?參數決定了近似精度:值越小,近似結果越接近原始輪廓;值越大,輪廓越簡化。


五、總結

本文詳細介紹了 OpenCV 中輪廓檢測的核心技術,包括輪廓檢測的預處理步驟、cv2.findContours()?函數的使用、輪廓繪制方法以及輪廓的各種屬性計算與操作(面積、周長、篩選、排序、外接形狀、輪廓近似等)。

輪廓檢測在目標識別、圖像分割、物體測量等領域有著廣泛的應用,掌握這些基礎操作是進行更復雜計算機視覺任務的前提。實際應用中,需要根據具體場景選擇合適的輪廓檢索模式和近似方法,以達到最佳的檢測效果。

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

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

相關文章

【圖論】 Graph.jl 概覽

文章目錄安裝基礎使用基本操作全局圖的指標頂點性質邊性質讀寫圖按照 .lgz 格式存儲圖數據(壓縮格式)按照 .lg 格式存儲圖數據(非壓縮格式)圖的繪制TikzGraphs.jl Latex 論文風格GraphPlot.jl 通常與 Compose.jl 一起使用SGtSNEpi…

[java] 控制三個線程按順序交替輸出數字123123…

控制三個線程按順序交替輸出數字123123… synchronized(配合專用鎖對象) 通過共享鎖和 volatile 變量控制執行順序,每個線程按指定順序打印指定內容,確保輸出序列如 “123123…”。使用 synchronized 和 wait/notifyAll 實現線程間…

[C#]winform基于yolov8-seg實現的指甲分割實現源碼

【測試環境】 vs2019 net framework4.7.2 onnxruntime1.16.3 opencvsharp 注意源碼運行在CPU上不支持GPU運行,由于net framework限制GPU會很慢因此沒有GPU版本提供。 【運行步驟】 打開sln項目 選擇x64 debug運行即可 如需要再x64 release運行可以將x64 debu…

數據結構——線性表(鏈表,力扣中等篇,增刪查改)

文章目錄一、增刪查改1.1增(插入節點)1.1.1兩數后插入公約數1.1.2循環有序鏈表的插入1.2刪(移除節點)1.2.1刪除已知的node節點【交換val值】1.2.2移除數組中已存在的節點【unordered_set】1.2.3刪除和為0的節點【前綴和】1.3改&am…

【Android】OkHttp發起GET請求 POST請求

三三要成為安卓糕手 一:OkHttp介紹 OkHttp 是一個開源的、強大且高效的 HTTP 客戶端庫,主要用于在 Java后端和Android 項目中進行網絡請求。 //在gradle中添加依賴 com.squareup.okhttp3:okhttp:4.12.0二:GET請求/*** 使用OkHttp發起get請求*…

[Mysql數據庫] 知識點總結8

1. 請詳細描述在復制拓撲中參與復制的線程類型以及各自所承擔的功能。答:當從屬服務器連接到主服務器時,在主服務器上會創建 Binlog 轉儲線程,在從屬服務器上會默 認創建 I/O 線程和 SQL 線程。- Binlog 轉儲線程用于從二進制日志讀取事件并將…

250829-Gitlab數據備份與恢復

下面給你一份可落地的遷移方案,保證 GitLab 的數據和配置完整遷移到服務器 B。你當前用的是 GitLab Omnibus(docker 版),數據都在你映射的 3 個目錄里(/etc/gitlab, /var/log/gitlab, /var/opt/gitlab)&…

吳恩達機器學習作業十一:異常檢測

數據集在作業一異常檢測異常檢測就是發現與大部分對象不同的對象,其實就是發現離群點。異常檢測有時也稱偏差檢測。異常對象是相對罕見的。用數據集建立概率模型p ( x ),如果新的測試數據在這個模型上小于某個閾值,則說它極大可能為異常點算法…

2000w 的數據量,mysql要進行幾次IO操作,為什么

在 MySQL 中,2000 萬數據量的表在進行查詢時所需的 ??IO 操作次數??主要取決于 ??索引結構(B樹層級)??、??查詢類型??和 ??數據分布特征??。以下是具體分析:一、B樹層級與 IO 次數的關系InnoDB 引擎通過 B樹索引管…

【代碼隨想錄day 22】 力扣 39. 組合總和

視頻講解:https://www.bilibili.com/video/BV1KT4y1M7HJ/?vd_sourcea935eaede74a204ec74fd041b917810c 文檔講解:https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html#%E6%80%9D%E8%B7%AF 力扣題目:https://leetcod…

DrissionPage 實戰:動態 IP 代理與百度翻譯 API 數據抓取

本文將詳細介紹如何使用 DrissionPage 實現動態 IP 代理訪問,并結合百度翻譯 API 進行數據抓取與處理。一、技術選型與架構設計1.1 為什么選擇 DrissionPage?DrissionPage 作為新一代網絡自動化工具,相比傳統 Selenium Requests 方案具有顯著…

策略模式:靈活應對算法動態切換

引言 在軟件開發中,我們常常會遇到需要在運行時動態選擇和切換算法或行為的場景。例如,電商系統中的多種支付方式、游戲中的不同難度設置,或是計算器中的各種運算符。傳統的方法可能會使用復雜的條件判斷語句(如if-else或switch-c…

【C++ 】string類:深拷貝與淺拷貝解析

【C 】string類操作全解析-CSDN博客 1.stirng類的模擬實現 1.1 經典的string類問題 上面已經對string類進行了簡單的介紹,大家只要能夠正常使用即可。在面試中,面試官總喜歡要求自己來模擬實現string類,最主要是實現string類的構造、拷貝…

Decoder 解碼器

Decoder 解碼器&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h>#include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libswscale/swscale.h>#define WORD uint16_t #define DWORD ui…

globals() 小技巧

scheduler_class globals()[scheduler_class_name] Python 中一種 動態獲取類對象 的常用技巧&#xff0c;屬于 反射&#xff08;reflection&#xff09; 編程的范疇globals()Python 內置函數&#xff0c;返回一個 字典&#xff08;dict&#xff09;&#xff0c;包含當前模塊&…

Android Studio 9.png制作

一、新建 二、把要做的圖png導入進去 png圖片建議 根據內容預留1像素可拉伸區域 eg:純色或可漸變底色 三、右邊創建.9.png 四、雙擊打開 1、繪制黑邊 參考視頻 2、縮放到800% ,移至右下 3、在下面和右邊繪制整根黑線 4、根據png 位置左側和上側黑線 4.1 分析 紅色方框為…

【百度】C++開發(25屆提前批 一面)面經

文章目錄1. 代碼實現&#xff1a;說說LRU&#xff0c;并代碼實現LRU為什么使用哈希表&#xff1f;&#xff08;有兩個原因&#xff09;1. 僅用雙向鏈表的缺陷2. 引入哈希表的作用1. 快速查找&#xff1a;2. 快速插入與刪除&#xff1a;雙向鏈表 哈希表的協作過程舉例說明代碼實…

Word文檔怎么打印?Word打印技巧?【圖文詳解】單面/雙面/指定頁面/逆序等Word打印選項

一、問題背景 在日常辦公、學習場景中&#xff0c;Word文檔作為常用的文字處理載體&#xff0c;經常需要將電子內容轉化為紙質版本&#xff0c;比如提交報告、打印學習資料、整理文檔存檔等。 但不少用戶在嘗試打印Word文檔時&#xff0c;常會遇到各種阻礙&#xff1a;有的不清…

漫談《數字圖像處理》之基函數與基圖像

在數字圖像處理領域&#xff0c;基函數與基圖像是貫穿理論分析與實際應用的核心概念 —— 它們如同 “樂高積木”&#xff0c;將復雜的圖像信號拆解為可解釋、可操作的基本單元&#xff0c;支撐起壓縮、去噪、特征提取等一系列關鍵任務。從傳統的傅里葉變換到前沿的因子場理論&…

打開多個Excel文件后快速關閉所有的文檔,并且退出Excel應用

打開多個Excel文件后如果要快速關閉所有的文檔&#xff0c;并且退出Excel應用&#xff0c;可以按住Shift鍵右上角的號&#xff08;關閉按鈕&#xff09;。Word和PowerPoint也是一樣的操作。如果有文檔修改后沒有保存&#xff0c;會提示是否保存。作為補充&#xff0c;先來看看兩…