数字图像处理边缘检测算子matlab,[Matlab] [原始] [数字图像处理]经典Canny边缘检测算子的手动实现...

e19c24d851ffdb8104069a77b65d6d39.png

1. 使用高斯滤波器使输入图像平滑并消除高频噪声.

2. 计算输入图像的梯度幅度和梯度角. . . 使用sobel运算符计算梯度

3. 非最大抑制

(1)首先,我们创建一个角度模板,指定边缘的四个方向: -45°,0°,45°,90°,并创建一个矩阵来存储与上述4个方向相对应的3x3邻域相对于邻域中心点的坐标偏移,位于右下canny算子边缘检测 matlab,下,左下和右.

(2)其次,由于我们使用arctan函数计算梯度方向,因此获得的角度矩阵的范围为-90°至90°. 为了便于进行下一步,在上一步中找到四个角度中的哪个最接近梯度方向,我们要对梯度方向进行归一化,即将-90°到90°的范围归一化为-67.5°到112.5°(将小于-67.5°+180度的零件旋转到正对).

3ea4f84875a842f7eddc16de8981d977.png

(3)对应于每个像素的梯度方向与四个角度之间的差,以找到最小值. 这里我们需要对应于最小值的索引. 例如,索引值1对应于-45度,即,梯度方向是-45. 该度数最接近,然后我们可以将邻域中心像素的坐标添加到-45度的偏移量中,即存储了坐标偏移量矩阵的第一行数据. 通过直接调用索引值,可以在像素邻域中的相应角度实现像素选择.

(4)在找到所有最接近像素梯度方向的角度之后,我们得到一个包含元素1、2、3和4的矩阵,该矩阵是相应角度的索引值. 现在,我们计算在每个3x3邻域中相应的最近角度所在的直线方向上的中心像素与两个8个相邻像素之间的关系. 例如,如果中心像素的渐变方向最接近0°,则考虑像素的渐变大小与其上方和下方的像素的渐变大小之间的关系.

b15ab29632e5726a6181eee3a125bf69.png

(5)如果邻域中心像素的梯度幅度不小于其两个邻域的梯度幅度,则保持该梯度幅度;如果情况相反,则丢弃该位置的梯度幅度.

4. 执行滞后阈值处理

两个阈值(一个高和一个低)的人工设置认为,梯度幅度大于高阈值的位置是强边的位置,而梯度幅度的位置在高阈值和低阈值之间是弱边的位置

5. 建立边缘连接

将具有强边缘的图像中所有强边缘像素的位置定位,并将该位置记录为最终边缘,然后在每个强边缘像素的八个邻域中检测弱边缘像素的存在,如果存在,则也记录为最终边缘. 也就是说,将强边缘视为一条轨迹,并沿着该轨迹检测在沿该轨迹的3x3区域中是否存在弱边缘.

6canny算子边缘检测 matlab,优化边缘

由于检测到的边缘相对较厚,为方便使用,它们通过数学形态进行了精化.

BJnAju.PNG

在此示例中,使用大小为13x13,标准偏差为2的高斯滤波器. (注意: 为了确保二维高斯概率密度函数在n * n区域中可以包含99.7%的概率,需要将n设置为6倍标准偏差的最小正奇数. )高和低阈值分别为0.1和0.04.

f=imread('Fig1006(a).tif');

f=double(f);

f=f/255;

%高斯滤波,平滑图像,去除高频噪点

G=fspecial('gaussian',13,2);

f_gaussian=imfilter(f,G,'replicate');

figure(1),imshow(f_gaussian);

%使用Sobel算子计算梯度

S_x=fspecial('sobel');

f_sobel_x=imfilter(f_gaussian,S_x,'replicate');

S_y=S_x';

f_sobel_y=imfilter(f_gaussian,S_y,'replicate');

f_sobel_amp=sqrt(f_sobel_x.^2+f_sobel_y.^2);

f_sobel_ang=atan(f_sobel_y./f_sobel_x);%注意arctan函数的值域为-pi/2到pi/2,即f_sobel_ang中的值只会在这两个数之间

figure(2),imshow(f_sobel_amp);

figure(3),imshow(f_sobel_ang);

%非最大值抑制

%将4个基本边缘方向的角度值存放在向量direction中

direction=[-45 0 45 90];

%将4个基本边缘方向的角度值对应的邻域中相对于中心像素位置的平移量保存在2维矩阵direction_offset中

direction_offset=[1 -1;1 0;1 1;0 1];

%将角度单位转成弧度单位

direction=direction/180*pi;

%将f_sobel_ang中的弧度值转化进-67.5度对应的弧度到90度对应的弧度范围间

f_sobel_ang_trans=zeros(size(f_sobel_ang));

for i=1:size(f_sobel_ang,1)

for j=1:size(f_sobel_ang,2)

if f_sobel_ang(i,j)

f_sobel_ang_trans(i,j)=f_sobel_ang(i,j)+pi;

else

f_sobel_ang_trans(i,j)=f_sobel_ang(i,j);

end

end

end

f_sobel_ang_appro=zeros(size(f_sobel_ang));%保存弧度近似的结果

%寻找与f_sobel_ang_trans中的每个弧度最近的向量direction中的弧度对应的索引值,并将近似弧度的索引值保存在f_sobel_ang_appro中

for i=1:size(f_sobel_ang_trans,1)

for j=1:size(f_sobel_ang_trans,2)

[~,indices]=min(abs(f_sobel_ang_trans(i,j)-direction));

f_sobel_ang_appro(i,j)=indices;

end

end

f_sup=zeros(size(f,1)+2,size(f,2)+2);%保存最大值抑制的结果

%在f_sobel_amp的任一3x3邻域中判断邻域中心值是否全部大于沿近似角度方向和反方向上的两个邻域值。

%为避免滑窗时溢出,先进行图像边界填充

f_sobel_amp=padarray(f_sobel_amp,[1,1],'replicate');

%为方便角度信息使用,对f_sobel_ang_appro进行图像边界填充

f_sobel_ang_appro=padarray(f_sobel_ang_appro,[1,1],'replicate');

for i=2:size(f_sobel_amp,1)-1

for j=2:size(f_sobel_amp,2)-1

a=[i,j]+direction_offset(f_sobel_ang_appro(i,j),:);%邻域像素的坐标计算

if f_sobel_amp(i,j) >= f_sobel_amp(a(1),a(2)) && ... %a(1)为行数,a(2)为列数

f_sobel_amp(i,j) >= f_sobel_amp(a(1),a(2))

f_sup(i,j)=f_sobel_amp(i,j);

else

f_sup(i,j)=0;

end

end

end

%将最大值抑制结果的尺寸调整成输入图像的尺寸

f_sup=f_sup(2:size(f_sup,1)-1,2:size(f_sup,2)-1);

figure(4),imshow(f_sup);

%滞后阈值处理

%Canny建议低阈值:高阈值=1:3

low=0.04;

high=0.1;

f_sup_low=(f_sup>=low);%储存强边缘+弱边缘

f_sup_high=(f_sup>=high);%储存强边缘

f_sup_thresh=f_sup_low-f_sup_high;%储存弱边缘,即low<=f_sup_thresh<=high

figure(5),imshow(f_sup_thresh);

figure(6),imshow(f_sup_high);

%边缘连接操作

%由于需要对图像进行3x3邻域的滑窗操作,所以需要扩展图像大小

f_sup_thresh=padarray(f_sup_low,[1,1],'replicate');

f_sup_high=padarray(f_sup_high,[1,1],'replicate');

f_sup_conn=zeros(size(f_sup_thresh));

neigh=[-1 -1;-1 0;-1 1;0 -1;0 1;1 -1;1 0;1 1];%8邻域坐标偏移模板

for i=2:size(f_sup_conn,1)-1

for j=2:size(f_sup_conn,2)-1

%判断在第i行,第j列是否存在强边缘

if f_sup_high(i,j)==1

%若存在,则将该点看作是边缘点,显示在f_sup_conn中

f_sup_conn(i,j)=1;

%在点(i,j)的8邻域中进行操作,检查是否存在弱边缘点

for k=1:8

%若8邻域中的某一点是弱边缘点,则将该点看做是边缘点,显示在f_sup_conn中

if f_sup_thresh(i+neigh(k,1),j+neigh(k,2))==1

f_sup_conn(i+neigh(k,1),j+neigh(k,2))=1;

end

end

end

end

end

f_sup_conn=f_sup_conn(2:size(f_sup_conn,1)-1,2:size(f_sup_conn,2)-1);

%使用图像形态学进行边缘细化

f_sup_conn=bwmorph(f_sup_conn,'skel',Inf);

figure(7),imshow(f_sup_conn);

%对比

f_comparison=edge(f,'canny',[low,high],2);

figure(8),imshow(f_comparison);

实验结果:

1. 输入图片:

b512016266711b5fec57499b09f1f3cd.png

2,通过高斯滤波,然后使用sobel算子获得的梯度振幅图像

17158f143d5ff1846c16cf16786acaa1.png

d33af4fe63f2a12fefc5201009720309.png

3. 渐变图像

3b920fa651721333a46c792b952532.JPEG

在上图中,具有相同亮度的区域表示相同的渐变方向.

4. 非最大抑制

cdad43f5adfead31f05e1548556854.JPEG

与梯度幅度图相比,可以看出,在非最大抑制之后,高斯滤波引起的边缘模糊得到了抑制,就好像抗锯齿游戏效果没有打开.

5. 边缘图像弱

16735d3784acb98ee0babac1d5ccb867.png

aa75efc49ed4425cf40c6a3da813cd1b.png

6. 强边缘图像

fe1bf779f2647f1ff700b7a9d65a225e.png

您会看到边缘很粗,需要细化.

7. 边缘连接的精致图像

68e92999a1f6e0ba833463e9c58517e5.png

8. 与Matlab随附的Canny运算符进行比较

本文来自电脑杂谈,转载请注明本文网址:

http://www.pc-fly.com/a/jisuanjixue/article-154203-1.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值