(亲测可用)基于matlab的用自写函数来实现图像的灰度处理sobel canny算子边缘检测

I=imread(‘E:\matlab\toolbox\images\imdata\tupian4.jpg’); %图片的位置是自己设置的

subplot(2,5,1);
imshow(I);
title(‘原始图像’);

G=I(:,:,2);
subplot(2,5,2);
imshow(G);
title(‘灰度处理后图像’); %彩色图像需要灰度处理,黑白图像则不需要

c=avefilt(G,3); %对G用3x3的模板进行滤波
subplot(2,5,3);
imshow(uint8( c ));
title(‘均值滤波后的图像’);

hx=[-1 -2 -1;0 0 0 ;1 2 1]; %生产sobel垂直梯度模板,这里用的是自定义的模板
hy=hx’; %生产sobel水平梯度模板

gradx=filter2(hx,c,‘same’);
gradx=abs(gradx); %计算图像的sobel垂直梯度

grady=filter2(hy,c,‘same’);
grady=abs(grady); %计算图像的sobel水平梯度

grad=gradx+grady;                  %得到图像的sobel梯度
subplot(2,5,4);
imshow(grad,[ ]);
title('图像的sobel梯度');

%canny算子--------------------------------------------------------
[m,n]=size(G);
src_gaussion=my_gaussian(G,3,9); %高斯滤波

w=fspecial(‘sobel’); %这里的sobel算子是与上面不同的算法
src_sobel_x=imfilter(src_gaussion,w,‘replicate’); %求横边缘
w=w’;
src_sobel_y=imfilter(src_gaussion,w,‘replicate’); %求竖边缘
src_sobel_x=double(src_sobel_x);
src_sobel_y=double(src_sobel_y);
src_sobel=sqrt(src_sobel_x.2+src_sobel_y.2); %注意平方和在开方。
% figure;
subplot(2,5,5);
imshow(uint8(src_sobel_x))

title(‘这是sobel进行梯度处理后的图像’);
new_angel_img=zeros(m,n);
for i=1:m
for j=1:n
Mx=src_sobel_x(i,j);
My=src_sobel_y(i,j);

    if My~=0  
        o=atan(Mx/My);      %边缘的法线弧度  
    elseif My==0 && Mx>0  
        o=pi/2;  
    else  
        o=-pi/2;              
    end  
      
    if( ( o>=( -22.5/180*pi ) && o<( 22.5/180*pi ) ) || ( o>=( 157.5/180*pi ) && o<=pi ) || ( o<=( -157.5/180*pi ) && o>=-pi ) )  
        d1=0;  
    elseif (  ( o>= ( 22.5/180*pi ) && o<( 67.5/180*pi ) ) ||  (   o>=( -157.5/180*pi ) && o<(-112.5/180*pi )  )   )  
        d1=-45;  
    elseif ( ( o>=(67.5/180*pi) && o<(112.5/180*pi) ) || ( o>=(-112.5/180*pi) && o<-67.5/180*pi ) )     
        d1=90;  
    else        
        d1=45;  
     end  
        new_angel_img(i,j)=d1;  
end  

end

canny_dst=src_sobel;
%%%%%%%%%%%%%%%%%%非最大值抑制%%%%%%%%%%%%%%%%%%%%%%%5
for i=3:m-2
for j=3:n-2
if( new_angel_img(i,j)0 )
A=[canny_dst(i-1,j),canny_dst(i+1,j)];
if( abs(canny_dst(i,j))< max( abs(A) ) )
canny_dst(i,j)=0;
end
elseif( new_angel_img(i,j)
-45 )
A=[canny_dst(i-1,j-1),canny_dst(i+1,j+1)];
if( abs(canny_dst(i,j))< max( abs(A) ))
canny_dst(i,j)=0;
end
elseif( new_angel_img(i,j)==90 )
A=[canny_dst(i,j-1),canny_dst(i,j+1)];
if( abs(canny_dst(i,j))< max( abs(A) ) )
canny_dst(i,j)=0;
end
elseif( new_angel_img(i,j)==45 )
A=[canny_dst(i-1,j+1),canny_dst(i+1,j-1)];
if( abs(canny_dst(i,j))< max( abs(A) ) )
canny_dst(i,j)=0;
end
end
end
end

% figure(2);
subplot(2,5,6);
imshow(canny_dst);

title(‘这是非最大值抑制11’);
gh=zeros(m,n);
gl=zeros(m,n);
gl1=zeros(m,n);
for i=1:m
for j=1:n
if( canny_dst(i,j)>=100 )
gh(i,j)=1;
else
gh(i,j)=0;
end
if( canny_dst(i,j)>=30)
gl(i,j)=1;
else
gl(i,j)=0;
end
end
end
gl1=gl;
gl1=logical(gl1);
gh=logical(gh);
% figure(3);
subplot(2,5,7);
imshow(gl1);
title(‘这是非最大值抑制22’);

% figure(4);
subplot(2,5,8);
imshow(gh);
title(‘这是递归连接后的33’);
%%%%%%%%%%%%%%%%%%%%%%%%递归连接%%%%%%%%%%%%%%%%%%%
up=100; %上阈值
low=33; %下阈值
set(0,‘RecursionLimit’,10000); %设置最大递归深度
for i=1:m
for j=1:n
if canny_dst(i,j)>up &&canny_dst(i,j)~=255 %判断上阈值
canny_dst(i,j)=255;
canny_dst=connect(canny_dst,i,j,low);
end
end
end
% figure(5);
subplot(2,5,9);
imshow(canny_dst==255);

title(‘这是递归连接后的’);
BW2 = edge(src_gaussion,‘canny’);
% figure(6);
subplot(2,5,10);
imshow(BW2);
title(‘这是递归连接后的2’);

%所需函数————————————————————————————————————

function d=my_gaussian(src,n,k)

n1=(n+1)/2; %%%%%%%%%%%%%计算高斯滤波模版中心
[m,l]=size(src);
b=zeros(n,n); %%%%%%%%%%%%%空模版
I=zeros(m,l);
d=zeros(m,l);
img=zeros(m,l);
%%%%%%%%%%%%%%%%%计算高斯滤波模版的各个系数
for i=1:n
for j=1:n
b(i,j)=(exp(-((i-n1)^2 +(j-n1)^2)/(2k)))/(2pi*k);
end
end

b = b/sum(b( : )); %%%%%%%%%%%%%%%%%%%%%%对系数进行归一化 (这个地方必须归一化,不然整体灰度会底) 删除括号里面的空格
I=double(src);
img=conv2(I,b,‘same’); %%%%%%%%%%%%图像与高斯滤波模版卷积,输出与输入图像大小相同的图像
d=uint8(img); %%%%%%%%%%转为无符号整型,用来显示

end

function nedge=connect(nedge,y,x,low) %种子定位后的连通分析
neighbour=[-1 -1;-1 0;-1 1;0 -1;0 1;1 -1;1 0;1 1]; %八连通搜寻
[m n]=size(nedge);
for k=1:8
yy=y+neighbour(k,1);
xx=x+neighbour(k,2);
if yy>=1 &&yy<=m &&xx>=1 && xx<=n
if nedge(yy,xx)>=low && nedge(yy,xx)~=255 %判断下阈值
nedge(yy,xx)=255;
nedge=connect(nedge,yy,xx,low);
end
end
end

end

function d=avefilt(x,n)
a(1:n,1:n)=1; %a即n×n模板,元素全是1
p=size(x); %输入图像是p×q的,且p>n,q>n
x1=double(x);
x2=x1;
%A(a:b,c:d)表示A矩阵的第a到b行,第c到d列的所有元素
for i=1:p(1)-n+1
for j=1:p(2)-n+1
c=x1(i:i+(n-1),j:j+(n-1)).a; %取出x1中从(i,j)开始的n行n列元素与模板相乘
s=sum(sum©); %求c矩阵(即模板)中各元素之和
x2(i+(n-1)/2,j+(n-1)/2)=s/(n
n); %将模板各元素的均值赋给模板中心位置的元素
end
end
% %未被赋值的元素取原值
d=uint8(x2);
end

运行结果

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值