图像处理:边缘提取算法(边缘提取算子总结)——Matlab代码实现
邊緣提取算子
一階:??Roberts算子、Sobel算子、Prewitt算子、Kirsch算子、Robinson算子
二階: Laplacian算子、Canny算子、Marr-Hildreth(LoG算子)
?
Roberts 算子
在(i+1/2,j+1/2)處差分
轉化為模板即為
Roberts算子,又稱羅伯茨算子,是一種最簡單的算子,是一種利用局部差分算子尋找邊緣的算子。他采用對角線方向相鄰兩象素之差近似梯度幅值檢測邊緣。檢測垂直邊緣的效果好于斜向邊緣,定位精度高,對噪聲敏感,無法抑制噪聲的影響。
Roberts算子檢測方法對具有陡峭的低噪聲的圖像處理效果較好,但是提取邊緣的結果是邊緣比較粗,因此邊緣的定位不是很準確。
?
Sobel算子
Sobel算法是一個離散的一階差分算子,用來計算圖像亮度函數的一階梯度之近似值。在圖像的任何一點使用此算子,將會產生該點對應的梯度矢量或是其法矢量。
?
Prewitt算子
Prewitt算子是一種一階微分算子的邊緣檢測,利用像素點上下、左右鄰點的灰度差,在邊緣處達到極值檢測邊緣,去掉部分偽邊緣,對噪聲具有平滑作用。
其原理是在圖像空間利用兩個方向模板與圖像進行鄰域卷積來完成的,這兩個方向模板一個檢測水平邊緣,一個檢測垂直邊緣。
Prewitt算子檢測方法對灰度漸變和噪聲較多的圖像處理效果較好。但邊緣較寬,而且間斷點多。
對數字圖像f(x,y),Prewitt算子的定義如下:
G(i)={[f(i-1,j-1)+f(i-1,j)+f(i-1,j+1)]-[f(i+1,j-1)+f(i+1,j)+f(i+1,j+1)]}
G(j)={[f(i-1,j+1)+f(i,j+1)+f(i+1,j+1)]-[f(i-1,j-1)+f(i,j-1)+f(i+1,j-1)]}
則P(i,j)=max[G(i),G(j)]或 P(i,j)=G(i)+G(j)
?
Kirsch算子
Kirsch算子是R.Kirsch提出來一種邊緣檢測算法,它采用8個3*3的模板對圖像進行卷積,這8個模板代表8個方向,并取最大值作為圖像的邊緣輸出,8個模板如下,它在保持細節和抗噪聲方面都有較好的效果。
?
?
Robinson算子
規則同上,也是8個模板。
?
Laplacian算子
Laplacian算子法對噪聲比較敏感,所以很少用該算子檢測邊緣,而是用來判斷邊緣像素視為與圖像的明區還是暗區。
Laplacian 算子是n維歐幾里德空間中的一個二階微分算子,定義為梯度grad的散度div??墒褂眠\算模板來運算這定理定律。
函數的拉普拉斯算子也是該數的黑塞矩陣的跡,可以證明,它具有各向同性,即與坐標軸方向無關,坐標軸旋轉后梯度結果不變。
Laplacian 算子對噪聲比較敏感,所以圖像一般先經過平滑處理,因為平滑處理也是用模板進行的,所以,通常的分割算法都是把Laplacian 算子和平滑算子結合起來生成一個新的模板。
如果鄰域系統是4 鄰域,Laplacian 算子的模板為:
如果鄰域系統是8 鄰域,Laplacian 算子的模板為:
?
Canny算子
Canny方法不容易受噪聲干擾,能夠檢測到真正的弱邊緣。
優點在于,使用兩種不同的閾值分別檢測強邊緣和弱邊緣,并且當弱邊緣和強邊緣相連時,才將弱邊緣包含在輸出圖像中。
該算子效果較好,但是它實現起來較為麻煩,Canny算子是一個具有濾波,增強,檢測的多階段的優化算子,在進行處理前,Canny算子先利用高斯平滑濾波器來平滑圖像以除去噪聲,Canny分割算法采用一階偏導的有限差分來計算梯度幅值和方向,在處理過程中,Canny算子還將經過一個非極大值抑制的過程,最后Canny算子還采用兩個閾值來連接邊緣。
Canny邊緣檢測算法
step1: 用高斯濾波器平滑圖象;
step2: 用一階偏導的有限差分來計算梯度的幅值和方向;
step3: 對梯度幅值進行非極大值抑制
step4: 用雙閾值算法檢測和連接邊緣
參考:
https://blog.csdn.net/fengye2two/article/details/79190759
https://blog.csdn.net/jiachen0212/article/details/80078685
https://www.cnblogs.com/zhuifeng-mayi/p/9563947.html
https://www.cnblogs.com/techyan1990/p/7291771.html
?
Marr-Hildreth(LoG算子)
LoG可以看成是一個高斯模板的拉普拉斯變換? ?Laplace of Gaussian
(圖像的高斯拉普拉斯(LoG),可利用差分高斯(DoG)近似)
參考:
好:LOG高斯-拉普拉斯算子?https://blog.csdn.net/touch_dream/article/details/62237018?
DoG算子和LoG算子?https://blog.csdn.net/dreamguard/article/details/83988814
好:LoG算子?https://blog.csdn.net/songzitea/article/details/12851079
LOG邊緣檢測--Marr-Hildreth邊緣檢測算法?https://blog.csdn.net/bettyshasha/article/details/51757185??
好:SIFT特征點檢測,特征點描述,特征點匹配理解?https://blog.csdn.net/ds0529/article/details/79617619
matlab代碼
?
matlab自帶edge函數
matlab中edge函數提供了很多算子,函數原型和算子包括:
matlab自帶edge函數 使用代碼:
clear;clc;%讀取圖像 I=imread('Lena512.png'); %I=rgb2gray(I); figure;imshow(I,[]);title('Original Image');%sobel---------------------- sobelBW = edge(I,'sobel',0.06); %可以省去0.06,系統會默認。 figure;imshow(sobelBW,[]);title('Sobel 0.06')%roberts---------------------- robertsBW=edge(I,'roberts'); figure;imshow(robertsBW);title('Roberts Edge');%prewitt---------------------- prewittBW=edge(I,'prewitt'); figure;imshow(prewittBW);title('Prewitt Edge');%Laplacian---------------------- logBW=edge(I,'log'); figure;imshow(logBW);title('Laplasian of Gaussian Edge');%canny---------------------- cannyBW=edge(I,'canny'); figure;imshow(cannyBW);title('Canny Edge');%高斯濾波 再 canny ---------------------- h=fspecial('gaussian',5);%高斯濾波 I2=imfilter(I,h,'replicate'); GcannyBW=edge(I2,'canny');%高斯濾波后使用Canny算子進行邊緣檢測 figure;imshow(GcannyBW);title('Gaussian & Canny Edge');?
非matlasb自帶 :梯度法、roberts算子、prewitt算子、sobel算子、krisch算子、LoG算子
%% 非matlasb自帶 :梯度法、roberts算子、prewitt算子、sobel算子、krisch算子、LoG算子 clear;clc;close all f=imread('Lena512.png'); T=20;%閾值 [m,n]=size(f); %------梯度法------- f_g=zeros(m,n); for i=2:m-1for j=2:n-1f_g(i,j)=abs(f(i+1,j)-f(i,j))+abs(f(i,j+1)-f(i,j));if f_g(i,j)<Tf_g(i,j)=0;elsef_g(i,j)=255;endend end figure(1); subplot(2,3,1);imshow(uint8(f_g));title('梯度法'); %------roberts算子------- f_r=zeros(m,n); for i=2:m-1for j=2:n-1f_r(i,j)=abs(f(i+1,j+1)-f(i,j))+abs(f(i,j+1)-f(i+1,j));if f_r(i,j)<Tf_r(i,j)=0;elsef_r(i,j)=255;endend end %f_r=imbinarize(imfilter(f,r),T); subplot(2,3,2);imshow(uint8(f_r));title('Roberts算子');%------prewitt算子------- f_p=zeros(m,n); for i=2:m-1for j=2:n-1f_p(i,j)=abs(f(i-1,j-1)+f(i,j-1)+f(i+1,j-1)-f(i-1,j+1)-f(i,j+1)-f(i+1,j+1))+abs(f(i+1,j-1)+f(i+1,j)+f(i+1,j+1)-f(i-1,j-1)-f(i-1,j)-f(i-1,j+1));if f_p(i,j)<15f_p(i,j)=0;elsef_p(i,j)=255;endend end subplot(2,3,3);imshow(uint8(f_p));title('Prewitt算子');%------sobel算子------- f_s=zeros(m,n); for i=2:m-1for j=2:n-1f_s(i,j)=abs(f(i-1,j-1)+2*f(i,j-1)+f(i+1,j-1)-f(i-1,j+1)-2*f(i,j+1)-f(i+1,j+1))+abs(f(i+1,j-1)+2*f(i+1,j)+f(i+1,j+1)-f(i-1,j-1)-2*f(i-1,j)-f(i-1,j+1));if f_s(i,j)<Tf_s(i,j)=0;elsef_s(i,j)=255;endend end subplot(2,3,4);imshow(uint8(f_s));title('Sobel算子');%------krisch算子------- k(:,:,1)=[-3,-3,-3;-3,0,5;-3,5,5]; k(:,:,2)=[-3,-3,5;-3,0,5;-3,-3,5]; k(:,:,3)=[-3,5,5;-3,0,5;-3,-3,-3]; k(:,:,4)=[-3,-3,-3;-3,0,-3;5,5,5]; k(:,:,5)=[5,5,5;-3,0,-3;-3,-3,-3]; k(:,:,6)=[-3,-3,-3;5,0,-3;5,5,-3]; k(:,:,7)=[5,-3,-3;5,0,-3;5,-3,-3]; k(:,:,8)=[5,5,-3;5,0,-3;-3,-3,-3]; kk=zeros(size(f)); I=double(f); for i=1:8f_k(:,:,i)=conv2(I,k(:,:,i),'same');kk=max(kk,f_k(:,:,i)); end f_kk=imbinarize(kk,600); subplot(2,3,5);imshow(f_kk);title('Krisch算子');%------LoG算子------- log1=[0 0 -1 0 0;0 -1 -2 -1 0;-1 -2 16 -2 -1;0 -1 -2 -1 0;0 0 -1 0 0];f_l=conv2(f,log1,'same'); f_ll=imbinarize(abs(f_l),300); subplot(2,3,6);imshow(f_ll);title('LoG算子');?
非matlab自帶 ? Kirsch算子
(參考https://blog.csdn.net/u014485485/article/details/78339420)
clear;clc;close all%讀取圖像 bw1=imread('Lena512.png'); %bw1=rgb2gray(bw1); figure;imshow(bw1,[]);title('Original Image');%均值濾波 bw2=filter2(fspecial('average',3),bw1); %高斯濾波 bw3=filter2(fspecial('gaussian'),bw2); %利用小波變換對圖象進行降噪處理 [thr,sorh,keepapp]=ddencmp('den','wv',bw3); %獲得除噪的缺省參數 bw4=wdencmp('gbl',bw3,'sym4',2,thr,sorh,keepapp);%圖象進行降噪處理%提取圖象邊緣 t=[0.8 1.0 1.5 2.0 2.5].*10^5 ; %設定閾值 bw5=double(bw4); [m,n]=size(bw5); g=zeros(m,n); d=zeros(1,8); %利用Kirsch算子進行邊緣提取 for i=2:m-1for j=2:n-1d(1) =(5*bw5(i-1,j-1)+5*bw5(i-1,j)+5*bw5(i-1,j+1)-3*bw5(i,j-1)-3*bw5(i,j+1)-3*bw5(i+1,j-1)-3*bw5(i+1,j)-3*bw5(i+1,j+1))^2; d(2) =((-3)*bw5(i-1,j-1)+5*bw5(i-1,j)+5*bw5(i-1,j+1)-3*bw5(i,j-1)+5*bw5(i,j+1)-3*bw5(i+1,j-1)-3*bw5(i+1,j)-3*bw5(i+1,j+1))^2; d(3) =((-3)*bw5(i-1,j-1)-3*bw5(i-1,j)+5*bw5(i-1,j+1)-3*bw5(i,j-1)+5*bw5(i,j+1)-3*bw5(i+1,j-1)-3*bw5(i+1,j)+5*bw5(i+1,j+1))^2; d(4) =((-3)*bw5(i-1,j-1)-3*bw5(i-1,j)-3*bw5(i-1,j+1)-3*bw5(i,j-1)+5*bw5(i,j+1)-3*bw5(i+1,j-1)+5*bw5(i+1,j)+5*bw5(i+1,j+1))^2; d(5) =((-3)*bw5(i-1,j-1)-3*bw5(i-1,j)-3*bw5(i-1,j+1)-3*bw5(i,j-1)-3*bw5(i,j+1)+5*bw5(i+1,j-1)+5*bw5(i+1,j)+5*bw5(i+1,j+1))^2; d(6) =((-3)*bw5(i-1,j-1)-3*bw5(i-1,j)-3*bw5(i-1,j+1)+5*bw5(i,j-1)-3*bw5(i,j+1)+5*bw5(i+1,j-1)+5*bw5(i+1,j)-3*bw5(i+1,j+1))^2; d(7) =(5*bw5(i-1,j-1)-3*bw5(i-1,j)-3*bw5(i-1,j+1)+5*bw5(i,j-1)-3*bw5(i,j+1)+5*bw5(i+1,j-1)-3*bw5(i+1,j)-3*bw5(i+1,j+1))^2; d(8) =(5*bw5(i-1,j-1)+5*bw5(i-1,j)-3*bw5(i-1,j+1)+5*bw5(i,j-1)-3*bw5(i,j+1)-3*bw5(i+1,j-1)-3*bw5(i+1,j)-3*bw5(i+1,j+1))^2; g(i,j) = max(d);end end %顯示邊緣提取后的圖象 figure(2) for k=1:5for i=1:mfor j=1:nif g(i,j)>t(k)bw5(i,j)=255; elsebw5(i,j)=0;endendendsubplot(1,5,k)imshow(bw5,[])title(['Kirsch' ' ' num2str(t(k))]) end最后我之前自己寫的梯度法:
I=imread('1.jpg'); I=rgb2gray(I); T=10;%閾值 [x,y]=gradient(double(I)); %獲取梯度 t=sqrt(x.^2+y.^2); I(t>=T)=255; %梯度提取邊緣 畫黑 I(t<T)=0; I=uint8(I); imshow(I);imwrite(I,'my開方梯度.jpg'); %保存圖像到當前目錄本人水平有限,難免有錯誤疏漏,還望大佬多多批評指正。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的图像处理:边缘提取算法(边缘提取算子总结)——Matlab代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像处理:像素间的基本关系
- 下一篇: 信号与系统:快速傅里叶变换FFT中的实际