計算機視覺(九):圖像輪廓

在計算機視覺(Computer Vision, CV)中,圖像輪廓(Image Contour)是圖像中物體邊界的重要表現形式。它不僅能描述物體的形狀特征,還能為目標識別、目標檢測、圖像分割、場景理解、三維重建等任務提供重要依據。與像素級的邊緣檢測相比,輪廓更強調封閉的邊界、整體性和幾何結構。

基本概念

定義

在圖像處理中,輪廓通常指圖像中前景目標與背景之間的邊界線。它是一個閉合曲線,可以用像素點序列來表示。

  • 對于二值圖像,輪廓是前景與背景的交界線。
  • 對于灰度圖像,輪廓常通過邊緣檢測或閾值分割得到。

輪廓與邊緣的區別

  • 邊緣(Edge):灰度強度發生顯著變化的位置,可能是不連續的。
  • 輪廓(Contour):物體的完整邊界,更強調閉合性和結構性。

數學表示

若一個二值目標區域記為 R,則其輪廓 C 可表示為:

在這里插入圖片描述

即邊界點是區域中與背景相鄰的像素點集合。

提取方法

輪廓提取的目標是將圖像中物體的邊界點序列化,形成閉合曲線。

1. 閾值分割 + 輪廓提取

  • 先通過全局閾值(如 Otsu 算法)或自適應閾值將圖像轉為二值圖。
  • 然后使用輪廓追蹤算法(如 OpenCV findContours)提取邊界。
  • 優點:簡單高效,適合對比度清晰的目標。
  • 缺點:對噪聲和光照敏感。

2. 邊緣檢測 + 輪廓連接

  • 常用邊緣算子:Sobel、Canny、Laplacian。
  • 檢測到邊緣后,通過連通域分析、霍夫變換或形態學操作獲得閉合輪廓。
  • 適合復雜紋理和低對比度圖像。

3. 形態學方法

  • 利用腐蝕(Erode)、膨脹(Dilate)、開運算、閉運算等形態學操作去噪或填洞。
  • 提取骨架(Skeletonization)后再追蹤輪廓。
  • 常用于噪聲較多的工業檢測任務。

4. 主動輪廓模型(Snake)

  • 通過能量函數(包含圖像梯度約束和曲線光滑性約束)使輪廓曲線自動收縮到物體邊界。
  • 優點:輪廓連續性好,可處理復雜目標。
  • 缺點:依賴初始輪廓位置,計算復雜。

5. 基于深度學習的方法

  • 使用語義分割(如 U-Net、Mask R-CNN)獲得物體區域,再提取輪廓。
  • 優點:魯棒性強,適應復雜場景。
  • 缺點:需要大量訓練數據。

輪廓的表示與特征

提取到輪廓后,需要對其進行表示和特征化,便于后續處理。

1. 邊界鏈碼(Chain Code)

  • 以起點為基準,用 4 鄰域或 8 鄰域的方向序列描述輪廓。
  • 優點:存儲緊湊。
  • 缺點:不平移不變。

2. 多邊形逼近

  • 用折線逼近復雜輪廓,例如 Douglas-Peucker 算法。
  • 常用于簡化輪廓,提高計算效率。

3. 矩(Moments)

  • 幾何矩:描述面積、質心。
  • Hu 不變矩:在旋轉、縮放、平移下保持不變,適合形狀識別。

4. 傅里葉描述子

  • 將輪廓點序列看作復數序列,做傅里葉變換。
  • 低頻分量表示整體形狀,高頻分量表示細節。
  • 可用于形狀匹配。

5. 曲率與角點

  • 曲率較大的點通常對應物體的特征角點。
  • 在目標識別和姿態估計中很重要。

OpenCV中的輪廓查找

核心函數

cv2.findContours()函數

查找輪廓。

contours, hierarchy = cv2.findContours(image, mode, method)

參數解析:

  • image: 輸入的二值圖像。注意: 此函數會修改輸入圖像,通常建議傳入一個副本。
  • mode: 輪廓檢索模式,決定了如何組織輪廓的層級關系。
    • cv2.RETR_EXTERNAL: 只檢索最外層的輪廓。
    • cv2.RETR_LIST: 檢索所有輪廓,但不建立任何層級關系。
    • cv2.RETR_CCOMP: 檢索所有輪廓,并將它們組織成兩級層次結構(外部輪廓和孔洞)。
    • cv2.RETR_TREE: 檢索所有輪廓,并建立完整的輪廓層次結構樹。
  • method: 輪廓近似方法,決定如何存儲輪廓點。
    • cv2.CHAIN_APPROX_NONE: 存儲輪廓上所有的點。
    • cv2.CHAIN_APPROX_SIMPLE: 只存儲輪廓的端點,例如,一個矩形只存儲四個角點。

返回值:

  • contours: 找到的所有輪廓的列表。每個輪廓都是一個 NumPy 數組,包含了該輪廓的所有點。
  • hierarchy: 一個可選的層級信息數組。它告訴我們每個輪廓的父輪廓、子輪廓、上一個輪廓和下一個輪廓。

cv2.drawContours()函數

在圖像上繪制找到的輪廓。

cv2.drawContours(image, contours, contourIdx, color, thickness)

參數解析:

  • image: 要在上面繪制輪廓的圖像。
  • contours: 輪廓列表,通常是 cv2.findContours() 的返回值。
  • contourIdx: 輪廓的索引,指定繪制哪個輪廓。如果要繪制所有輪廓,傳入 -1
  • color: 輪廓的顏色,以 (B, G, R) 元組形式表示。
  • thickness: 輪廓線的粗細。如果傳入 -1cv2.FILLED,則輪廓內部會被填充。

示例

查找并繪制圖像中的輪廓

import cv2
import numpy as np# 1. 讀取圖像并轉換為灰度圖
image = cv2.imread('shape.png') 
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 2. 圖像閾值化
# 將圖像轉換為二值圖像,大于127的像素變為255,否則變為0
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 3. 查找輪廓
# 檢索所有輪廓,并使用簡單的近似方法
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 4. 在原圖上繪制輪廓
# 繪制所有輪廓,顏色為綠色,粗細為2
output_image = image.copy()
cv2.drawContours(output_image, contours, -1, (0, 255, 0), 2)# 5. 顯示結果
cv2.imshow('Original Image', image)
cv2.imshow('Binary Image', thresh)
cv2.imshow('Contours', output_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

執行效果:

在這里插入圖片描述

形狀分析與測量

通過計算輪廓的面積、周長等屬性來了解物體的基本幾何信息。

import cv2
import numpy as np# 1. 創建一個二值圖像
img = np.zeros((300, 300), dtype=np.uint8)
# 畫一個圓,填充它
cv2.circle(img, (150, 150), 80, 255, -1)# 2. 查找輪廓
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 獲取第一個也是唯一的輪廓
cnt = contours[0]# 3. 計算輪廓屬性
area = cv2.contourArea(cnt)
perimeter = cv2.arcLength(cnt, True) # True 表示輪廓是閉合的#print(f"輪廓面積: {area}")
#print(f"輪廓周長: {perimeter}")# 4. 繪制輪廓的邊界框和最小外接圓
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(img, (x, y), (x + w, y + h), (100), 2)(center_x, center_y), radius = cv2.minEnclosingCircle(cnt)
center = (int(center_x), int(center_y))
radius = int(radius)
cv2.circle(img, center, radius, (100), 2)cv2.imshow("Shape Analysis", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

執行效果:

在這里插入圖片描述

形狀匹配

形狀匹配用于比較兩個輪廓的相似度。這在物體識別、缺陷檢測等任務中非常有用。cv2.matchShapes 函數是實現這一功能的關鍵。

import cv2
import numpy as np# 1. 定義兩個形狀(輪廓)
# 第一個形狀:矩形
rect = np.zeros((200, 200), dtype=np.uint8)
cv2.rectangle(rect, (50, 50), (150, 150), 255, -1)
contours1, _ = cv2.findContours(rect, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 第二個形狀:旋轉的矩形
rotated_rect = np.zeros((200, 200), dtype=np.uint8)
M = cv2.getRotationMatrix2D((100, 100), 45, 1) # 旋轉45度
rotated_rect = cv2.warpAffine(rect, M, (200, 200))
contours2, _ = cv2.findContours(rotated_rect, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 2. 匹配兩個形狀
# cv2.CONTOURS_MATCH_I1 是一個常用的方法
match_score = cv2.matchShapes(contours1[0], contours2[0], cv2.CONTOURS_MATCH_I1, 0)print(f"result: {match_score}")
# 分數越低,兩個形狀越相似。理想情況下,完全相同的形狀得分為0。
# 即使形狀經過旋轉、縮放或平移,matchShapes函數也能很好地工作。cv2.imshow("Original", rect)
cv2.imshow("Rotated", rotated_rect)
cv2.waitKey(0)
cv2.destroyAllWindows()

執行結果:

在這里插入圖片描述

基于輪廓的圖像分割與對象提取

找到輪廓后,可以用它來創建一個掩模(Mask),以精確地從原始圖像中提取出物體。

import cv2
import numpy as np# 1. 讀取彩色圖像
image = cv2.imread('object.jpg')# 2. 轉到 HSV 顏色空間
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)# 3. 定義顏色范圍(這里以綠色圓為例)
lower_green = np.array([40, 50, 50])
upper_green = np.array([80, 255, 255])# 4. 生成掩模
mask = cv2.inRange(hsv, lower_green, upper_green)# 5. 提取物體
extracted_object = cv2.bitwise_and(image, image, mask=mask)# 6. 顯示
cv2.imshow("Original", image)
cv2.imshow("Mask", mask)
cv2.imshow("Extracted Object", extracted_object)
cv2.waitKey(0)
cv2.destroyAllWindows()

執行效果:

在這里插入圖片描述

輪廓近似與多邊形擬合

輪廓可能包含成千上萬個點,為了簡化形狀并減少計算量,可以使用多邊形擬合。

import cv2
import numpy as np# 1. 創建一個形狀(這里是一個圓,但可以用于任何復雜的形狀)
img = np.zeros((300, 300), dtype=np.uint8)
cv2.circle(img, (150, 150), 100, 255, -1)# 2. 查找輪廓
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 使用CHAIN_APPROX_NONE來獲取所有點
original_contour = contours[0]# 3. 輪廓近似
# 參數 epsilon 決定了近似的精度,值越小,近似越接近原始輪廓
epsilon = 0.04 * cv2.arcLength(original_contour, True)
approx_contour = cv2.approxPolyDP(original_contour, epsilon, True)# 4. 繪制原始輪廓和近似后的輪廓
# 原始輪廓(紅色)
original_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
cv2.drawContours(original_img, [original_contour], -1, (0, 0, 255), 2)# 近似輪廓(綠色)
approx_img = np.zeros_like(original_img)
cv2.drawContours(approx_img, [approx_contour], -1, (0, 255, 0), 2)
cv2.imshow("Original vs. Approximated", np.hstack([original_img, approx_img]))
cv2.waitKey(0)
cv2.destroyAllWindows()

執行效果:

在這里插入圖片描述

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

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

相關文章

ThinkPHP 6框架常見錯誤:htmlentities()函數參數類型問題解決

在ThinkPHP 6框架中,htmlentities() 函數是一個常用的PHP函數,用于將字符轉換為HTML實體。這個函數通常在輸出內容到瀏覽器時使用,以防止跨站腳本(XSS)攻擊。然而,在使用過程中可能會遇到參數類型問題。錯誤…

網絡通信 IO 模型學習總結基礎強化

網絡通信概念網絡通信因為要處理復雜的物理信號,錯誤處理等,所以采用了分層設計。為什么要采用分層設計?1. 每層可以獨立開發,測試和替換;2. 發生問題也可以快速定位到具體層次;3. 協議標準化,不…

【ComfyUI】深度 ControlNet 深度信息引導生成

今天給大家演示一個結合 ControlNet 深度信息的 ComfyUI 建筑可視化工作流。整個流程通過引入建筑專用的權重模型和深度控制網絡,使得生成的建筑圖像不僅具備高質量和超寫實的細節,還能精確遵循輸入圖片的結構特征。在這個案例中,模型加載、文…

Python數據可視化科技圖表繪制系列教程(六)

目錄 散點圖1 散點圖2 添加線性回歸線的散點圖 自定義點形狀的散點圖 不同樣式的散點圖 抖動散點圖 邊際圖 邊緣為直方圖的邊際圖 邊緣為箱線圖的邊際圖 曼哈頓圖 【聲明】:未經版權人書面許可,任何單位或個人不得以任何形式復制、發行、出租、…

spring AI 的簡單使用

1. 引入 Spring 官?推出的?個穩定版??智能(AI)集成框架. 旨在幫助 Java/Spring 開發者更便捷地在企業級應?中集成 AI 能? (如?語?模型、機器學習、向量數據庫、圖像?成等)。 它主要提供了以下功能: ? ?持主要的AI模型提供商, ?如 Anthropic、OpenAI、M…

圖像去霧:從暗通道先驗到可學習融合——一份可跑的 PyTorch 教程

一、為什么“去霧”依然是好課題? 真實需求大:手機拍照、自動駕駛、遙感、監控都要在惡劣天氣下成像。 數據集相對干凈:與通用目標檢測相比,去霧只有“有霧/無霧”一對圖像,標注成本低。 傳統與深度并存:…

Ubuntu 22.04.1上安裝MySQL 8.0及設置root密碼

安裝MySQL 8.0 在 Ubuntu 22.04.1 系統需要遵循幾個明確的步驟,并在安裝過程中配置root密碼,以下是詳細的過程和相關的注意事項。步驟 1: 更新系統 使用終端更新系統軟件包列表以確保所有的包是最新的。sudo apt update sudo apt upgrade步驟 2: 安裝MyS…

用?content-visibility?即刻提速:那個被你忽略的 CSS 性能杠桿

我有一支技術全面、經驗豐富的小型團隊,專注高效交付中等規模外包項目,有需要外包項目的可以聯系我🔍 引言長頁面、信息密集、滾動遲滯?**content-visibility** 這項相對較新的 CSS 屬性,允許瀏覽器跳過視口外元素的渲…

字符串(2)

4.字符串的常見函數代碼#include <stdio.h> #include <string.h> int main() {char* str1 "abc";char str2[100] "abc";char str3[5] { q,w,e,r ,\0 };printf("---------------------strlen&#xff08;長度&#xff09;-------------…

案例分享|企微智能會話風控系統:為尚豐盈鋁業筑牢溝通安全防線

企微智能會話安全風險分析系統是一款基于企業微信原生集成的高性能處理平臺&#xff0c;其核心在于通過智能監測和AI風險識別技術&#xff0c;對員工與內外部客戶的聊天內容進行多模態分析&#xff08;涵蓋文本、圖片、語音、視頻、文件等多種形式&#xff09;&#xff0c;利用…

Paimon——官網閱讀:配置

配置(Maintenance) 系統表 表特定系統表 表特定系統表包含關于每個表的元數據和信息&#xff0c;例如創建的快照以及正在使用的選項。用戶可以通過批量查詢來訪問系統表。 目前&#xff0c;Flink、Spark、Trino 和 StarRocks 支持查詢系統表。 在某些情況下&#xff0c;表…

阿里云對象存儲OSS的使用

文章目錄注冊阿里OSS注冊并登錄阿里云賬號開通對象存儲OSS創建Bucket修改權限創建AccessKey全局存儲到你的計算機(可以跳過)查看官方文檔(可以跳過)SSM使用引入依賴在spring-mvc.xml中加入配置創建上傳工具類AliOssUtil響應工具類ResultJSON編寫controller編寫前端代碼使用Elme…

香港云主機常見使用問題匯總

本文主要為初次或正在接觸香港云主機的用戶介紹&#xff0c;對于香港云服務器的一些問題進行解答&#xff0c;幫助用戶更好的了解香港云主機&#xff0c;熟悉香港云主機。1.香港云主機是否需要備案?香港云主機無需進行像內地服務器那樣的 ICP 備案&#xff0c;可直接部署使用。…

JAVA同城打車小程序APP打車順風車滴滴車跑腿源碼微信小程序打車源碼

JAVA同城打車系統源碼&#xff1a;多端融合的智能出行生態解決方案一、市場需求與行業背景在共享經濟蓬勃發展和數字化轉型加速的背景下&#xff0c;中國同城出行市場正迎來快速增長期。2025年中國同城出行市場規模預計突破8000億元&#xff0c;年復合增長率超過25%。基于Sprin…

AI入坑: Trae 通過http調用.net 開發的 mcp server

1. 為什么要寫這個 為什么要寫這個內容&#xff0c;前幾天開始加入到ai大軍&#xff0c;通過一周的學習&#xff0c;看了國外網站、看了b站教程、看了抖音教程&#xff0c;居然發現都是開發在本地的mcp server。本地mcp沒問題&#xff0c;個人使用都ok&#xff0c;或者通過npx下…

記錄Pycharm所使用虛擬環境與終端無法對應

在anaconda安裝時&#xff0c;本文中的安裝位置在D盤&#xff0c; D:\soware\anaconda 理論環境位置 D:\soware\anaconda\envs 經檢查PATH配置均未發現錯誤&#xff0c;其次問題并不在于Pycharm的設置中解譯器與終端的設置經過多次查找未發現可用解決方案 在anaconda建立虛擬環…

國產數據庫之YashanDB:新花怒放

YashanDB&#xff08;崖山數據庫&#xff09;是由深圳計算科學研究院自主研發的一款新型關系數據庫管理系統。 YashanDB 在經典數據庫理論基礎上&#xff0c;融入了原創的有界計算、近似計算、并行可擴展和跨模融合計算理論&#xff0c;可以滿足金融、政企、能源等關鍵行業對高…

Java基礎 9.5

1.異常處理基本介紹異常處理就是當異常發生的時候 對異常處理的方式異常處理方式try-catch-finally程序員在代碼中捕獲發生的異常 自行處理throws將發生的異常拋出 交給調用者&#xff08;方法&#xff09;處理 最頂級的處理者是JVM示意圖2.try-catch方式處理異常說明Java提供t…

B.50.10.06-NoSQL數據庫與電商應用

NoSQL數據庫核心原理與電商應用實戰核心思想: NoSQL (Not Only SQL) 數據庫是為了解決傳統關系型數據庫在超大規模數據、高并發和靈活數據模型方面的不足而設計的。它們通過犧牲部分一致性&#xff08;通常是最終一致性&#xff09;和事務的嚴格性&#xff0c;來換取極高的性能…

把開發環境丟云上,我的電腦風扇再也沒轉過!

Hello&#xff0c;兄弟們&#xff0c;我來啦作為一個天天搬磚的程序員&#xff0c;每天最讓我心態爆炸的是啥&#xff1f;不是產品又改需求&#xff0c;也不是 Bug 藏得深&#xff0c;而是TMD——配&#xff01;環&#xff01;境&#xff01;新項目 git clone 下來&#xff0c;…