图像边界提取——canny算法

%利用canny算子提取边缘
clc,clear
% 读入图片
rice_img = imread('rice.jpg');
figure,imshow(rice_img);
title('原始图像')
[m,n] = size(rice_img);
%%
%对图像进行高斯平滑,选用的模板为3*3的模板
% 生成高斯模板
[x,y] = meshgrid([-3:3],[-3:3]);
sigma = 0.5;
h = exp(-(x.*x+y.*y)./(2*sigma^2))/(2*pi*sigma^2)
% 接着进行归一化处理
sumh = sum(h(:))
h = h/sumh;
% 模板已经生成,接下来开始模板处理图像
[hh,hw] = size(h);
H_size = floor(hh/2);
l_img1 = zeros(m+H_size*2,n+H_size*2);
l_img1(H_size+1:H_size+m,H_size+1:H_size+n) = rice_img;
rice_img_Gauss = zeros(m,n);
for i =1:m
    for j=1:n
        t = l_img1(i:i+hh-1,j:hw+j-1).*h;
        rice_img_Gauss (i,j) = sum(t(:));
    end
end;
figure,imshow(uint8(rice_img_Gauss));
title('高斯平滑之后的图像');
%%
%利用sobel算子计算图像的两个方向的梯度幅值
%sobel算子
Gy = [-1 0 1; -2 0 2; -1 0 1];
Gx = [-1 -2 -1; 0 0 0; 1 2 1];
%填充图像
[M1,N1] = size(rice_img_Gauss);
l_img2 = zeros(M1+2,N1+2);
l_img2(2:M1+1,2:N1+1) = rice_img_Gauss;
l_img2(1,2:N1+1) = rice_img_Gauss(1,:);
l_img2(M1+2,2:N1+1) = rice_img_Gauss(M1,:);
l_img2(2:M1+1,1) = rice_img_Gauss(:,1);
l_img2(2:M1+1,N1+2) = rice_img_Gauss(:,N1);
for i =1:m
    for j =1:n
        t1 = l_img2(i:i+2,j:j+2).*Gx;
        t2 = l_img2(i:i+2,j:j+2).*Gy;
        rice_img_sobel_x(i,j) = sum(t1(:));
        rice_img_sobel_y(i,j) = sum(t2(:));
    end
end
%计算梯度的幅值和方向
rice_img_sobel = abs(rice_img_sobel_x)+abs(rice_img_sobel_y);
rice_img_seta = atan2(rice_img_sobel_y,rice_img_sobel_x);
rice_img_sobel = uint8(rice_img_sobel);
% 角度值的范围在-3.14---0.14
%%
%接下来确定每个点的方向,并进行标记
% 2 1 4 
% 3   3
% 4 1 2
rice_img_seta = rice_img_seta/pi*180;
% 将角度映射到-180--180°上
rice_dirction_mark = zeros(m,n);
for i =1:m
    for j =1:n
        if((rice_img_seta(i,j)>=-22.5)&&(rice_img_seta(i,j)<22.5))||((rice_img_seta(i,j)>=-180)&&(rice_img_seta(i,j)<-157.5))||(rice_img_seta(i,j)>=157.5)
            rice_dirction_mark(i,j) = 1;
        else if ((rice_img_seta(i,j)>=22.5)&&(rice_img_seta(i,j)<67.5))||((rice_img_seta(i,j)>=-157.5)&&(rice_img_seta(i,j)<-122.5))
                rice_dirction_mark(i,j) = 2;
            else if((rice_img_seta(i,j)>=67.5)&&(rice_img_seta(i,j)<122.5))||((rice_img_seta(i,j)>=-122.5)&&(rice_img_seta(i,j)<-67.5))
                    rice_dirction_mark(i,j) = 3;
                else
                    rice_dirction_mark(i,j) = 4;
                end
            end
        end
    end
end
%%
% 下面依据标记的结果,进行非极大值抑制
% 设置上下阈值
max_rate = 0.9;
min_rate = 0.6;
% 最低阈值调高,会使最后的效果更好
threshold_max = max_rate * 255;
threshold_min = min_rate * 255;
match_list = [1 1 0 -1 -1 -1  0 1;
              0 1 1  1  0 -1 -1 -1 ];
img_non_maxmum_suppression_result = zeros(m,n);
for i =2:m-1
    for j =2:n-1
        if(rice_img_sobel(i,j)>=threshold_max)
            img_non_maxmum_suppression_result(i,j) = 255;
        else if(rice_img_sobel(i,j)<=threshold_min)
                img_non_maxmum_suppression_result(i,j) = 0;
            else
                nb_point_1 = rice_img_sobel(i + match_list(1,rice_dirction_mark(i,j)),j + match_list(2,rice_dirction_mark(i,j)));
                nb_point_2 = rice_img_sobel(i + match_list(1,rice_dirction_mark(i,j)+4),j + match_list(2,rice_dirction_mark(i,j)+4))
                if(rice_img_sobel(i,j)>=nb_point_1)&&(rice_img_sobel(i,j)>=nb_point_2)
                    img_non_maxmum_suppression_result(i,j) = 250;
                else
                    img_non_maxmum_suppression_result(i,j) = 0;
                end
            end
        end
    end
end
img_non_maxmum_suppression_result = uint8(img_non_maxmum_suppression_result);
figure,imshow(img_non_maxmum_suppression_result);
title('canny处理后的结果')

原始图像
在这里插入图片描述
滤波之后的图像
在这里插入图片描述
canny处理之后的图像
在这里插入图片描述
效果还不错

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值