一、Canny邊緣檢測算法概述
Canny邊緣檢測算法是一種經典的邊緣檢測算法,該算法由 John F. Canny 在 1986 年提出。Canny算法的主要目標是在最小錯誤率的前提下儘可能正確地檢測出圖像中的邊緣。它採用了多階段的邊緣檢測過程,首先使用高斯濾波器對圖像進行平滑處理,隨後使用 Sobel 算子計算圖像梯度,同時獲取梯度方向和大小信息。最後,通過非極大值抑制和雙閾值篩選來檢測並連接真實邊緣。
二、Canny邊緣檢測算法優缺點
1.**優點**
Canny算法可以準確地檢測出圖像中的邊緣,並且抑制噪聲的能力較強。它能夠消除大部分非邊緣響應點,以及盡量保留真實邊緣的形態和特徵。此外,Canny算法還可以自適應地確定雙閾值,使得結果更加準確可靠。
2.**缺點**
Canny算法還存在一些問題。首先,它對計算資源的需求比較高,這會導致它的處理速度較慢。其次,在邊緣非常接近時,Canny算法可能會漏檢或錯誤檢測;在邊緣彎曲或存在斷裂時,也容易造成無法正確檢測邊緣。
三、Canny邊緣檢測算法原理
Canny算法主要分為四個步驟:高斯濾波、計算圖像梯度、非極大值抑制和雙閾值篩選。
1.**高斯濾波**
Canny算法首先使用高斯濾波器對原始圖像進行平滑化操作,以去除圖像中的高頻部分和噪聲。高斯濾波器是一個平滑權重的過程,它可以使得圖像中的像素點變得更加模糊,從而減少噪聲的影響。高斯濾波的公式為:G_(x,y)=(1/2∏σ^2)exp(-(x^2+y^2)/2σ^2),其中 σ 表示高斯核的標準差。
2.**圖像梯度計算**
Canny算法使用 Sobel 算子計算圖像的梯度,包括梯度方向和梯度大小。在這個階段,我們需要對圖像進行卷積計算。Sobel算子是一個 3×3 的卷積核,可以用來計算圖像的一階導數。Sobel算子分為水平(Gx)和垂直(Gy)兩個方向,分別使用以下卷積核進行卷積:
Gx = [-1 0 1; -2 0 2; -1 0 1]; Gy = [-1 -2 -1; 0 0 0; 1 2 1];
3.**非極大值抑制**
非極大值抑制是指只留下梯度值最大的點,而抑制其餘梯度值較小或不是局部最大值的點。這個步驟的目的是消除平滑後圖像中的較弱點,保留更加突出的邊緣。對於每個像素點,我們檢查周圍 8 個像素點,如果它的梯度值不是周圍8個像素中的最大值,則將其梯度值設為0。
4.**雙閾值篩選**
雙閾值篩選是為了將所有梯度值的點分成三類:強邊緣、弱邊緣和非邊緣。如果一個點的梯度值大於高閾值,我們就將其標記為強邊緣;如果一個點的梯度值小於低閾值,我們就將其標記為非邊緣;如果一個點的梯度值介於兩者之間,則將其標記為弱邊緣。在這個階段,我們嘗試將弱邊緣通過與強邊緣相鄰接來轉換成強邊緣,並且將與非邊緣相鄰的弱邊緣直接去除。
四、Canny邊緣檢測算法Matlab代碼
1. Canny算法Matlab代碼
% 讀取圖像 I = imread('lena.png'); % 將圖像轉換為灰度圖像 I = rgb2gray(I); % 使用高斯濾波器進行平滑化操作 I_smooth = imgaussfilt(I, 2); % 計算梯度,獲取梯度幅度和方向 [Gx, Gy] = imgradientxy(I_smooth); [GMag, GDir] = imgradient(Gx, Gy); % 非極大值抑制 GMag_suppressed = zeros(size(GMag)); for i = 2:size(GMag, 1)-1 for j = 2:size(GMag, 2)-1 if (GDir(i,j) -22.5) || ... (GDir(i,j) 157.5) if (GMag(i,j) >= GMag(i, j-1) && GMag(i,j) >= GMag(i,j+1)) GMag_suppressed(i,j) = GMag(i,j); end elseif (GDir(i,j) > 22.5 && GDir(i,j) <= 67.5) || ... (GDir(i,j) -157.5) if (GMag(i,j) >= GMag(i-1, j-1) && GMag(i,j) >= GMag(i+1, j+1)) GMag_suppressed(i,j) = GMag(i,j); end elseif (GDir(i,j) > 67.5 && GDir(i,j) <= 112.5) || ... (GDir(i,j) -112.5) if (GMag(i,j) >= GMag(i-1, j) && GMag(i,j) >= GMag(i+1, j)) GMag_suppressed(i,j) = GMag(i,j); end elseif (GDir(i,j) > 112.5 && GDir(i,j) <= 157.5) || ... (GDir(i,j) -67.5) if (GMag(i,j) >= GMag(i-1, j+1) && GMag(i,j) >= GMag(i+1, j-1)) GMag_suppressed(i,j) = GMag(i,j); end end end end % 雙閾值篩選 T_L = 0.05 * max(max(GMag_suppressed)); T_H = 0.15 * max(max(GMag_suppressed)); G_edge = zeros(size(GMag_suppressed)); for i = 1:size(GMag_suppressed, 1) for j = 1:size(GMag_suppressed, 2) if GMag_suppressed(i,j) > T_H G_edge(i,j) = 1; elseif GMag_suppressed(i,j) > T_L && GMag_suppressed(i,j) T_H || GMag_suppressed(i-1,j) > T_H || GMag_suppressed(i-1,j+1) > T_H || ... GMag_suppressed(i,j-1) > T_H || GMag_suppressed(i,j+1) > T_H || ... GMag_suppressed(i+1,j-1) > T_H || GMag_suppressed(i+1,j) > T_H || GMag_suppressed(i+1,j+1) > T_H) G_edge(i,j) = 1; end end end end % 展示結果 imshow(G_edge);
2. Sobel算子Matlab代碼
% 讀取圖像 I = imread('lena.png'); % 將圖像轉換為灰度圖像 I = rgb2gray(I); % 計算Sobel算子,獲取水平和垂直方向的梯度 Sx = [-1 0 1; -2 0 2; -1 0 1]; Sy = [-1 -2 -1; 0 0 0; 1 2 1]; Gx = imfilter(I, Sx); Gy = imfilter(I, Sy); % 顯示結果 subplot(1,2,1); imshow(Gx); title('Sobel算子水平梯度'); subplot(1,2,2); imshow(Gy); title('Sobel算子垂直梯度');
3. 圖像邊緣檢測Matlab函數
% 讀取圖像 I = imread('lena.png'); % 將圖像轉換為灰度圖像 I = rgb2gray(I); % 使用canny函數進行邊緣檢測 BW = edge(I, 'canny'); % 顯示結果 imshow(BW);
五、Canny邊緣檢測算法Python代碼
1. Canny算法Python代碼
# 導入Python圖片處理庫
from PIL import Image
# 導入Python圖像處理庫
from scipy import ndimage
import numpy as np# 讀取圖像
image = Image.open('lena.png').convert('L')# 將圖像轉換為數組
image_array = np.array(image)# 高斯濾波
image_smooth = ndimage.gaussian_filter(image_array, 2)# 計算梯度
dx, dy = np.gradient(image_smooth)
gradient_mag = np.sqrt(dx ** 2 + dy ** 2)
gradient_dir = np.arctan2(dy, dx) * 180 / np.pi# 非極大值抑制
grad_suppressed = np.zeros_like(gradient_mag)
h, w = gradient_mag.shape
for i in range(1, h - 1):
for j in range(1, w - 1):
if (gradient_dir[i][j] -22.5) or (gradient_dir[i][j] 157.5):
if (gradient_mag[i][j] >= gradient_mag[i][j - 1] and gradient_mag[i][j] >= gradient_mag[i][j + 1]):
grad_suppressed[i][j] = gradient_mag[i][j]
elif (gradient_dir[i][j] > 22.5 and gradient_dir[i][j] <= 67.5) or (gradient_dir[i][j] -157.5):
if (gradient_mag[i][j] >= gradient_mag[i - 1][j - 1] and gradient_mag[i][j] >= gradient_mag[i + 1][j + 1]):
grad_suppressed[i][j] = gradient_mag[i][j]
elif (gradient_dir[i][j] > 67.5 and gradient_dir[i][j] <= 112.5) or (gradient_dir[i][j] -112.5):
if (gradient_mag[i][j] >= gradient_mag[i - 1][j] and gradient_mag[i][j] >= gradient_mag[i + 1][j]):
grad_suppressed[i][j] = gradient_mag[i][j]
elif (gradient_dir[i][j] > 112.5 and gradient_dir[i][j] <= 157.5) or (gradient_dir[i原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/182009.html