clc;
clear all;
close all;
I=im2double(imread('D:\Gray Files\10-26.tif'));
[M,N]=size(I);
%%
%=============================边缘检测(五)=================================
% Canny Edge Detector
%-------------------------用高斯低通滤波器平滑图像-------------------------
%建筑图像所设参数
% n=25;
% sigma=4;
%头颅扫描图像所设参数
n=13;
sigma=2;
%lena测试图像所设参数
% n=5;
% sigma=1;
type='symmetric';
f_s=GaussianBlur(n,I,sigma,type);
% imshow(f_s)
% imwrite(f_s,'D:\Gray Files\lena-test.jpg','jpg');
%-----------------------计算平滑后的图像梯度和角度-------------------------
n_l=1;
%Sobel算子
s_y=[-1 -2 -1;
0 0 0;
1 2 1];
s_x=[-1 0 1;
-2 0 2;
-1 0 1];
%定义梯度和角度
gx=zeros(M,N);
gy=zeros(M,N);
f_s_pad=padarray(f_s,[n_l,n_l],'replicate');
for i=1:M
for j=1:N
Block=f_s_pad(i:i+2*n_l,j:j+2*n_l);
gx(i,j)=sum(sum(Block.*s_x));
gy(i,j)=sum(sum(Block.*s_y));
end
end
type='replicate';
gx=GaussianBlur(n,gx,sigma,type);
gy=GaussianBlur(n,gy,sigma,type);
M_s=sqrt(gx.^2+gy.^2);
M_s=M_s/max(M_s(:));
a_s=atan2(gy,gx)*180/pi;
% imshow(M_s)
%-----------------------对梯度图像进行非极大值抑制-------------------------
n_l=1;
%定义非极大值抑制图像
g_N=M_s;
M_s_pad=padarray(M_s,[n_l,n_l],'replicate');
for i=1:M
for j=1:N
%取出中心点的梯度值
K=M_s_pad(i+1,j+1);
theta=a_s(i,j);
if (theta>=0 && theta<=45) ||...
(theta<-135 && theta>=-180)
yBot=[M_s_pad(i+1,j+2) M_s_pad(i+2,j+2)];
yTop=[M_s_pad(i+1,j) M_s_pad(i,j)];
k=abs(gy(i,j)/M_s_pad(i+1,j+1));
K1=(yBot(2)-yBot(1))*k+yBot(1);
K2=(yTop(2)-yTop(1))*k+yTop(1);
end
if (theta>45 && theta<=90) ||...
(theta<-90 && theta>=-135)
yBot=[M_s_pad(i+2,j+1) M_s_pad(i+2,j+2)];
yTop=[M_s_pad(i,j+1) M_s_pad(i,j)];
k=abs(gx(i,j)/M_s_pad(i+1,j+1));
K1=(yBot(2)-yBot(1))*k+yBot(1);
K2=(yTop(2)-yTop(1))*k+yTop(1);
end
if (theta>90 && theta<=135) ||...
(theta<-45 && theta>=-90)
yBot=[M_s_pad(i+2,j+1) M_s_pad(i+2,j)];
yTop=[M_s_pad(i,j+1) M_s_pad(i,j+2)];
k=abs(gx(i,j)/M_s_pad(i+1,j+1));
K1=(yBot(2)-yBot(1))*k+yBot(1);
K2=(yTop(2)-yTop(1))*k+yTop(1);
end
if (theta>135 && theta<=180) ||...
(theta<0&& theta>=-45)
yBot=[M_s_pad(i+1,j) M_s_pad(i+2,j)];
yTop=[M_s_pad(i+1,j+2) M_s_pad(i,j+2)];
k=abs(gy(i,j)/M_s_pad(i+1,j+1));
K1=(yBot(2)-yBot(1))*k+yBot(1);
K2=(yTop(2)-yTop(1))*k+yTop(1);
end
if KT_H);
g_N_pad(ind_H)=1;
ind_Zeros=find(g_N_pad
高斯模糊GaussianBlur函数:
function [g]=GaussianBlur(n,I,sigma,type)
[M,N]=size(I);
%生成高斯核函数
G=GaussianKernelG(n,sigma);
%平滑图像
n_l=n-1;
g=zeros(M,N);
%对原图进行扩展,方便处理边界
I_pad=padarray(I,[n_l,n_l],type);
for i=1:M
for j=1:N
%获得图像子块区域
Block=I_pad(i:i+n_l,j:j+n_l);
%用Kirsch内核对子区域卷积
g(i,j)=sum(sum(Block.*G));
end
end
%归一化
g=g/max(g(:));
end
%生成高斯核函数
% n 核函数的大小
function G=GaussianKernelG(n,sigma)
n_l=floor(n/2);
%初始化
G=zeros(n,n);
%产生高斯核矩阵
for i=-n_l:n_l
for j=-n_l:n_l
d=i^2+j^2;
G(i+n_l+1,j+n_l+1)=exp(-(d)/(2*sigma^2));
end
end
%寻找最小值
m=sum(G(:));
%取整
G=G/m;
%将大于3*delta的取值置零
for i=-n_l:n_l
for j=-n_l:n_l
d=sqrt(i^2+j^2);
if d>3*sigma
G(i+n_l+1,j+n_l+1)=0;
end
end
end
end
查找8连通函数,FindConnected_8:
%查找所有8连通的点
% p为中心点,ind_L为有效矩阵,Conn为连通矩阵,M为图像矩阵的行数
function [ind_L,Conn]=FindConnected_8(p,ind_L,Conn,M)
%查找p点是否有连通点,即在ind_L中是否有值
%上
c=find(ind_L==p-1);
if ~isempty(c)
Conn=cat(1,Conn,p-1);
ind_L(c)=[];
end
%下
c=find(ind_L==p+1);
if ~isempty(c)
Conn=cat(1,Conn,p+1);
ind_L(c)=[];
end
%左
c=find(ind_L==p-M);
if ~isempty(c)
Conn=cat(1,Conn,p-M);
ind_L(c)=[];
end
%左上
c=find(ind_L==p-M-1);
if ~isempty(c)
Conn=cat(1,Conn,p-M-1);
ind_L(c)=[];
end
%左下
c=find(ind_L==p-M+1);
if ~isempty(c)
Conn=cat(1,Conn,p-M+1);
ind_L(c)=[];
end
%右
c=find(ind_L==p+M);
if ~isempty(c)
Conn=cat(1,Conn,p+M);
ind_L(c)=[];
end
%右上
c=find(ind_L==p+M-1);
if ~isempty(c)
Conn=cat(1,Conn,p+M-1);
ind_L(c)=[];
end
%右下
c=find(ind_L==p+M+1);
if ~isempty(c)
Conn=cat(1,Conn,p+M+1);
ind_L(c)=[];
end
end
图像细化函数,ImageThinning如下:
%图像细化,目前只对二值图像进行处理
function [g]=ImageThinning(I)
n_l=1;
%对边界图进行扩充,四周各加1行、1列0(与结构元素的大小相对应),目的是为了处理边界点
I_pad=padarray(I,[n_l,n_l]);
%获得扩充图像大小
[M,N]=size(I_pad);
%寻找图像中的亮点,即值为1的点
ind=find(I_pad==1);
ind_c=[];
while ~isequal(ind_c,ind)
%备份赋值,以便下一次循环开始进行比较
ind_c=ind;
%保存ind中符合条件的下标
ind_sub=[];
%按照B1结构元素搜索
for i=1:length(ind)
p=ind(i,1);
if ~isempty(find(ind==p+1)) && ~isempty(find(ind==p-M+1)) && ~isempty(find(ind==p+M+1)) &&...
isempty(find(ind==p-1)) && isempty(find(ind==p-M-1)) && isempty(find(ind==p+M-1))
ind_sub=cat(1,ind_sub,i);
end
end
%将下标符合条件的数值,从ind中清除,以下类似
if ~isempty(ind_sub)
ind(ind_sub)=[];
end
ind_sub=[];
%按照B2结构元素搜索
for i=1:length(ind)
p=ind(i,1);
if ~isempty(find(ind==p+1)) && ~isempty(find(ind==p-M)) && ~isempty(find(ind==p-M+1)) &&...
isempty(find(ind==p-1)) && isempty(find(ind==p+M)) && isempty(find(ind==p+M-1))
ind_sub=cat(1,ind_sub,i);
end
end
if ~isempty(ind_sub)
ind(ind_sub)=[];
end
ind_sub=[];
%按照B3结构元素搜索
for i=1:length(ind)
p=ind(i,1);
if ~isempty(find(ind==p-M-1)) && ~isempty(find(ind==p-M)) && ~isempty(find(ind==p-M+1)) &&...
isempty(find(ind==p+M-1)) && isempty(find(ind==p+M)) && isempty(find(ind==p+M+1))
ind_sub=cat(1,ind_sub,i);
end
end
if ~isempty(ind_sub)
ind(ind_sub)=[];
end
ind_sub=[];
%按照B4结构元素搜索
for i=1:length(ind)
p=ind(i,1);
if ~isempty(find(ind==p-1)) && ~isempty(find(ind==p-M)) && ~isempty(find(ind==p-M-1)) &&...
isempty(find(ind==p+1)) && isempty(find(ind==p+M)) && isempty(find(ind==p+M+1))
ind_sub=cat(1,ind_sub,i);
end
end
if ~isempty(ind_sub)
ind(ind_sub)=[];
end
ind_sub=[];
%按照B5结构元素搜索
for i=1:length(ind)
p=ind(i,1);
if ~isempty(find(ind==p-M-1)) && ~isempty(find(ind==p-1)) && ~isempty(find(ind==p+M-1)) &&...
isempty(find(ind==p-M+1)) && isempty(find(ind==p+1)) && isempty(find(ind==p+M+1))
ind_sub=cat(1,ind_sub,i);
end
end
if ~isempty(ind_sub)
ind(ind_sub)=[];
end
ind_sub=[];
%按照B6结构元素搜索
for i=1:length(ind)
p=ind(i,1);
if ~isempty(find(ind==p-1)) && ~isempty(find(ind==p+M-1)) && ~isempty(find(ind==p+M)) &&...
isempty(find(ind==p+1)) && isempty(find(ind==p-M+1)) && isempty(find(ind==p-M))
ind_sub=cat(1,ind_sub,i);
end
end
if ~isempty(ind_sub)
ind(ind_sub)=[];
end
ind_sub=[];
%按照B7结构元素搜索
for i=1:length(ind)
p=ind(i,1);
if ~isempty(find(ind==p+M-1)) && ~isempty(find(ind==p+M)) && ~isempty(find(ind==p+M+1)) &&...
isempty(find(ind==p-M-1)) && isempty(find(ind==p-M)) && isempty(find(ind==p-M+1))
ind_sub=cat(1,ind_sub,i);
end
end
if ~isempty(ind_sub)
ind(ind_sub)=[];
end
ind_sub=[];
%按照B8结构元素搜索
for i=1:length(ind)
p=ind(i,1);
if ~isempty(find(ind==p+1)) && ~isempty(find(ind==p+M)) && ~isempty(find(ind==p+M+1)) &&...
isempty(find(ind==p-1)) && isempty(find(ind==p-M)) && isempty(find(ind==p-M-1))
ind_sub=cat(1,ind_sub,i);
end
end
if ~isempty(ind_sub)
ind(ind_sub)=[];
end
end
%m连通检测
ind_c=[];
while ~isequal(ind_c,ind)
ind_c=ind;
ind_back=ind;
while ~isempty(ind_back)
p=ind_back(1,:);
%如果p点四联通中有三个值为1,则将该点置为零
if (~isempty(find(ind==p+1)) && ~isempty(find(ind==p+M)) && ~isempty(find(ind==p-M))) ||...
(~isempty(find(ind==p-1)) && ~isempty(find(ind==p+M)) && ~isempty(find(ind==p-M))) ||...
(~isempty(find(ind==p+1)) && ~isempty(find(ind==p-1)) && ~isempty(find(ind==p-M))) ||...
(~isempty(find(ind==p+1)) && ~isempty(find(ind==p-1)) && ~isempty(find(ind==p+M)))
c=find(ind==p);
ind(c)=[];
end
%如果p点四联通中有两个值为1,且其对角为0,则将该点置为零
if (~isempty(find(ind==p+1)) && ~isempty(find(ind==p+M)) && isempty(find(ind==p-M-1))) ||...
(~isempty(find(ind==p-1)) && ~isempty(find(ind==p+M)) && isempty(find(ind==p-M+1))) ||...
(~isempty(find(ind==p+1)) && ~isempty(find(ind==p-M)) && isempty(find(ind==p+M-1))) ||...
(~isempty(find(ind==p-1)) && ~isempty(find(ind==p-M)) && isempty(find(ind==p+M+1)))
c=find(ind==p);
ind(c)=[];
end
ind_back(1,:)=[];
end
end
%删除扩展的边缘
g=zeros(size(I_pad));
g(ind)=1;
g=g(2:M-1,2:N-1);
end