OpenCV--圖像邊緣檢測

在計算機視覺和圖像處理領域,邊緣檢測是極為關鍵的技術。邊緣作為圖像中像素值發生急劇變化的區域,承載了圖像的重要結構信息,在物體識別、圖像分割、目標跟蹤等眾多應用場景中發揮著核心作用。OpenCV 作為強大的計算機視覺庫,提供了豐富且高效的邊緣檢測算法。本文將深入探討常見邊緣檢測算法的原理,并結合 OpenCV 的代碼示例,助力讀者深入理解與運用邊緣檢測技術。

一、邊緣檢測簡介

邊緣檢測旨在識別和提取圖像中物體的邊界,通過檢測圖像中像素值的變化,標記出圖像中明顯的邊緣部分。不同類型的圖像邊緣可能對應不同的物體邊界、紋理變化或光照變化。在實際應用中,良好的邊緣檢測結果能大幅簡化后續圖像處理任務,提高算法的效率和準確性。

二、Sobel 算子

1. 原理

Sobel 算子是一種常用的邊緣檢測算法,它基于圖像中像素的梯度來檢測邊緣。該算法分別計算圖像在水平方向(X 方向)和垂直方向(Y 方向)的梯度,通過近似計算一階偏導數來獲取梯度幅值和方向。具體來說,Sobel 算子使用兩個卷積核,一個用于檢測水平方向的邊緣,另一個用于檢測垂直方向的邊緣。以 3x3 的 Sobel 核為例,水平方向核為\(\begin{bmatrix}-1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1\end{bmatrix}\),垂直方向核為\(\begin{bmatrix}-1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1\end{bmatrix}\)。通過對圖像進行卷積運算,得到水平和垂直方向的梯度值,再根據兩者計算梯度幅值和方向,以確定邊緣位置。由于 Sobel 算子在計算梯度時考慮了鄰域像素的加權平均,對噪聲有一定的抑制能力。

2. OpenCV 實現

在 OpenCV 中,使用cv2.Sobel()函數實現 Sobel 邊緣檢測。該函數的第一個參數為輸入圖像,第二個參數為輸出圖像的深度,第三個參數為 X 方向的導數階數,第四個參數為 Y 方向的導數階數,此外還可指定卷積核的大小等參數。下面是使用 Sobel 算子進行邊緣檢測的示例代碼:

import cv2import numpy as npimport matplotlib.pyplot as plt# 讀取圖像并轉換為灰度圖img = cv2.imread('test.jpg', 0)# 計算X方向的梯度sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize = 5)sobelx = np.uint8(np.absolute(sobelx))# 計算Y方向的梯度sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize = 5)sobely = np.uint8(np.absolute(sobely))# 計算梯度幅值sobelxy = cv2.addWeighted(cv2.convertScaleAbs(sobelx), 0.5, cv2.convertScaleAbs(sobely), 0.5, 0)# 顯示結果plt.subplot(141), plt.imshow(img, cmap = 'gray'), plt.title('Original')plt.xticks([]), plt.yticks([])plt.subplot(142), plt.imshow(sobelx, cmap = 'gray'), plt.title('Sobel X')plt.xticks([]), plt.yticks([])plt.subplot(143), plt.imshow(sobely, cmap = 'gray'), plt.title('Sobel Y')plt.xticks([]), plt.yticks([])plt.subplot(144), plt.imshow(sobelxy, cmap = 'gray'), plt.title('Sobel XY')plt.xticks([]), plt.yticks([])plt.show()

三、Scharr 算子

1. 原理

Scharr 算子同樣用于計算圖像的梯度,本質上是 Sobel 算子的改進版本。在 Sobel 算子中,當卷積核較小時,對圖像細節的檢測能力有限。Scharr 算子使用固定的 3x3 卷積核,在計算梯度時,能更精確地逼近導數,對圖像細節的檢測效果優于 Sobel 算子。水平方向的 Scharr 核為\(\begin{bmatrix}-3 & 0 & 3 \\ -10 & 0 & 10 \\ -3 & 0 & 3\end{bmatrix}\),垂直方向的 Scharr 核為\(\begin{bmatrix}-3 & -10 & -3 \\ 0 & 0 & 0 \\ 3 & 10 & 3\end{bmatrix}\),這使得它在檢測圖像邊緣的細微變化時表現更出色。

2. OpenCV 實現

在 OpenCV 中,通過將cv2.Sobel()函數的ksize參數設置為cv2.CV_SCHARR來使用 Scharr 算子。下面是使用 Scharr 算子進行邊緣檢測的示例:

import cv2import numpy as npimport matplotlib.pyplot as plt# 讀取圖像并轉換為灰度圖img = cv2.imread('test.jpg', 0)# 計算X方向的梯度scharrx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize = cv2.CV_SCHARR)scharrx = np.uint8(np.absolute(scharrx))# 計算Y方向的梯度scharry = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize = cv2.CV_SCHARR)scharry = np.uint8(np.absolute(scharry))# 計算梯度幅值scharrxy = cv2.addWeighted(cv2.convertScaleAbs(scharrx), 0.5, cv2.convertScaleAbs(scharry), 0.5, 0)# 顯示結果plt.subplot(141), plt.imshow(img, cmap = 'gray'), plt.title('Original')plt.xticks([]), plt.yticks([])plt.subplot(142), plt.imshow(scharrx, cmap = 'gray'), plt.title('Scharr X')plt.xticks([]), plt.yticks([])plt.subplot(143), plt.imshow(scharry, cmap = 'gray'), plt.title('Scharr Y')plt.xticks([]), plt.yticks([])plt.subplot(144), plt.imshow(scharrxy, cmap = 'gray'), plt.title('Scharr XY')plt.xticks([]), plt.yticks([])plt.show()

四、Laplacian 算子

1. 原理

Laplacian 算子是一種二階導數算子,通過計算圖像的二階導數來檢測邊緣。與 Sobel 和 Scharr 算子基于一階導數不同,Laplacian 算子對圖像中的孤立點、線以及邊緣的變化更為敏感。其原理是通過對圖像進行拉普拉斯運算,找到二階導數為零的點,這些點通常對應圖像的邊緣。在實際應用中,常用的 Laplacian 核有\(\begin{bmatrix}0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0\end{bmatrix}\)等。由于 Laplacian 算子對噪聲非常敏感,通常在使用前需要對圖像進行平滑處理。

2. OpenCV 實現

在 OpenCV 中,使用cv2.Laplacian()函數實現 Laplacian 邊緣檢測。該函數的第一個參數為輸入圖像,第二個參數為輸出圖像的深度。以下是使用 Laplacian 算子進行邊緣檢測的示例代碼:

import cv2import numpy as npimport matplotlib.pyplot as plt# 讀取圖像并轉換為灰度圖img = cv2.imread('test.jpg', 0)# 使用高斯濾波對圖像進行平滑處理img = cv2.GaussianBlur(img, (3, 3), 0)# 進行Laplacian邊緣檢測laplacian = cv2.Laplacian(img, cv2.CV_64F)laplacian = np.uint8(np.absolute(laplacian))# 顯示結果plt.subplot(121), plt.imshow(img, cmap = 'gray'), plt.title('Original')plt.xticks([]), plt.yticks([])plt.subplot(122), plt.imshow(laplacian, cmap = 'gray'), plt.title('Laplacian')plt.xticks([]), plt.yticks([])plt.show()

五、Canny 邊緣檢測

1. 原理

Canny 邊緣檢測是一種被廣泛應用的邊緣檢測算法,它是一種多階段的算法,旨在檢測出圖像中真實、清晰的邊緣。Canny 算法主要包含以下幾個步驟:

  • 高斯濾波:對輸入圖像進行高斯濾波,去除噪聲,減少噪聲對邊緣檢測的干擾。
  • 計算梯度幅值和方向:使用 Sobel 等算子計算圖像中每個像素的梯度幅值和方向。
  • 非極大值抑制:在梯度方向上,對每個像素進行檢查,僅保留梯度幅值最大的像素,抑制非邊緣像素,從而細化邊緣。
  • 雙閾值檢測和邊緣連接:設置高、低兩個閾值,將梯度幅值大于高閾值的像素確定為強邊緣,小于低閾值的像素排除,介于兩者之間的像素根據其與強邊緣的連接性來確定是否為邊緣。

2. OpenCV 實現

在 OpenCV 中,使用cv2.Canny()函數實現 Canny 邊緣檢測。該函數的第一個參數為輸入圖像,第二個參數為低閾值,第三個參數為高閾值。示例代碼如下:

import cv2import numpy as npimport matplotlib.pyplot as plt# 讀取圖像并轉換為灰度圖img = cv2.imread('test.jpg', 0)# 進行Canny邊緣檢測edges = cv2.Canny(img, 100, 200)# 顯示結果plt.subplot(121), plt.imshow(img, cmap = 'gray'), plt.title('Original')plt.xticks([]), plt.yticks([])plt.subplot(122), plt.imshow(edges, cmap = 'gray'), plt.title('Canny Edges')plt.xticks([]), plt.yticks([])plt.show()

六、總結

本文詳細介紹了 OpenCV 中的多種邊緣檢測算法,包括 Sobel 算子、Scharr 算子、Laplacian 算子和 Canny 邊緣檢測算法。每種算法都有其獨特的原理和適用場景,Sobel 和 Scharr 算子基于一階導數,對噪聲有一定抗性且能較好檢測明顯邊緣;Laplacian 算子基于二階導數,對細節敏感但對噪聲也敏感;Canny 算法通過多階段處理,能檢測出更真實、連續的邊緣。在實際應用中,需根據圖像的特點和處理需求,選擇合適的邊緣檢測算法,以達到最佳的處理效果。

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

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

相關文章

Rollup詳解

Rollup 是一個 JavaScript 模塊打包工具,專注于 ES 模塊的打包,常用于打包 JavaScript 庫。下面從它的工作原理、特點、使用場景、配置和與其他打包工具對比等方面進行詳細講解。 一、 工作原理 Rollup 的核心工作是分析代碼中的 import 和 export 語句…

Chapter 7: Compiling C++ Sources with CMake_《Modern CMake for C++》_Notes

Chapter 7: Compiling C Sources with CMake 1. Understanding the Compilation Process Key Points: Four-stage process: Preprocessing → Compilation → Assembly → LinkingCMake abstracts low-level commands but allows granular controlToolchain configuration (c…

5分鐘上手GitHub Copilot:AI編程助手實戰指南

引言 近年來,AI編程工具逐漸成為開發者提升效率的利器。GitHub Copilot作為由GitHub和OpenAI聯合推出的智能代碼補全工具,能夠根據上下文自動生成代碼片段。本文將手把手教你如何快速安裝、配置Copilot,并通過實際案例展示其強大功能。 一、…

謝志輝和他的《韻之隊詩集》:探尋生活與夢想交織的詩意世界

大家好,我是謝志輝,一個扎根在文字世界,默默耕耘的寫作者。寫作于我而言,早已不是簡單的愛好,而是生命中不可或缺的一部分。無數個寂靜的夜晚,當世界陷入沉睡,我獨自坐在書桌前,伴著…

Logo語言的死鎖

Logo語言的死鎖現象研究 引言 在計算機科學中,死鎖是一個重要的研究課題,尤其是在并發編程中。它指的是兩個或多個進程因爭奪資源而造成的一種永久等待狀態。在編程語言的設計與實現中,如何避免死鎖成為了優化系統性能和提高程序可靠性的關…

深入理解矩陣乘積的導數:以線性回歸損失函數為例

深入理解矩陣乘積的導數:以線性回歸損失函數為例 在機器學習和數據分析領域,矩陣微積分扮演著至關重要的角色。特別是當我們涉及到優化問題,如最小化損失函數時,對矩陣表達式求導變得必不可少。本文將通過一個具體的例子——線性…

real_time_camera_audio_display_with_animation

視頻錄制 import cv2 import pyaudio import wave import threading import os import tkinter as tk from PIL import Image, ImageTk # 視頻錄制設置 VIDEO_WIDTH = 640 VIDEO_HEIGHT = 480 FPS = 20.0 VIDEO_FILENAME = _video.mp4 AUDIO_FILENAME = _audio.wav OUTPUT_…

【Pandas】pandas DataFrame astype

Pandas2.2 DataFrame Conversion 方法描述DataFrame.astype(dtype[, copy, errors])用于將 DataFrame 中的數據轉換為指定的數據類型 pandas.DataFrame.astype pandas.DataFrame.astype 是一個方法,用于將 DataFrame 中的數據轉換為指定的數據類型。這個方法非常…

Johnson

理論 全源最短路算法 Floyd 算法,時間復雜度為 O(n)跑 n 次 Bellman - Ford 算法,時間復雜度是 O(nm)跑 n 次 Heap - Dijkstra 算法,時間復雜度是 O(nmlogm) 第 3 種算法被 Johnson 做了改造,可以求解帶負權邊的全源最短路。 J…

Exce格式化批處理工具詳解:高效處理,讓數據更干凈!

Exce格式化批處理工具詳解:高效處理,讓數據更干凈! 1. 概述 在數據分析、報表整理、數據庫管理等工作中,數據清洗是不可或缺的一步。原始Excel數據常常存在格式不統一、空值、重復數據等問題,影響數據的準確性和可用…

(三十七)Dart 中使用 Pub 包管理系統與 HTTP 請求教程

Dart 中使用 Pub 包管理系統與 HTTP 請求教程 Pub 包管理系統簡介 Pub 是 Dart 和 Flutter 的包管理系統,用于管理項目的依賴。通過 Pub,開發者可以輕松地添加、更新和管理第三方庫。 使用 Pub 包管理系統 1. 找到需要的庫 訪問以下網址&#xff0c…

代碼隨想錄算法訓練營第三十五天 | 416.分割等和子集

416. 分割等和子集 題目鏈接:416. 分割等和子集 - 力扣(LeetCode) 文章講解:代碼隨想錄 視頻講解:動態規劃之背包問題,這個包能裝滿嗎?| LeetCode:416.分割等和子集_嗶哩嗶哩_bilibi…

HTTP 教程 : 從 0 到 1 全面指南 教程【全文三萬字保姆級詳細講解】

目錄 HTTP 的請求-響應 HTTP 方法 HTTP 狀態碼 HTTP 版本 安全性 HTTP/HTTPS 簡介 HTTP HTTPS HTTP 工作原理 HTTPS 作用 HTTP 與 HTTPS 區別 HTTP 消息結構 客戶端請求消息 服務器響應消息 實例 HTTP 請求方法 各個版本定義的請求方法 HTTP/1.0 HTTP/1.1 …

spring功能匯總

1.創建一個dao接口,實現類;service接口,實現類并且service里用new創建對象方式調用dao的方法 2.使用spring分別獲取dao和service對象(IOC) 注意 2中的service里面獲取dao的對象方式不用new的(DI) 運行測試: 使用1的方式創建servic…

Vue.js 實現下載模板和導入模板、數據比對功能核心實現。

在前端開發中,數據比對是一個常見需求,尤其在資產管理等場景中。本文將基于 Vue.js 和 Element UI,通過一個簡化的代碼示例,展示如何實現“新建比對”和“開始比對”功能的核心部分。 一、功能簡介 我們將聚焦兩個核心功能&…

volatile關鍵字用途說明

volatile 關鍵字在 C# 中用于指示編譯器和運行時系統,某個字段可能會被多個線程同時訪問,并且該字段的讀寫操作不應被優化(例如緩存到寄存器或重排序),以確保所有線程都能看到最新的值。這使得 volatile 成為一種輕量級…

【區塊鏈安全 | 第三十五篇】溢出漏洞

文章目錄 溢出上溢示例溢出漏洞溢出示例漏洞代碼代碼審計1. deposit 函數2. increaseLockTime 函數 攻擊代碼攻擊過程總結修復建議審計思路 溢出 算術溢出(Arithmetic Overflow),簡稱溢出(Overflow),通常分…

百度的deepseek與硅基模型的差距。

問題: 已經下載速度8兆每秒,請問下載30G的文件需要多長時間? 關于這個問題。百度的回答如下: ?30GB文件下載時間計算? ?理論計算?(基于十進制單位): ?單位換算? 文件大小:3…

車載診斷架構 --- 特殊定義NRC處理原理

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 周末洗了一個澡,換了一身衣服,出了門卻不知道去哪兒,不知道去找誰,漫無目的走著,大概這就是成年人最深的孤獨吧! 舊人不知我近況,新人不知我過…

面試題ing

1、js中set和map的作用和區別? 在 JavaScript 中,Set 和 Map 是兩種非常重要的集合類型 1、Set 是一種集合數據結構,用于存儲唯一值。它類似于數組,但成員的值都是唯一的,沒有重復的值。Set 中的值只能是唯一的,任何…