OpenCV輪廓近似與Python命令行參數解析

在計算機視覺任務中,輪廓分析是目標檢測、形狀識別的核心步驟。而approxPolyDP函數作為輪廓簡化的關鍵工具,能有效減少輪廓頂點數量,降低計算復雜度;同時,argparse庫則能讓Python腳本更靈活、易用。本文將結合具體案例,詳細講解這兩個技術的原理與實戰應用。


一、輪廓近似:cv2.approxPolyDP的核心原理

1.1 為什么需要輪廓近似?

在圖像中,物體的輪廓通常由大量離散的像素點組成。直接處理這些點會導致計算量激增(例如繪制或匹配時)。cv2.approxPolyDP通過道格拉斯-普克算法(Douglas-Peucker Algorithm),在保留輪廓形狀的前提下,用更少的頂點近似原輪廓,顯著提升后續處理效率。

1.2 函數參數詳解

函數定義:
approx = cv2.approxPolyDP(curve, epsilon, closed)

參數含義
curve輸入輪廓(二維點集,通常是findContours輸出的輪廓之一)
epsilon近似精度(核心參數):允許的最大誤差(歐氏距離)。epsilon越小,近似結果越接近原輪廓;越大,頂點越少,輪廓越粗略。
closed布爾值,表示輪廓是否封閉(如矩形、圓形是封閉的,線段是不封閉的)

1.3 效果演示:不同epsilon的影響

以手機圖片的輪廓為例,我們觀察不同epsilon值對近似結果的影響:

import cv2
import matplotlib.pyplot as plt# 讀取圖像并預處理
phone = cv2.imread('phone.png')
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)
_, phone_thresh = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY)
contours = cv2.findContours(phone_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2]# 原始輪廓(第0個輪廓)
original_cnt = contours[0]
print(f"原始輪廓頂點數: {len(original_cnt)}")  # 輸出:原始輪廓頂點數: 123(示例值)# 不同epsilon值的近似效果
epsilons = [0.001, 0.005, 0.01] * cv2.arcLength(original_cnt, closed=True)
approx_contours = []
for eps in epsilons:approx = cv2.approxPolyDP(original_cnt, eps, closed=True)approx_contours.append(approx)print(f"epsilon={eps:.2f}時,近似輪廓頂點數: {len(approx)}")  # 輸出頂點數遞減# 繪制對比圖
plt.figure(figsize=(15, 10))
plt.subplot(2, 2, 1), plt.imshow(cv2.cvtColor(phone, cv2.COLOR_BGR2RGB)), plt.title('原圖')
plt.subplot(2, 2, 2), plt.imshow(cv2.cvtColor(phone, cv2.COLOR_BGR2RGB)), plt.title(f'原始輪廓({len(original_cnt)}點)')
for i, (eps, approx) in enumerate(zip(epsilons, approx_contours)):img = phone.copy()cv2.drawContours(img, [approx], -1, (0, 255, 0), 2)plt.subplot(2, 2, i+3), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title(f'epsilon={eps:.4f}{len(approx)}點)')
plt.show()
  • 關鍵結論
    epsilon=0.001×輪廓周長時,近似輪廓幾乎與原輪廓重合(頂點數接近原輪廓);
    epsilon=0.01×輪廓周長時,輪廓被簡化為幾個關鍵頂點(如矩形的4個頂點),但形狀仍可辨識。

二、命令行參數解析:argparse讓腳本工程化

2.1 為什么需要argparse

在實際項目中,直接硬編碼參數(如圖像路徑、閾值、epsilon值)會導致腳本復用性差。argparse是Python標準庫中用于解析命令行參數的工具,允許用戶通過命令行動態指定參數,大幅提升腳本的靈活性和可維護性。

2.2 核心功能與用法

argparse的核心流程:

  1. 創建ArgumentParser對象(解析器);
  2. 使用add_argument()添加參數(位置參數、可選參數);
  3. 調用parse_args()解析命令行輸入,返回參數對象。

2.3 示例:為輪廓近似腳本添加參數解析

以下代碼演示如何用argparse為輪廓近似腳本添加參數,支持用戶自定義輸入路徑、閾值、epsilon比例等:

import cv2
import argparsedef main():# 1. 創建參數解析器parser = argparse.ArgumentParser(description='輪廓近似演示:使用approxPolyDP簡化輪廓')# 2. 添加參數(位置參數+可選參數)parser.add_argument('--input', type=str, required=True, help='輸入圖像路徑(必填)')parser.add_argument('--thresh', type=int, default=120, help='二值化閾值(默認120)')parser.add_argument('--epsilon-scale', type=float, default=0.005, help='epsilon比例(相對于輪廓周長,默認0.005)')parser.add_argument('--output', type=str, default='output.jpg', help='輸出圖像路徑(默認output.jpg)')# 3. 解析參數args = parser.parse_args()# 4. 執行圖像處理流程# 讀取圖像img = cv2.imread(args.input)if img is None:raise ValueError(f"無法讀取圖像:{args.input}")# 灰度轉換+二值化gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)_, thresh = cv2.threshold(gray, args.thresh, 255, cv2.THRESH_BINARY)# 輪廓檢測contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2]if not contours:raise RuntimeError("未檢測到任何輪廓")# 選擇最大輪廓(面積最大)main_cnt = max(contours, key=cv2.contourArea)# 輪廓近似epsilon = args.epsilon_scale * cv2.arcLength(main_cnt, closed=True)approx_cnt = cv2.approxPolyDP(main_cnt, epsilon, closed=True)# 繪制結果result_img = img.copy()cv2.drawContours(result_img, [main_cnt], -1, (0, 0, 255), 2)  # 原輪廓(紅色)cv2.drawContours(result_img, [approx_cnt], -1, (0, 255, 0), 2)  # 近似輪廓(綠色)# 保存結果cv2.imwrite(args.output, result_img)print(f"處理完成,結果保存至:{args.output}")if __name__ == '__main__':main()

2.4 使用說明

運行腳本時,通過命令行傳遞參數:

python contour_approx.py --input phone.png --thresh 120 --epsilon-scale 0.005 --output approx_result.jpg
  • 參數說明

    • --input:輸入圖像路徑(必填,否則報錯);
    • --thresh:二值化閾值(可選,默認120);
    • --epsilon-scaleepsilon相對于輪廓周長的比例(可選,默認0.005);
    • --output:輸出圖像路徑(可選,默認output.jpg)。
  • 優勢:用戶無需修改代碼,即可通過命令行調整參數,適應不同場景(如處理不同圖像、優化近似精度)。


三、綜合實戰:結合輪廓近似與參數解析的目標檢測

假設我們需要檢測圖像中的矩形物體(如書本、手機),并結合參數解析讓腳本通用化。以下是完整實現:

3.1 需求分析

  • 輸入:任意圖像路徑;
  • 處理:灰度轉換→二值化→輪廓檢測→輪廓近似→篩選矩形(4個頂點);
  • 輸出:標注原輪廓(紅色)和近似矩形(綠色)的結果圖像。

3.2 代碼實現

import cv2
import argparsedef detect_rectangles(img_path, thresh=120, epsilon_scale=0.005, output_path='rectangles.jpg'):# 讀取圖像img = cv2.imread(img_path)if img is None:raise ValueError(f"無法讀取圖像:{img_path}")# 預處理gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)_, thresh_img = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY_INV)  # 反轉二值化(假設目標為深色)# 輪廓檢測(RETR_EXTERNAL僅檢測最外層輪廓)contours = cv2.findContours(thresh_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]# 篩選并近似輪廓rectangles = []for cnt in contours:# 忽略小面積輪廓(面積閾值可根據需求調整)if cv2.contourArea(cnt) < 1000:continue# 輪廓近似epsilon = epsilon_scale * cv2.arcLength(cnt, closed=True)approx = cv2.approxPolyDP(cnt, epsilon, closed=True)# 篩選4頂點的近似輪廓(矩形)if len(approx) == 4:rectangles.append(approx)# 繪制結果result_img = img.copy()for rect in rectangles:cv2.drawContours(result_img, [rect], -1, (0, 255, 0), 3)  # 綠色標注矩形# 保存結果cv2.imwrite(output_path, result_img)print(f"檢測完成,共找到{len(rectangles)}個矩形,結果保存至:{output_path}")if __name__ == '__main__':# 參數解析parser = argparse.ArgumentParser(description='矩形檢測:基于輪廓近似的物體識別')parser.add_argument('--input', type=str, required=True, help='輸入圖像路徑')parser.add_argument('--thresh', type=int, default=120, help='二值化閾值(默認120)')parser.add_argument('--epsilon-scale', type=float, default=0.005, help='epsilon比例(默認0.005)')parser.add_argument('--output', type=str, default='rectangles.jpg', help='輸出圖像路徑(默認rectangles.jpg)')args = parser.parse_args()# 執行檢測detect_rectangles(img_path=args.input,thresh=args.thresh,epsilon_scale=args.epsilon_scale,output_path=args.output)

3.3 效果驗證

假設輸入圖像是一張包含書本和手機的桌面圖,運行腳本:

python detect_rectangles.py --input desk.jpg --thresh 150 --epsilon-scale 0.003 --output result.jpg

輸出圖像中,書本和手機的矩形輪廓會被綠色線條標注,原輪廓(可選)可用紅色線條疊加顯示(修改代碼添加原輪廓繪制)。


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

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

相關文章

基于Springboot在線音樂推薦平臺

目錄 一、項目介紹 二、功能介紹 三、核心代碼 四、效果圖 源碼獲取 前言 在經濟繁榮的浪潮過去后&#xff0c;社會的焦點逐漸從物質追求轉向了文化和生活品質的提升[1]。文化生活的繁榮成為人們關注的焦點之一&#xff0c;而音樂&#xff0c;作為文化的一部分&#xff0…

LeetCode算法日記 - Day 26: 歸并排序、交易逆序對的總數

目錄 1. 歸并排序 1.1 題目解析 1.2 解法 1.3 代碼實現 2. 交易逆序對的總數 2.1 題目解析 2.2 解法 2.3 代碼實現 1. 歸并排序 912. 排序數組 - 力扣&#xff08;LeetCode&#xff09; 給你一個整數數組 nums&#xff0c;請你將該數組升序排列。 你必須在 不使用任…

C++(Qt)軟件調試---vcpkg安裝crashpad(34)

C(Qt)軟件調試—vcpkg安裝crashpad&#xff08;34&#xff09; 文章目錄C(Qt)軟件調試---vcpkg安裝crashpad&#xff08;34&#xff09;[toc]1 概述&#x1f41c;2 環境配置3 qt使用crashpad庫捕獲異常4 cmake中添加crashpad5 相關地址&#x1f410;更多精彩內容&#x1f449;內…

Kafka 副本同步異常與 ISR 收縮故障排查實錄

背景 某高流量 Kafka 集群&#xff08;原 10G 網卡&#xff09;在切中心時頻繁觸發帶寬報警&#xff0c;擴容至 25G 網卡后出現副本同步異常&#xff1a; 操作流程&#xff1a;停機→升級網卡→重啟→觸發分區同步→切換首選 Leader現象&#xff1a; 寫入流量上升后&#xff0c…

頂點 (VS)vs 片段(FS):OpenGL紋理滾動著色器的性能博弈與設計哲學

一個微妙的選擇&#xff0c;影響整個應用性能表現在實時圖形渲染中&#xff0c;實現紋理滾動效果是一種常見需求。但當我們在頂點著色器和片段著色器之間做出不同實現選擇時&#xff0c;會對性能產生顯著影響。今天&#xff0c;我們將深入探討這兩種實現的差異&#xff0c;幫助…

基于博客系統的自動化測試項目

目錄 一、引言 二、項目背景 三、項目功能 1&#xff09;初始登錄界面 2&#xff09;博客首頁 3&#xff09;博客詳情頁 4&#xff09;博客編輯頁 四、測試工具 1&#xff09;基礎操作系統環境 2&#xff09;瀏覽器環境 3&#xff09;開發與測試工具環境 4&#xf…

R 語言 eulerr 包繪制韋恩圖:比例精準

在數據可視化中,韋恩圖是展示多組數據交集關系的常用工具,尤其在生物信息(如基因差異表達分析)、統計分析等領域高頻使用。但傳統繪圖工具常面臨橢圓比例失衡、數值顯示混亂、樣式調整繁瑣等問題,而 R 語言的eulerr包恰好能解決這些痛點 —— 它支持按數據比例自動適配圖形…

CRYPT32!CryptMsgUpdate函數分析和asn.1 editor nt5inf.cat 的總覽信息

0000: 30 83 09 69 2f ; SEQUENCE (9692f Bytes) 0005: 06 09 ; OBJECT_IDENTIFIER (9 Bytes) 0007: | 2a 86 48 86 f7 0d 01 07 02| ; "PKCS 7 已簽名 (1.2.840.113549.1.7.2)" 0010: …

04數據庫約束實戰:從入門到精通

感謝黑馬程序員提供的免費課程約束概念&#xff1a;約束是作用于表中字段上的規則&#xff0c;用于限制存儲在表中的數據。目的&#xff1a;保證數據庫中數據的正確、有效性和完整性。常見的幾種約束&#xff1a;注意&#xff1a;約束是作用于表中字段上的&#xff0c;可以在創…

WPF+IOC學習記錄

最近在學WPF&#xff0c;上一篇文章記錄了WPF的MVVM自己實現和用框架的區別&#xff08;WPFMVVM入門學習&#xff09;&#xff0c;接下這篇文章記錄一下在WPF中使用IOC&#xff0c;這里演示用的是微軟官方的DependencyInjection&#xff0c;也可以用其他的第三方框架。 項目源…

從零開始學習單片機16

STM32單片機STM32和51單片機的區別51單片機的外設資源少&#xff0c;寄存器少&#xff0c;運行速度慢&#xff0c;價格便宜&#xff0c;容易上手STM32單片機的外設資源更多&#xff0c;寄存器多&#xff0c;運行速度相對快&#xff0c;價格相對貴&#xff0c;上手相對較難STM32…

[特殊字符]論一個 bug 如何經過千難萬險占領線上

謹以此文獻給每一個曾與 Bug 搏斗、最終卻目睹它成功上線的你 本文旨在揭露 Bug 的狡猾&#xff0c;絕非鼓勵以下行為。若你照做&#xff0c;后果自負&#x1f436;每一個在線上逍遙法外的 Bug&#xff0c;都不是偶然。它是一場精心策劃的奇跡&#xff0c;是開發、聯調、測試、…

Day12-python文件操作(二)

目錄前言一、Excel文檔操作1.1、xlrd和xlwt庫1.2、openpyxl庫1.3、pandas庫總結前言 今天繼續學習文件操作相關內容&#xff0c;為后續辦公自動化打基礎。 一、Excel文檔操作 1.1、xlrd和xlwt庫 如果要兼容 Excel 2007 以前的版本&#xff0c;也就是xls格式的 Excel 文件&am…

CollageIt:簡單易用的照片拼貼工具

在數字圖像處理領域&#xff0c;制作照片拼貼是一種常見的創意表達方式。CollageIt作為一款體積小巧、簡單易用的照片拼貼工具&#xff0c;能夠幫助用戶輕松將多張圖片拼合成一張精美的拼貼畫。它不僅操作簡單&#xff0c;還支持多種圖片格式&#xff0c;確保用戶可以快速制作出…

Java全棧工程師的實戰面試:從基礎到微服務的全面解析

Java全棧工程師的實戰面試&#xff1a;從基礎到微服務的全面解析 一、開場介紹 面試官&#xff1a;你好&#xff0c;歡迎來到我們公司。我是今天的面試官&#xff0c;負責技術部分的評估。請先簡單介紹一下你自己。 應聘者&#xff1a;您好&#xff0c;我叫李明&#xff0c;25歲…

驅動開發系列68 - GLSL編譯器實現 - 算數指令折疊及訪存優化

一 : 指令合并概述 指令折疊的意思,原本一個語句會產生多條指令,通過折疊,可以刪除一些中間指令,減少指令數量,并且能夠減少寄存器占用。提高執行效率。 舉一個例子: MUL A, B, 4 ; A = B * 4MAD D, A, 2, F ; D = A * 2 + F MAD G, A, 3, I ; G …

深入解析Qt節點編輯器框架:高級特性與性能優化(四)

文章目錄一、高級交互特性&#xff1a;超越基礎操作的用戶體驗提升1. 節點組管理&#xff1a;折疊與嵌套的層級組織2. 智能連接線路由&#xff1a;避免交叉與視覺混亂3. 批量操作與快捷鍵&#xff1a;提升操作效率二、性能優化&#xff1a;應對大規模節點場景的核心策略1. 圖形…

Python 入門操作指南

引言 Python 是一種簡單易學卻功能強大的編程語言,廣泛應用于數據分析、人工智能、Web 開發等領域。對于初學者而言,掌握 Python 的入門操作是邁向編程世界的第一步。本文將以總分總的結構,系統介紹 Python 的安裝方法、推薦的開發工具、第一個 Python 程序示例,以及包管理…

ZooKeeper 安裝配置

前言 有時會需要安裝開源的大數據集群進行測評或者驗證問題&#xff0c;已經裝過很多遍了&#xff0c;所以想系統的總結整理一下各個組件的安裝部署&#xff0c;包括 Zookeeper、Hadoop、Hive、Spark 等。 版本 Zookeeper 3.5.6 3.8.4 3.9.3 初始化 包括主機名修改、SSH互…

考研數據結構Part3——二叉樹知識點總結

一、前言 二叉樹是一種特殊的樹形結構&#xff0c;每個節點最多有兩個子節點&#xff0c;分別稱為左子樹和右子樹。其特點是子樹有嚴格的左右之分&#xff0c;順序不可顛倒。從歷年真題來看&#xff0c;二叉樹的鏈式存儲實現、遍歷算法、屬性統計是高頻考點&#xff0c;常以選擇…