實踐《數字圖像處理》之Canny邊緣檢測、霍夫變換與主動二值化處理在短線段清除應用中的實踐

? ? ? 在最近的圖像處理項目中,其中一個環節:圖片中大量短線(不是噪聲),需要在下一步處理前進行清除。在確定具體實現時,碰到了Canny邊緣檢測、霍夫變換與主動二值化處理的辯證使用,相關邏輯從圖片灰度化以后開始,到短線的刪除。

一、處理的主要流程如下:

? ? ? 第一步:轉換為灰度圖;

? ? ? 第二步:Canny的邊緣檢測;? ? ?

? ? ? 第三步:霍夫變換直線檢測;

? ? ? 第四步:刪除短線;

? ? ?以下是核心代碼(Python):

    # 1、轉換為灰度圖gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)print(f"二值化: {np.unique(gray)}")# 2、優化的邊緣檢測參數,適合檢測細線條edges = cv2.Canny(gray, 20, 60, apertureSize=3, L2gradient=True)# 3、使用霍夫變換檢測直線(優化參數適合短線檢測)lines = cv2.HoughLinesP(edges, rho=1, theta=np.pi/180, threshold=10, minLineLength=min_line_length,maxLineGap=2  # 減小間隙閾值,適合短線)# 4、要移除的短線if lines is not None:# 創建一個掩碼用于繪制要移除的短線mask = np.zeros_like(edges)cv2.imwrite('mask1.jpg', mask)print(f"檢測到 {len(lines)} 條直線")# 遍歷所有檢測到的線for line in lines:x1, y1, x2, y2 = line[0]# 計算線的長度line_length = np.sqrt((x2 - x1)**2 + (y2 - y1)** 2)print(f"要移除的短線長度:{line_length}")       print(f"要移除的短線端點:{x2},{y2},{x1},{y1}")       # 如果線的長度小于閾值(此處為100),則認為是短線,需要移除if line_length < 100:# 在掩碼上繪制短線(白色)cv2.line(mask, (x1, y1), (x2, y2), 255, 3)# 找到掩碼中非零的區域(即短線區域)cv2.imwrite('mask.jpg', mask)non_zero = cv2.findNonZero(mask)if non_zero is not None:# 二值化圖像處理:直接將短線區域像素設為255(白色背景)# 注意:如果你的背景是黑色(0),則改為 result[mask != 0] = 0result[mask != 0] = 255

二、為什么霍夫變換前要進行Canny邊緣檢測

? ? ? ?先說結論:Canny?的核心作用是 “過濾無效信息,只給霍夫變換提供真正的邊緣”。圖片直接進行霍夫變換,會 “過度檢測”,把灰度圖中所有非純白的區域都誤判為直線,最終導致?mask?產生大量線條。

? ? ? ?理解其中緣由,需從霍夫變換的輸入圖像特性?和?Canny?邊緣檢測的作用?兩方面分析:

1、霍夫變換(HoughLinesP)的核心邏輯

? ? ? ?HoughLinesP?是用來檢測圖像中的直線,它的輸入是 “邊緣圖像”(即只有邊緣像素為非零值的圖像)。

  • 如果輸入是原始灰度圖(沒經過?Canny):灰度圖中所有非純白(255)的像素都會被視為 “潛在邊緣”;
  • 如果輸入是 **Canny?后的邊緣圖 **:只有真正的邊緣像素會被保留,背景是純黑(0)。
2、Canny?邊緣檢測的作用

? ? ? ?Canny?是 “精準邊緣提取器”,它會:

  1. 過濾噪聲,只保留強邊緣
  2. 把邊緣細化為單像素寬度;
  3. 最終輸出 “只有邊緣是白色(255),背景是黑色(0)” 的圖像。
3、沒有Canny邊緣檢測,霍夫變換 “亂檢測” 的原因

? ? ? ?當你直接把原始灰度圖傳給?HoughLinesP?時:

  • 灰度圖中所有不是純白(255)的區域,都會被?HoughLinesP?視為 “可能的直線片段”;
  • 原始圖像中即使是平滑的灰度漸變、輕微的噪聲,都會被誤判為 “直線”,導致檢測出大量虛假直線。
4、直觀對比:有?Canny?vs 無?Canny
步驟有?Canny?的情況無?Canny?的情況
輸入圖像只有 “強邊緣” 的二值圖(背景全黑)原始灰度圖(包含大量非純白的灰度像素)
HoughLinesP?檢測只檢測 “強邊緣” 組成的直線,數量少且精準把所有 “非純白區域” 都當邊緣,檢測出大量虛假直線
mask?標記結果只標記真正需要刪除的短線,數量少標記大量虛假直線,mask?充滿線條

? ? ? ?因此,通常Canny邊緣檢測,是霍夫變換精準檢測直線的前提。

三、為什么Canny邊緣檢測前不要進行主動二值化處理

? ? ? ?Canny?邊緣檢測的輸出是二值化圖像,在?Canny?前主動做二值化,對?Canny?提取邊緣的核心效果來說,確實沒有多少價值,甚至可能產生反作用。可以從?Canny?的工作邏輯和二值化的局限性兩方面來理解這個問題:

1、先明確:Canny?自身會 “隱性處理” 二值化邏輯

? ? ? ?Canny?邊緣檢測的核心是 “找灰度值突變的區域”(即邊緣),它的流程里有兩個關鍵步驟,本質上已經包含了 “類似二值化” 的篩選邏輯:

  1. 非極大值抑制:把梯度方向上的 “非邊緣像素”(灰度變化不顯著的)直接壓成 0(黑色);
  2. 雙閾值檢測:用高、低兩個閾值過濾 —— 只有梯度值超過 “高閾值” 的像素才被判定為 “強邊緣”(設為 255),低于 “低閾值” 的直接舍棄(設為 0),介于兩者之間的需依賴 “強邊緣連接” 才保留(最終也是 255 或 0)。

? ? ? ?換句話說:Canny?會自己根據 “灰度變化強度”,把圖像最終輸出為?“邊緣 = 255、背景 = 0” 的二值化邊緣圖,完全不需要依賴輸入圖像是否提前二值化。

2、更關鍵:提前二值化可能 “破壞?Canny?的邊緣提取基礎”

? ? ? ?Canny?提取邊緣的核心依賴是?“圖像的灰度梯度”(即相鄰像素的灰度差異),而提前二值化會直接破壞這個梯度:

  • 二值化會把圖像強行切成 “純黑(0)” 和 “純白(255)”,原本連續的灰度漸變(比如從 100→200 的平滑過渡)會變成 “0 和 255 的跳變”;
  • 這種 “跳變” 會讓?Canny?誤判出大量 “虛假邊緣”(比如二值化后色塊的邊界,未必是你要的目標邊緣),還可能讓原本連續的目標邊緣 “斷裂”(比如細線條二值化后部分像素被壓成 0,導致?Canny?無法連接完整邊緣)。

? ? ? ?舉個直觀例子:如果你的原始圖像是 “灰色背景上的黑色細線條”,提前二值化后,線條會變成純黑(0)、背景變成純白(255)—— 此時?Canny?確實能找到線條邊緣,但如果線條本身有輕微灰度不均(比如部分像素是 10 而非 0),二值化會直接把這些像素 “一刀切” 成 0 或 255,反而可能讓?Canny?提取的邊緣變 “粗糙” 或 “不連續”;而如果直接給?Canny?輸入灰度圖,它能根據灰度梯度更精準地定位線條邊緣,甚至修復輕微的灰度不均。

3、結論:Canny?前的二值化 “可省且建議省”

? ? ? ?對?Canny?來說,輸入 “原始灰度圖” 比 “提前二值化的圖” 更友好

  • 原始灰度圖保留了完整的 “灰度梯度信息”,Canny?能更精準地判斷 “哪些是真邊緣、哪些是噪聲”;
  • 提前二值化不僅幫不上?Canny?的忙,還可能破壞梯度、引入虛假邊緣,反而增加后續霍夫變換 “誤檢直線” 的概率。

? ? ? ? 這樣調整后,Canny?提取的邊緣會更精準,霍夫變換誤檢的虛假直線會減少,通過mask標記查看,會發現其中檢測出的短線主要是項目關注的短線。

四、結論

? ? ? ?“主動二值化” 只是簡單的 “閾值分割”,無法替代?Canny?對邊緣的 “精細化、連續化、去噪化”?處理。霍夫變換需要 “精準、連續的單像素邊緣” 才能高效檢測直線,通常Canny是必要的(它能進一步優化邊緣質量)。

? ? ? ?實踐驗證,可分別對 “二值化圖像” 和 “Canny?邊緣圖” 做霍夫變換,對比檢測出的直線數量和精準度 —— 會發現?Canny?輸出的邊緣圖,能讓霍夫變換檢測出更精準、更少的虛假直線。

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

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

相關文章

vue3與ue5通信-工具類

工具 ue5-simple.js /*** UE5 通信工具* 兩個核心方法&#xff1a;發送消息和接收消息*/// 確保全局對象存在 if (typeof window ! undefined) {window.ue window.ue || {};window.ue.interface window.ue.interface || {}; }/*** 生成 UUID*/ function generateUUID() {retu…

在kotlin中如何使用像java中的static

在 Kotlin 中&#xff0c;沒有直接的 static 關鍵字&#xff0c;但有幾種等效的方式來實現 Java 中靜態成員的功能&#xff1a; 1. 伴生對象 (Companion Object) - 最常用 class MyClass {companion object {// 靜態常量const val STATIC_CONSTANT "constant value"…

如何在 Spring Boot 中指定不同的配置文件?

介紹 Spring Boot 提供了多種方式來管理和加載配置文件&#xff0c;特別是在多環境配置下&#xff0c;比如開發、測試和生產環境。通過指定不同的配置文件&#xff0c;可以靈活地調整應用程序的行為&#xff0c;以適應不同的需求。本文將介紹在 Spring Boot 中如何指定使用不同…

在centOS源碼編譯方式安裝MySQL5.7

一、前言 在生產環境中部署數據庫時&#xff0c;很多人會選擇直接使用 yum/apt 包管理器 安裝 MySQL&#xff0c;這樣簡單快速&#xff0c;但缺點是版本受限&#xff0c;靈活性不足。對于需要指定版本、啟用特定編譯參數或優化的場景&#xff0c;源碼編譯安裝 MySQL 就顯得非常…

探討Hyperband 等主要機器學習調優方法的機制和權衡

本篇文章Master Hyperband — An Efficient Hyperparameter Tuning Method in Machine Learning深入探討了Hyperband這一高效的超參數調優方法。文章的技術亮點在于其結合了多臂老虎機策略和逐次減半算法&#xff0c;能夠在大搜索空間中快速剔除表現不佳的配置&#xff0c;從而…

Mysql:InnoDB 關鍵特性

目錄 一、插入緩沖&#xff08;Change Buffer&#xff09;→ 快遞驛站的 “臨時存放區” 二、兩次寫&#xff08;Double Write&#xff09;→ 重要文件的 “備份存檔” 三、自適應哈希索引&#xff08;AHI&#xff09;→ 圖書館的 “熱門書快捷查找區” 四、異步 IO&#x…

STM32-----SPI

SPI簡介SCK:和I2C中SCL的時鐘線一個作用&#xff0c;都是在高電平拿出數據&#xff0c;在低電平寫數據MOSI:主機輸出從機輸入MISO:主機輸入從機輸出&#xff0c;只有當對應從機的SS為低電平&#xff0c;從機的MISO引腳才能設置推挽輸出&#xff0c;當從機SS為高電平時&#xff…

華為考試:HCIE數通考試難度分析

隨著信息技術的飛速發展&#xff0c;網絡技術已成為支撐各行各業運轉的重要基礎&#xff0c;市場對高水平網絡技術人才的需求持續增長。HCIE作為華為認證體系中的最高級別認證&#xff0c;代表了網絡技術領域的專業頂尖水平。本文將對HCIE數通認證的考試內容、難度及備考策略進…

一些常用的激活函數及繪圖

深度網絡的一些常用激活函數&#xff0c;并通過matplot繪制出來&#xff1a; import matplotlib.pyplot as plt import numpy as npdef relu(x):return np.maximum(0, x)def leaky_relu(x, alpha0.01):return np.where(x > 0, x, alpha * x)def gelu(x):return 0.5 * x * (1…

AE蘋果手機iPhone 17展示動畫片頭模板 App Promo Phone 17 Pro

專為 App 發布會、電商促銷、新品宣傳 打造的 iPhone 17 Pro 動畫展示 AE 模板。 4K 超清分辨率 26 張可替換照片位&#xff0c;無需第三方插件&#xff0c;拖拽即可輸出專業級手機宣傳片。 核心亮點 4K 超清&#xff1a;38402160 分辨率&#xff0c;大屏投放與社媒高清壓縮無…

基于Python的云原生TodoList Demo 項目,驗證云原生核心特性

以下是一個基于 Python 的云原生 TodoList Demo 項目&#xff0c;涵蓋 容器化、Kubernetes 編排、CI/CD、可觀測性、彈性擴縮容 等核心云原生特性&#xff0c;代碼簡潔且附詳細操作指南&#xff0c;適合入門學習。項目概覽 目標&#xff1a;實現一個支持增刪改查&#xff08;CR…

go 日志的分裝和使用 Zap + lumberjack

自帶的log無法滿足 按大小輪轉 &#xff0c;按天數清理舊日志 &#xff0c;自動壓縮 &#xff0c;限制備份數量 &#xff0c;防止磁盤寫滿 &#xff0c;生產環境推薦 等 使用 Zap lumberjack package mainimport ("go.uber.org/zap""go.uber.org/zap/zapcore&q…

【.Net技術棧梳理】01-核心框架與運行時(CLR)

文章目錄1 .NET Runtime&#xff08;CLR-公共語言運行時&#xff09;1.1 中間語言 IL1.1.1 從源代碼到通用中間語言&#xff08;IL&#xff09;1.1.2 運行時加載&#xff1a;CLR登場1.1.3 核心步驟&#xff1a;即時編譯 (JIT Compilation)1.1.4 執行與內存管理&#xff08;GC&a…

Claude Code 平替:OpenAI發布 Codex CLI ,GPT-5 國內直接使用

openai推出的命令行編程工具codex已經可以使用最新 GPT-5 模型&#xff0c;擁有可媲美 Claude Code 的 AI 編碼能力。本文將指導你在 Windows 系統上部署原生的 Codex CLI 程序&#xff0c;并接入超低價中轉 API&#xff0c;讓你在國內直接用上超高性價比的 OpenAI Codex CLI 應…

在VS2022的WPF仿真,為什么在XAML實時預覽點擊 ce.xaml頁面控件,卻不會自動跳轉到具體代碼,這樣不方便我修改代碼,

在VS2022的WPF仿真&#xff0c;為什么在XAML實時預覽點擊 WpfApp1\FunctionalModule\08Replace\Replace.xaml頁面控件&#xff0c;卻不會自動跳轉到具體代碼&#xff0c;這樣不方便我修改代碼&#xff0c;

Git Bash 別名

有些常用的指令參數非常多&#xff0c;每次都要輸入好多參數&#xff0c;我們可以使用別名。Linux 系統中很多 shell&#xff0c;包括 bash&#xff0c;sh&#xff0c;zsh&#xff0c;dash 和 korn 等&#xff0c;不管哪種 shell 都會有一個 .bashrc 的隱藏文件&#xff0c;它就…

Centos7部署ceph存儲

一、準備5臺centos7主機 node節點雙網卡&#xff08;1個內部檢測&#xff0c;1個外部使用&#xff09;node節點都添加新網卡關閉防火墻和上下文都需要添加hosts文件都需要cat > /etc/hosts << EOF > 127.0.0.1 localhost localhost.localdomain localhost4 loca…

2025.9.10總結

今日感悟&#xff1a;刷到00后下班去菜市場撿菜的熱點視頻&#xff0c;確實挺有意思&#xff0c;不得不說&#xff0c;又省錢又好玩。雖然每天晚上能免費領個25塊錢的水果回去&#xff0c;但確實沒有什么新鮮感了。別人下班還能撿撿菜放松下&#xff0c;我下班&#xff0c;除了…

【數據結構與算符Trip第2站】稀疏數組

稀疏sparsearray數組 什么是稀疏數組&#xff1f; 稀疏數組是一種特殊的數據結構&#xff0c;用于高效存儲和表示大部分元素為零&#xff08;或默認值&#xff09;的數組。它通過只存儲非零元素的位置和值來節省內存空間。是一種壓縮數組。 實現原理 在Go語言中&#xff0c;稀疏…

Sub-GHz無線收發單片機,低功耗物聯網通信的硬件“基石”

隨著物聯網應用持續向規模化部署、廣域化覆蓋與高效化協同邁進&#xff0c; 作為IoT終端設備實現無線交互的核心通信單元之一——Sub-GHz無線收發單片機&#xff08;Sub-GHz射頻收發芯片與單片機高度集成&#xff09;已成為系統設計中進一步簡化外圍元件數量、縮小硬件體積、降…