OpenCV中的邊緣檢測

邊緣檢測是圖像處理和計算機視覺中的關鍵技術之一,旨在識別圖像中像素強度發生顯著變化的區域,這些區域通常對應于物體的邊界或輪廓。邊緣檢測在機器視覺中具有重要的需求背景,主要體現在以下幾個方面:

  1. 圖像分割:邊緣檢測可以幫助將圖像分割成不同的區域,便于后續的圖像分析和處理。
  2. 物體識別:通過檢測物體的邊緣,可以提取物體的特征,為物體識別提供基礎。
  3. 圖像增強:邊緣檢測可以增強圖像中的重要特征,提高圖像的清晰度和質量。
  4. 三維重建:在三維重建中,邊緣檢測可以幫助確定物體的形狀和結構。

1.1.2. 應用場景

邊緣檢測在機器視覺中有著廣泛的應用場景,包括但不限于以下幾個方面:

  1. 工業檢測:用于檢測產品表面的缺陷,如裂紋、劃痕、凹陷等。
  2. 自動駕駛:用于檢測道路、交通標志、車輛和行人等物體的輪廓,輔助自動駕駛系統進行決策。
  3. 醫學圖像分析:用于識別醫學圖像中的器官、病變和組織邊界,輔助醫生進行診斷。
  4. 安防監控:用于檢測視頻中的異常行為或物體,提高監控系統的智能化水平。
  5. 機器人視覺:用于識別環境中的物體和障礙物,幫助機器人進行導航和避障。

1.2. OpenCV中的實現方法

OpenCV提供了多種邊緣檢測方法,常用的包括:

  1. Canny 邊緣檢測
  2. Sobel 算子
  3. Laplacian 算子

1.2.1. Canny 邊緣檢測

原理及內部流程: Canny 邊緣檢測是一種多階段的邊緣檢測算法,主要包括以下步驟:

  1. 噪聲抑制:使用高斯濾波器對圖像進行平滑處理,以減少噪聲的影響。
  2. 計算梯度:使用Sobel算子計算圖像的梯度幅值和方向。
  3. 非極大值抑制:沿著梯度方向,保留局部梯度最大的像素點,抑制其他像素點,有效的去除多余的邊緣效應,精確圖像的邊緣。
  4. 雙閾值檢測:設置高閾值和低閾值,高于高閾值的像素被認為是強邊緣,介于高閾值和低閾值之間的像素被認為是弱邊緣。
  5. 邊緣連接:通過強邊緣像素和與之相鄰的弱邊緣像素進行連接,形成完整的邊緣線。

參數確定及影響

  • 高斯濾波器的參數:通常根據圖像的噪聲水平選擇合適的高斯濾波器參數,如標準差和核大小。
  • 閾值:高閾值和低閾值的選擇對邊緣檢測結果有重要影響。高閾值用于檢測強邊緣,低閾值用于檢測弱邊緣。閾值的選擇需要根據圖像的特點和應用場景進行調整。

1.2.2. Sobel 算子

原理及內部流程: Sobel 算子是一種基于一階導數的邊緣檢測算子,通過計算圖像在水平和垂直方向的梯度來檢測邊緣。Sobel 算子使用兩個3×3的卷積核,分別計算水平和垂直方向的梯度,然后通過這兩個梯度來估計邊緣。

參數確定及影響

  • 卷積核大小:通常為3×3,但可以根據需要選擇其他大小。
  • 閾值:通過設置閾值來確定邊緣像素,閾值的選擇需要根據圖像的特點和應用場景進行調整。

1.2.3. Laplacian 算子

原理及內部流程: Laplacian 算子是一種基于二階導數的邊緣檢測算子,通過對圖像進行二階微分操作來檢測邊緣。Laplacian 算子可以提供邊緣的強度和方向信息。

參數確定及影響

  • 卷積核大小:通常為3×3,但可以根據需要選擇其他大小。
  • 閾值:通過設置閾值來確定邊緣像素,閾值的選擇需要根據圖像的特點和應用場景進行調整。、

1.2.4. 在openCV中如何使用

Sobel 算子與Laplacian 算子:這個在之前的高通濾波中已經說明過。

Canny 算子:

edges = cv2.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=False)
  1. image
    • 作用:輸入圖像,必須是單通道灰度圖像
    • 確認方法:如果輸入圖像是彩色圖像,需要先將其轉換為灰度圖像:Python復制
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  1. threshold1
    • 作用:低閾值,用于滯后閾值處理。
    • 作用機制:用于檢測弱邊緣。如果梯度幅值低于此閾值,則認為該像素不是邊緣。
    • 確認方法
      • 根據經驗,可以設置為 50 左右。
      • 通過實驗調整,觀察邊緣檢測的效果。通常需要結合高閾值一起調整。
      • 調的較低會保留更多的弱邊緣,對于邊緣較弱的,可以適當降低低閾值
  1. threshold2
    • 作用:高閾值,用于滯后閾值處理。
    • 作用機制:用于檢測強邊緣。如果梯度幅值高于此閾值,則認為該像素是強邊緣。
    • 確認方法
      • 根據經驗,可以設置為 150 左右。
      • 高閾值與低閾值的比值通常在 2:1 到 3:1 之間。例如,低閾值為 50,高閾值為 150 或 100。
      • 對于邊緣較復雜的圖像,可以適當增加高閾值。
  1. apertureSize
    • 作用:Sobel 算子的卷積核大小,影響梯度計算的精度。
    • 默認值:3
    • 確認方法
      • 如果需要更平滑的邊緣,可以嘗試更大的值(如 5 或 7)。
      • 值越大,計算復雜度越高,但邊緣檢測結果可能更平滑。
  1. L2gradient
    • 作用:決定梯度幅值的計算方式。
      • 如果為 True,則使用 L2 范數計算梯度幅值(M=Gx2+Gy2)。
      • 如果為 False,則使用 L1 范數計算梯度幅值(M=∣Gx∣+∣Gy∣)。
    • 默認值False
    • 確認方法
      • 如果對精度要求較高,可以設置為 True
      • 如果對性能要求較高,可以使用默認值 False
# Canny 邊緣檢測
edges = cv2.Canny(gray_image, 100, 200)

我們可以找一張圖片,先高斯濾波,然后Canny檢測,再邊緣檢測,感受一下各參數的改變的Canny邊緣檢測的影響:

新建文件:UiTest.py 在其中構建下列類

import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Sliderclass EdgeDetectionDemo:def __init__(self, image_path):self.image = cv2.imread(image_path)if self.image is None:raise ValueError(f"Failed to load image at path: {image_path}")self.image_gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)# 初始化默認參數self.blur_size = 5self.canny_low = 100self.canny_high = 200self.min_w = 100self.min_h = 100# 創建圖像窗口self.fig, (self.ax1, self.ax2, self.ax3) = plt.subplots(1, 3, figsize=(18, 6))self.fig.subplots_adjust(bottom=0.25)  # 調整底部空間以放置滑塊# 顯示原始圖像self.ax1.imshow(cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB))self.ax1.set_title("Original Image")self.ax1.axis('off')# 顯示邊緣檢測和輪廓檢測結果self.update_processing()# 創建滑塊self.create_sliders()plt.show()def update_processing(self):# 高斯模糊(確保核大小為奇數)blur_size = self.blur_size if self.blur_size % 2 == 1 else self.blur_size + 1blurred = cv2.GaussianBlur(self.image_gray, (blur_size, blur_size), 0)# Canny邊緣檢測edges = cv2.Canny(blurred, self.canny_low, self.canny_high)# 查找輪廓contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 繪制邊緣檢測結果self.ax2.clear()self.ax2.imshow(edges, cmap='gray')self.ax2.set_title(f"Canny Edges (Low={self.canny_low}, High={self.canny_high})")self.ax2.axis('off')# 繪制輪廓檢測結果contour_img = self.image.copy()valid_contours = []for cnt in contours:x, y, w, h = cv2.boundingRect(cnt)if w > self.min_w and h > self.min_h:cv2.rectangle(contour_img, (x, y), (x+w, y+h), (0, 255, 0), 2)valid_contours.append(cnt)self.ax3.clear()self.ax3.imshow(cv2.cvtColor(contour_img, cv2.COLOR_BGR2RGB))self.ax3.set_title(f"Contours (Min Size: {self.min_w}x{self.min_h})")self.ax3.axis('off')self.fig.canvas.draw_idle()  # 重新繪制圖像def create_sliders(self):# 創建滑塊ax_blur_size = self.fig.add_axes([0.25, 0.15, 0.65, 0.03])ax_canny_low = self.fig.add_axes([0.25, 0.12, 0.65, 0.03])ax_canny_high = self.fig.add_axes([0.25, 0.09, 0.65, 0.03])ax_min_w = self.fig.add_axes([0.25, 0.06, 0.65, 0.03])ax_min_h = self.fig.add_axes([0.25, 0.03, 0.65, 0.03])self.slider_blur_size = Slider(ax_blur_size, 'Blur Size', 1, 15, valinit=self.blur_size, valstep=2)self.slider_canny_low = Slider(ax_canny_low, 'Canny Low', 0, 300, valinit=self.canny_low, valstep=10)self.slider_canny_high = Slider(ax_canny_high, 'Canny High', 50, 500, valinit=self.canny_high, valstep=10)self.slider_min_w = Slider(ax_min_w, 'Min Width', 50, 500, valinit=self.min_w, valstep=10)self.slider_min_h = Slider(ax_min_h, 'Min Height', 50, 500, valinit=self.min_h, valstep=10)# 綁定滑塊事件self.slider_blur_size.on_changed(self.update_slider)self.slider_canny_low.on_changed(self.update_slider)self.slider_canny_high.on_changed(self.update_slider)self.slider_min_w.on_changed(self.update_slider)self.slider_min_h.on_changed(self.update_slider)def update_slider(self, val):self.blur_size = int(self.slider_blur_size.val)self.canny_low = int(self.slider_canny_low.val)self.canny_high = int(self.slider_canny_high.val)self.min_w = int(self.slider_min_w.val)self.min_h = int(self.slider_min_h.val)self.update_processing()

在另外一個文件(learnCV.py)中引用該類

from ImageManipulation import cvTest
from UiTest import EdgeDetectionDemo
def main():# cvTest.TestGrayImage()# cvTest.TestChannelSplite()demo = EdgeDetectionDemo("Cars.jpg")if(__name__=="__main__"):main()
  1. 濾波核大小對弱邊緣有影響,濾波核越大,弱邊緣越少

?

?

高閾值越高,弱邊緣越少

?


極限檢測:

上下限和濾波都是0:

?

先逐漸把低閾值拉滿:

?

再把高閾值拉滿:

?

弱邊緣是在持續減少的。

大家可以個人自己多嘗試嘗試

?

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

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

相關文章

【簡歷優化】性能調優 — 編程性能調優篇

😊你好,我是小航,一個正在變禿、變強的文藝傾年。 🔔本文講解【簡歷優化】性能調優 — 編程性能調優篇,期待與你一同探索、學習、進步,一起卷起來叭! 目錄 一、編程性能調優字符串String 發展優…

深入理解 MySQL 8 C++ 源碼:SELECT MOD(MONTH(NOW()), 2) 的函數執行過程

MySQL 作為最流行的關系型數據庫之一,其內部實現機制一直是開發者探索的熱點。本文將以一條簡單的 SQL 查詢 SELECT MOD(MONTH(NOW()), 2) 為例,深入分析 MySQL 8 源碼中內置函數 MOD、MONTH 和 NOW 的執行過程,揭示其底層實現邏輯。 一、SQL…

RNN中遠距離時間步梯度消失問題及解決辦法

RNN中遠距離時間步梯度消失問題及解決辦法 RNN 遠距離時間步梯度消失問題LSTM如何解決遠距離時間步梯度消失問題 RNN 遠距離時間步梯度消失問題 經典的RNN結構如下圖所示: 假設我們的時間序列只有三段, S 0 S_{0} S0? 為給定值,神經元沒有…

Tomcat理論(Ⅰ)

目錄 服務器流程圖一覽 一、JavaWeb前奏(了解) 1. C/S結構 2. B/S結構 3. 靜態網頁&動態網頁 4.常見的網頁 5.Web服務器 知名服務器: ?編輯 二、Tomcat安裝(熟練) 1.Tomcat概述 2.Tomcat的作用 3.Tomcat安裝 4.Tomcat測試 3.…

如何使用 DeepSeek R1 構建開源 ChatGPT Operator 替代方案

開源大型語言模型(LLMs)的興起使得創建 AI 驅動的工具比以往任何時候都更容易,這些工具可以與 OpenAI 的 ChatGPT Operator 等專有解決方案相媲美。在這些開源模型中,DeepSeek R1 以其強大的推理能力、自由的可訪問性和適應性而脫…

使用Docker Desktop部署GitLab

1. 環境準備 確保Windows 10/11系統支持虛擬化技術(需在BIOS中開啟Intel VT-x/AMD-V)內存建議≥8GB,存儲空間≥100GB 2. 安裝Docker Desktop 訪問Docker官網下載安裝包安裝時勾選"Use WSL 2 instead of Hyper-V"(推薦…

【復習】Java集合

集合概念 集合與數組 數組是固定長度;集合是動態長度的數據結構,需要動態增加或刪除元素 數組可以包含基本數據類型和對象;集合只能包含對象 數組可以直接訪問元素;集合需要通過迭代器訪問元素 線程安全的集合? …

vue3 文件類型傳Form Data數據格式給后端

在 Vue 3 中,如果你想將文件(例如上傳的 Excel 文件)以 FormData 格式發送到后端,可以通過以下步驟實現。這種方式通常用于處理文件上傳,因為它可以將文件和其他數據一起發送到服務器。 首先,創建一個 Vue…

使用 INFINI Console 配置集群監控 Webhook 通知指南

在集群管理中,監控關鍵指標如CPU、內存、磁盤、JVM等是至關重要的。對于Easysearch及ES生態系統,還需要關注集群本身的指標,例如搜索延遲、集群狀態、節點移除等。INFINI Console不僅提供了默認的監控指標,還支持用戶自定義監控項…

WPF的頁面設計和實用功能實現

目錄 一、TextBlock和TextBox 1. 在TextBlock中實時顯示當前時間 二、ListView 1.ListView顯示數據 三、ComboBox 1. ComboBox和CheckBox組合實現下拉框多選 四、Button 1. 設計Button按鈕的邊框為圓角,并對指針懸停時的顏色進行設置 一、TextBlock和TextBox…

二級公共基礎之數據結構與算法篇(八)排序技術

目錄 前言 一、交換類排序 1.冒泡排序法 1. 冒泡排序的思想 2. 冒泡排序的實現步驟 3. 示例 4. 冒泡排序的特點 2.快速排序 1. 快速排序的核心思想 2. 快速排序的實現步驟 3. 示例代碼(C語言) 4. 快速排序的特點 二、插入類排序 1. 簡單插入排序 1.簡單插入排…

記錄一次 ALG 的處理過程

前幾天朋友找我幫忙,說碰到很大困難了,實際上,不過如此 現象是這樣的: FreeSWITCH mod_unimrcp 工作不正常 FS 和 mrcp-server 兩邊同時抓包,看到的是: sip 流程正常 FS TCP 連接到 mccp-server 失敗&…

【Linux網絡編程】IP協議格式,解包步驟

目錄 解析步驟 1.版本字段(大小:4比特位) 2.首部長度(大小:4比特位)(單位:4字節) 🍜細節解釋: 3.服務類型(大小:8比特…

CSDN文章質量分查詢系統【贈python爬蟲、提分攻略】

CSDN文章質量分查詢系統 https://www.csdn.net/qc 點擊鏈接-----> CSDN文章質量分查詢系統 <------點擊鏈接 點擊鏈接-----> https://www.csdn.net/qc <------點擊鏈接 點擊鏈接-----> CSDN文章質量分查詢系統 <------點擊鏈接 點擊鏈…

HTML應用指南:利用GET請求獲取全國瀘溪河門店位置信息

隨著新零售業態的快速發展,門店位置信息的獲取變得越來越重要。作為新興烘焙品牌之一,瀘溪河自2013年在南京創立以來,一直堅持“健康美味,香飄世界”的企業使命,以匠人精神打造新中式糕點。為了更好地理解和利用這些數據,本篇文章將深入探討GET請求的實際應用,并展示如何…

如何在 React 中測試高階組件?

在 React 中測試高階組件可以采用多種策略&#xff0c;以下是常見的測試方法&#xff1a; 1. 測試高階組件返回的組件 高階組件本身是一個函數&#xff0c;它返回一個新的組件。因此&#xff0c;可以通過測試這個返回的組件來間接測試高階組件的功能。通常使用 Jest 作為測試…

R語言Stan貝葉斯空間條件自回歸CAR模型分析死亡率多維度數據可視化

全文鏈接&#xff1a;https://tecdat.cn/?p40424 在空間數據分析領域&#xff0c;準確的模型和有效的工具對于研究人員至關重要。本文為區域數據的貝葉斯模型分析提供了一套完整的工作流程&#xff0c;基于Stan這一先進的貝葉斯建模平臺構建&#xff0c;幫助客戶為空間分析帶來…

Casbin 權限管理介紹及在 Go 語言中的使用入門

引言 在現代軟件開發過程中&#xff0c;權限管理是一個至關重要的環節&#xff0c;它關系到系統的安全性和用戶體驗。Casbin 是一個強大的訪問控制庫&#xff0c;支持多種訪問控制模型&#xff0c;如 ACL&#xff08;訪問控制列表&#xff09;、RBAC&#xff08;基于角色的訪問…

快速入門——第三方組件element-ui

學習自嗶哩嗶哩上的“劉老師教編程”&#xff0c;具體學習的網站為&#xff1a;10.第三方組件element-ui_嗶哩嗶哩_bilibili&#xff0c;以下是看課后做的筆記&#xff0c;僅供參考。 第一節 組件間的傳值 組件可以有內部Data提供數據&#xff0c;也可由父組件通過prop方式傳…

【算法通關村 Day7】遞歸與二叉樹遍歷

遞歸與二叉樹遍歷青銅挑戰 理解遞歸 遞歸算法是指一個方法在其執行過程中調用自身。它通常用于將一個問題分解為更小的子問題&#xff0c;通過重復調用相同的方法來解決這些子問題&#xff0c;直到達到基準情況&#xff08;終止條件&#xff09;。 遞歸算法通常包括兩個主要…