边缘检测——Matlab实现计算机视觉<1>

目录

作业概述:

一.一阶导数算子——Sobel算子

二.二阶导数算子——Canny算子

附录:

1.使用的sobel算子

2.使用的5*5高斯平滑模版

3.源代码


西安电子科技大学_计算机视觉_作业一_边缘检测

作业概述:

作业 1:边缘检测 编程语言:Matlab(推荐) 或 Python(可能需要使用 OpenCV)

题目内容:

自选一张图像,编程实现以下操作:

• 分别采用 Sobel 算子和 Canny 算子滤波,进行边缘提取;

• 显示原始图像以及不同滤波器滤波后的结果

• 对于 Sobel 滤波结果,显示 x 方向的梯度、y 方向的梯度、梯度幅度、梯 度角度等

• 对于 Canny 算子滤波,显示滤波后边缘检测结果 并分析不同滤波结果的差异。

说明:

(1)基于原理,自行实现,进行计算(禁止使用自带函数进行滤波)。各种滤 波函数应进行封装,并在统一的 test 文件(test.m or test.py)中调用使用。

(2) 所得各图像,按照子图样式显示(subplot),并标注(title)

(3) 打包文件夹,包含代码和文档,文档中应包含上述结果的截图及最终分 析。

要求:内容完备(包含计算过程),结构清晰、排版美观。

一.一阶导数算子——Sobel算子

通过求导可以得到边缘,边缘像素变化快,导数绝对值大。在离散点中则使用差分近似,通过与特定的卷积核卷积实现差分运算,并近似出该点导数。

而Sobel算子分为x轴方向和y轴方向,分别卷积获得各像素点x、y轴梯度x_g和y_g。梯度幅值用x_g和y_g的2-范数(平方和开根)求得(也可用1-范数[绝对值求和]近似,减少运算量),相位用arctan求得。

测试结果:

原图:

sobel滤波:

x方向梯度:

y方向梯度:

从图中可以清晰看到x轴方向和y轴方向的Sobel算子检测结果的差异。梯度的幅度和相位保存在mat文件中。

二.二阶导数算子——Canny算子

Canny边缘检测算法包括以下步骤[1]:

1.高斯平滑,滤除噪声

2.计算梯度强度和方向

3.应用非极大值抑制法(Nom-Maximum Suppression,NMS),以消除杂散效应

4.应用滞后阈值法检测边缘

(5.边缘跟踪得到单像素宽度的边缘图像)

这里主要说明第3步:

        图像梯度矩阵中的元素值大,不能直接用来判断该点为边缘。NMS可以剔除伪边缘信息。如果该像素满足梯度局部最大值,则判断该像素为边缘,并对其余像素的相关信息进行抑制。

        中心点周围有8个领域点,但做中心点梯度方向的直线的交点并不一定的8-领域点,根据交点所在的区域可以将领域划分为4块,交点PM、PN的值通过线性插值计算。

        最后放大保留下来的像素点,这里简单地将满足双阈值间的点灰度设置为255。

测试结果:

高斯平滑:

高斯平滑后sobel滤波:

非极大值抑制:

双阈值处理:

可以通过调整双阈值来调整最终结果保留细节的多少

附录:

1.使用的sobel算子

s_x=1/8*[1,0,-1;2,0,-2;1,0,-1];

s_y=1/8*[-1,-2,-1;0,0,0;1,2,1];

2.使用的5*5高斯平滑模版

gs=1/159*[2,4,5,4,2;4,9,12,9,4;5,12,15,12,5;4,9,12,9,4;2,4,5,4,2];

3.源代码

function []=Sobel_Canny_Filter(Src_img)
%% 输入参数:同路径下照片名。使用举例:Sobel_Canny_filter('Test.jpg')

%%  一阶导数——Sobel算子。
F=imread(Src_img);
f=double(rgb2gray(F));
[row,col]=size(f);

%   Sobel核处理结果
X_grad=zeros(row,col);
Y_grad=zeros(row,col);
S_dir=zeros(row,col);
Output_img=zeros(row,col);

%   Sobel核
s_x=[1,0,-1;2,0,-2;1,0,-1];
s_y=[-1,-2,-1;0,0,0;1,2,1];

for i=2:row-1
    for j=2:col-1
        %   卷积运算
        fx=[f(i-1,j-1),f(i-1,j),f(i-1,j+1);f(i,j-1),f(i,j),f(i,j+1);f(i+1,j-1),f(i+1,j),f(i+1,j+1)];
        fy=[f(i-1,j-1),f(i-1,j),f(i-1,j+1);f(i,j-1),f(i,j),f(i,j+1);f(i+1,j-1),f(i+1,j),f(i+1,j+1)];
        Sx=0.125*s_x.*fx;
        Sy=0.125*s_y.*fy;
        x_g=sum(Sx,'all');
        y_g=sum(Sy,'all');
        
        %   关键数值求解
        S_dir(i,j)=atan2(y_g,x_g);        
        A=sqrt(x_g^2+y_g^2);
        X_grad(i,j)=abs(x_g);
        Y_grad(i,j)=abs(y_g);
        Output_img(i,j)=A;
    end
end

%%   绘图
figure(8);

%   原图
subplot(2,4,1);
imshow(F);
title('source');

%   sober滤波后图
subplot(2,4,2);
imshow(Output_img,[]);
title('sobel-filter');
imwrite(uint8(Output_img),'sobel_filter.jpg');

%   x方向梯度
subplot(2,4,3);
imshow(X_grad,[]);
title('x-grad');
imwrite(uint8(X_grad),'X_grad.jpg');

%   y方向梯度
subplot(2,4,4);
imshow(Y_grad,[]);
title('y-grad');
imwrite(uint8(Y_grad),'Y_grad.jpg');

%   保存梯度的幅度和相位
save('Amplitude.mat',"A");
save('dir.mat',"S_dir");

%% 二阶导数——Canny算子。
%%   高斯滤波  
Gs=zeros(row,col);
Gs_sobel=zeros(row,col);
Canny_temp=zeros(row,col);
Canny=zeros(row,col);
%   5*5高斯核
gs=[2,4,5,4,2;4,9,12,9,4;5,12,15,12,5;4,9,12,9,4;2,4,5,4,2];
for i=3:row-2
    for j=3:col-2
        gg=[f(i-2,j-2),f(i-2,j-1),f(i-2,j),f(i-2,j+1),f(i-2,j+2);f(i-1,j-2),f(i-1,j-1),f(i-1,j),f(i-1,j+1),f(i-1,j+2);f(i,j-2),f(i,j-1),f(i,j),f(i,j+1),f(i,j+2);f(i+1,j-2),f(i+1,j-1),f(i+1,j),f(i+1,j+1),f(i+1,j+2);f(i+2,j-2),f(i+2,j-1),f(i+2,j),f(i+2,j+1),f(i+2,j+2)];
        s_g=gs.*gg/159;
        Gs(i,j)=sum(s_g,'all');
    end
end

%%   高斯平滑
for i=3:row-2
    for j=3:col-2
        gsx=[Gs(i-1,j-1),Gs(i-1,j),Gs(i-1,j+1);Gs(i,j-1),Gs(i,j),Gs(i,j+1);Gs(i+1,j-1),Gs(i+1,j),Gs(i+1,j+1)];
        gsy=[Gs(i-1,j-1),Gs(i-1,j),Gs(i-1,j+1);Gs(i,j-1),Gs(i,j),Gs(i,j+1);Gs(i+1,j-1),Gs(i+1,j),Gs(i+1,j+1)];
        Sx=0.125*s_x.*gsx;
        Sy=0.125*s_y.*gsy;
        gsx_g=sum(Sx,'all');
        gsy_g=sum(Sy,'all');
        
        GSS_dir(i,j)=atan(gsx_g/gsy_g);        
        GSA=sqrt(gsx_g^2+gsy_g^2);
        GSX_grad(i,j)=abs(x_g);
        GSY_grad(i,j)=abs(y_g);
        Gs_sobel(i,j)=GSA;
    end
end

%%   高斯平滑后sobel滤波
for i=3:row-2
    for j=3:col-2
        k=abs(tan(GSS_dir(i,j)));
        %   非极大值抑制
        %   判断领域点(非8-领域点可划分为4部分)并进行相应线性插值并判断是否为局部大优点(进行保留)
        if (GSS_dir(i,j)>=0 && GSS_dir(i,j)<pi/4) || (GSS_dir(i,j)>=-pi && GSS_dir(i,j)<-3*pi/4)
            if Gs_sobel(i,j) >= Gs_sobel(i+1,j+1)+(Gs_sobel(i+1,j+1)-Gs_sobel(i+1,j))/k && Gs_sobel(i,j) >= Gs_sobel(i-1,j-1)+(Gs_sobel(i-1,j-1)-Gs_sobel(i-1,j))/k
             Canny_temp(i, j) = Gs_sobel(i, j);
            end        
        elseif (GSS_dir(i,j)>=pi/4 && GSS_dir(i,j)<pi/2) || (GSS_dir(i,j)>=-3*pi/4 && GSS_dir(i,j)<-pi/2)
            if Gs(i,j) >= (Gs_sobel(i-1,j-1)+(Gs_sobel(i,j-1)-Gs_sobel(i-1,j-1))/k) && Gs_sobel(i,j) >= (Gs_sobel(i+1,j+1)+(Gs_sobel(i,j+1)-Gs_sobel(i+1,j+1))/k)
             Canny_temp(i, j) = Gs_sobel(i, j);
            end
        elseif (GSS_dir(i,j)>=pi/2 && GSS_dir(i,j)<3*pi/4) || (GSS_dir(i,j)>=-pi/2 && GSS_dir(i,j)<-pi/4)
            if Gs_sobel(i,j) >= Gs_sobel(i+1,j-1)+(Gs_sobel(i,j-1)-Gs_sobel(i+1,j-1))/k && Gs_sobel(i,j) >= Gs_sobel(i-1,j+1)+(Gs_sobel(i,j+1)-Gs_sobel(i-1,j+1))/k
             Canny_temp(i, j) = Gs_sobel(i, j);
            end
        elseif (GSS_dir(i,j)>=3*pi/4 && GSS_dir(i,j)<pi) || (GSS_dir(i,j)>=-pi/4 && GSS_dir(i,j)<0)
            if Gs_sobel(i,j) >= Gs_sobel(i+1,j-1)+(Gs_sobel(i+1,j-1)-Gs_sobel(i+1,j))/k && Gs_sobel(i,j) >= Gs_sobel(i-1,j+1)+(Gs_sobel(i-1,j+1)-Gs_sobel(i-1,j))/k
             Canny_temp(i, j) = Gs_sobel(i, j);
            end
        end
    end
end

%%   双阈值变换
lowTh  = 0.02 *max(max(Canny_temp));%高阈值
higtTh = 1 *max(max(Canny_temp));%低阈值

for i = 3 : row-2
    for j = 3 : col-2
        %   灵活设置保留值
        if Canny_temp(i,j) >=lowTh && Canny_temp(i,j) <= higtTh
            %Canny(i,j) = Canny_temp(i,j);
            Canny(i,j) = 255;
        end
    end
end

%% 绘图
%   高斯平滑结果
subplot(2,4,5);
imshow(Gs,[]);
title('gauss-filter');
imwrite(uint8(Gs),'gauss_filter.jpg');

%   高斯平滑后sobel滤波结果
subplot(2,4,6);
imshow(Gs_sobel,[]);
title('gauss-sobel-filter');
imwrite(uint8(Gs_sobel),'Gs_sobel_filter.jpg');

%   非极大值抑制后结果
subplot(2,4,7);
imshow(Canny_temp,[]);
title('Canny-temp');
imwrite(uint8(Canny_temp),'Canny_temp.jpg');

%   阈值间处理
subplot(2,4,8);
imshow(Canny,[]);
title('Canny-filter');
imwrite(uint8(Canny),'Canny_filter.jpg');

%保存结果
saveas(8,'result.jpg');
 
end

参考文献

[1]柳林.基于OpenCV的数字图像处理技术[M].杭州:浙江大学出版社,2020:202-203.

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

switch_swq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值