目录
西安电子科技大学_计算机视觉_作业一_边缘检测
作业概述:
作业 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.
本文转自 https://blog.csdn.net/qq_32971095/article/details/133420554,如有侵权,请联系删除。