clear all;
close all;
%%%%%%%%%%%%%%载入图像%%%%%%%%%%%%%%
I=imread('rice','BMP');
% I=imnoise(I,'gaussian',0,0.01);
X=double(I);
[Ix,Iy]=size(X); %图像长宽
%%%%%%%%%%%%%%二级尺度%%%%%%%%%%%%%%
m=1.0;
delta=2^m;
%%%%%%%%%高斯函数X,Y方向的偏导%%%%%%%
N=20; %长度和幅度
A=-1/sqrt(2*pi);
phi_x=zeros(N,N);
phi_y=zeros(N,N);
for i=1:N %偏导
for j=1:N
x=i-(N+1)/2;
y=j-(N+1)/2;
phi_x(i,j)=A*(x/delta^2).*exp(-(x*x+y*y)/(2*delta^2));
phi_y(i,j)=A*(y/delta^2).*exp(-(x*x+y*y)/(2*delta^2));
end
end
%%%%%%%%%图象行、列卷积%%%%%%%%%%%%%%
W_x=conv2(X,phi_x,'same');
W_y=conv2(X,phi_y,'same');
%%%%%%%%%%%%求梯度%%%%%%%%%%%%%%%%%%%
Mod_G=zeros(Ix,Iy);
for i2=1:Ix
for j2=1:Iy
Mod_G(i2,j2)=sqrt(W_x(i2,j2)*W_x(i2,j2)+W_y(i2,j2)*W_y(i2,j2));
end
end
M=fix(Mod_G);
%%%%%%%%%%%%求幅角%%%%%%%%%%%%%%%%%%%
Arg=zeros(Ix,Iy);
for i3=1:Ix
for j3=1:Iy
angle=atan(W_y(i3,j3)/W_x(i3,j3))*180/pi; %求反正切
if ((W_x(i3,j3)>0)&&(W_y(i3,j3)>0)) %第一象限
angle=angle+0;
elseif ((W_x(i3,j3)<0)&&(W_y(i3,j3)>0)) %第二象限
angle=angle+180;
elseif ((W_x(i3,j3)<0)&&(W_y(i3,j3)<0)) %第三象限
angle=angle+180;
elseif ((W_x(i3,j3)>0)&&(W_y(i3,j3)<0)) %第四象限
angle=angle+360;
elseif (abs(W_y(i3,j3)/W_x(i3,j3))>100000000) %大值90度
angle=90;
elseif (abs(W_y(i3,j3)/W_x(i3,j3))==0) %零值0度
angle=0;
end
if(angle>180) %幅角限制在0-180
angle=angle-180;
end
Arg(i3,j3)=angle;
end
end
%%%%%%%%%%%%图像边界%%%%%%%%%%%%%%%%%%%%
%沿着梯度方向检测小波变换系数模的局部极大%
%%%%%%%%值点即可得到图像的边缘点%%%%%%%%%
Edge=zeros(Ix,Iy);
for i4=2:(Ix-1)
for j4=2:(Iy-1)
if ((Arg(i4,j4)>=0&&Arg(i4,j4)<=22.5))
if (Mod_G(i4,j4)>Mod_G(i4+1,j4)&&Mod_G(i4,j4)>Mod_G(i4-1,j4))%水平
Edge(i4,j4)=Mod_G(i4,j4);
end
elseif ((Arg(i4,j4)>=(90-22.5)&&Arg(i4,j4)<=(90+22.5)))
if (Mod_G(i4,j4)>Mod_G(i4,j4+1)&&Mod_G(i4,j4)>Mod_G(i4,j4-1))%45度
Edge(i4,j4)=Mod_G(i4,j4);
end
elseif ((Arg(i4,j4)>=(45-22.5)&&Arg(i4,j4)<=(45+22.5)))
if (Mod_G(i4,j4)>Mod_G(i4+1,j4+1)&&Mod_G(i4,j4)>Mod_G(i4-1,j4-1))%垂直
Edge(i4,j4)=Mod_G(i4,j4);
end
else
if (Mod_G(i4,j4)>Mod_G(i4+1,j4-1)&&Mod_G(i4,j4)>Mod_G(i4-1,j4+1))%135度
Edge(i4,j4)=Mod_G(i4,j4);
end
end
end
end
MAX_E=max(Edge(:));
if (MAX_E>0)
Edge=Edge/MAX_E; %归一化
end
%%%%%%%%%%%根据直方图获取高低阈值%%%%%%%%%%
count=0; %累计直方图统计可能是边缘点的个数
hist=zeros(1,1024);
for k1=1:Ix
for k2=1:Iy
if (Edge(k1,k2)~=0)
hist(1,M(k1,k2)+1)=hist(1,M(k1,k2)+1)+1;
count=count+1;
end
end
end
for k3=1:1024
if hist(1,k3)~=0
nmaxmag=k3;
end
end
p=0.7;
dot=ceil(p*count);
k4=1;
nedgenb=hist(1,1);
while (k4<(nmaxmag-1)&&(nedgenb<dot))
k4=k4+1;
nedgenb=nedgenb+hist(1,k4);
end
k4=k4/1000;
high=k4; %高阈值
low=0.4*high; %低阈值,一般高为低的2.5倍
%%%%%%%%%%%%边缘点判定%%%%%%%%%%%%%%%%%%
for i5=1:Ix
for j5=1:Iy
if (Edge(i5,j5)>=high) %高于高阈值一定是边缘
Edge(i5,j5)=1;
elseif (Edge(i5,j5)<=low) %低于高阈值一定是边缘
Edge(i5,j5)=0;
else %高低阈值之间判断8邻域是否高于阈值否则不是边缘
if((Edge(i5-1,j5)>high)&&(Edge(i5,j5-1)>high)&&(Edge(i5+1,j5)>=high)&&(Edge(i5,j5+1)>=high)...
&&(Edge(i5-1,j5-1)>high)&&(Edge(i5+1,j5-1)>high)&&(Edge(i5-1,j5+1)>high)&&(Edge(i5+1,j5+1)>high))
Edge(i5,j5)=1;
else
Edge(i5,j5)=0;
end
end
end
end
% high=mean2(Edge);
% for i5=1:Ix
% for j5=1:Iy
% if (Edge(i5,j5)>high)
% Edge(i5,j5)=1;
% else
% Edge(i5,j5)=0;
% end
% end
% end
%%%%%%%%%%%%%%%显示%%%%%%%%%%%%%%%%%%%%
figure(1);imshow(I);title('原图像')
figure(2);imshow(Edge);title('边缘')
% figure(1);subplot(1,2,1);imshow(I);title('原图像加噪')
% subplot(1,2,2);imshow(Edge);title('边缘')
close all;
%%%%%%%%%%%%%%载入图像%%%%%%%%%%%%%%
I=imread('rice','BMP');
% I=imnoise(I,'gaussian',0,0.01);
X=double(I);
[Ix,Iy]=size(X); %图像长宽
%%%%%%%%%%%%%%二级尺度%%%%%%%%%%%%%%
m=1.0;
delta=2^m;
%%%%%%%%%高斯函数X,Y方向的偏导%%%%%%%
N=20; %长度和幅度
A=-1/sqrt(2*pi);
phi_x=zeros(N,N);
phi_y=zeros(N,N);
for i=1:N %偏导
for j=1:N
x=i-(N+1)/2;
y=j-(N+1)/2;
phi_x(i,j)=A*(x/delta^2).*exp(-(x*x+y*y)/(2*delta^2));
phi_y(i,j)=A*(y/delta^2).*exp(-(x*x+y*y)/(2*delta^2));
end
end
%%%%%%%%%图象行、列卷积%%%%%%%%%%%%%%
W_x=conv2(X,phi_x,'same');
W_y=conv2(X,phi_y,'same');
%%%%%%%%%%%%求梯度%%%%%%%%%%%%%%%%%%%
Mod_G=zeros(Ix,Iy);
for i2=1:Ix
for j2=1:Iy
Mod_G(i2,j2)=sqrt(W_x(i2,j2)*W_x(i2,j2)+W_y(i2,j2)*W_y(i2,j2));
end
end
M=fix(Mod_G);
%%%%%%%%%%%%求幅角%%%%%%%%%%%%%%%%%%%
Arg=zeros(Ix,Iy);
for i3=1:Ix
for j3=1:Iy
angle=atan(W_y(i3,j3)/W_x(i3,j3))*180/pi; %求反正切
if ((W_x(i3,j3)>0)&&(W_y(i3,j3)>0)) %第一象限
angle=angle+0;
elseif ((W_x(i3,j3)<0)&&(W_y(i3,j3)>0)) %第二象限
angle=angle+180;
elseif ((W_x(i3,j3)<0)&&(W_y(i3,j3)<0)) %第三象限
angle=angle+180;
elseif ((W_x(i3,j3)>0)&&(W_y(i3,j3)<0)) %第四象限
angle=angle+360;
elseif (abs(W_y(i3,j3)/W_x(i3,j3))>100000000) %大值90度
angle=90;
elseif (abs(W_y(i3,j3)/W_x(i3,j3))==0) %零值0度
angle=0;
end
if(angle>180) %幅角限制在0-180
angle=angle-180;
end
Arg(i3,j3)=angle;
end
end
%%%%%%%%%%%%图像边界%%%%%%%%%%%%%%%%%%%%
%沿着梯度方向检测小波变换系数模的局部极大%
%%%%%%%%值点即可得到图像的边缘点%%%%%%%%%
Edge=zeros(Ix,Iy);
for i4=2:(Ix-1)
for j4=2:(Iy-1)
if ((Arg(i4,j4)>=0&&Arg(i4,j4)<=22.5))
if (Mod_G(i4,j4)>Mod_G(i4+1,j4)&&Mod_G(i4,j4)>Mod_G(i4-1,j4))%水平
Edge(i4,j4)=Mod_G(i4,j4);
end
elseif ((Arg(i4,j4)>=(90-22.5)&&Arg(i4,j4)<=(90+22.5)))
if (Mod_G(i4,j4)>Mod_G(i4,j4+1)&&Mod_G(i4,j4)>Mod_G(i4,j4-1))%45度
Edge(i4,j4)=Mod_G(i4,j4);
end
elseif ((Arg(i4,j4)>=(45-22.5)&&Arg(i4,j4)<=(45+22.5)))
if (Mod_G(i4,j4)>Mod_G(i4+1,j4+1)&&Mod_G(i4,j4)>Mod_G(i4-1,j4-1))%垂直
Edge(i4,j4)=Mod_G(i4,j4);
end
else
if (Mod_G(i4,j4)>Mod_G(i4+1,j4-1)&&Mod_G(i4,j4)>Mod_G(i4-1,j4+1))%135度
Edge(i4,j4)=Mod_G(i4,j4);
end
end
end
end
MAX_E=max(Edge(:));
if (MAX_E>0)
Edge=Edge/MAX_E; %归一化
end
%%%%%%%%%%%根据直方图获取高低阈值%%%%%%%%%%
count=0; %累计直方图统计可能是边缘点的个数
hist=zeros(1,1024);
for k1=1:Ix
for k2=1:Iy
if (Edge(k1,k2)~=0)
hist(1,M(k1,k2)+1)=hist(1,M(k1,k2)+1)+1;
count=count+1;
end
end
end
for k3=1:1024
if hist(1,k3)~=0
nmaxmag=k3;
end
end
p=0.7;
dot=ceil(p*count);
k4=1;
nedgenb=hist(1,1);
while (k4<(nmaxmag-1)&&(nedgenb<dot))
k4=k4+1;
nedgenb=nedgenb+hist(1,k4);
end
k4=k4/1000;
high=k4; %高阈值
low=0.4*high; %低阈值,一般高为低的2.5倍
%%%%%%%%%%%%边缘点判定%%%%%%%%%%%%%%%%%%
for i5=1:Ix
for j5=1:Iy
if (Edge(i5,j5)>=high) %高于高阈值一定是边缘
Edge(i5,j5)=1;
elseif (Edge(i5,j5)<=low) %低于高阈值一定是边缘
Edge(i5,j5)=0;
else %高低阈值之间判断8邻域是否高于阈值否则不是边缘
if((Edge(i5-1,j5)>high)&&(Edge(i5,j5-1)>high)&&(Edge(i5+1,j5)>=high)&&(Edge(i5,j5+1)>=high)...
&&(Edge(i5-1,j5-1)>high)&&(Edge(i5+1,j5-1)>high)&&(Edge(i5-1,j5+1)>high)&&(Edge(i5+1,j5+1)>high))
Edge(i5,j5)=1;
else
Edge(i5,j5)=0;
end
end
end
end
% high=mean2(Edge);
% for i5=1:Ix
% for j5=1:Iy
% if (Edge(i5,j5)>high)
% Edge(i5,j5)=1;
% else
% Edge(i5,j5)=0;
% end
% end
% end
%%%%%%%%%%%%%%%显示%%%%%%%%%%%%%%%%%%%%
figure(1);imshow(I);title('原图像')
figure(2);imshow(Edge);title('边缘')
% figure(1);subplot(1,2,1);imshow(I);title('原图像加噪')
% subplot(1,2,2);imshow(Edge);title('边缘')