图像分割——边缘检测——边缘连接的局部处理(Matlab)

%Edge linking using local processing
clc;
clear all;
close all;
%边缘连接测试图像
I=im2double(imread('D:\Gray Files\10-27.tif'));
[M,N]=size(I);
%=============================边缘检测(六)=================================
% Edge linking using local processing
%边缘连接的局部处理
%--------------------------计算图像梯度和角度------------------------------
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_pad=padarray(I,[n_l,n_l],'replicate');
for i=1:M
    for j=1:N
        Block=f_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
gx=abs(gx);
gy=abs(gy);
% M_s=sqrt(gx.^2+gy.^2);
% M_s=M_s/max(M_s(:));
a_s=atan2(gy,gx)*180/pi;
% imshow(M_s)
%-------------------------------图像二值化---------------------------------
%设置梯度门限
th=0.3;
T_max=max(gy(:));
T_M=T_max*th;
T_A=45;
%计算水平方向
Tx=zeros(M,N);
A_x=90;
for i=1:M
    for j=1:N
        if gy(i,j)>T_M
            if a_s(i,j)>=A_x-T_A && a_s(i,j)<=A_x+T_A
                Tx(i,j)=1;
            end
        end
    end
end

T_max=max(gx(:));
T_M=T_max*th;
T_A=45;
Ty=zeros(M,N);
A_y=0;
for i=1:M
    for j=1:N
        if gx(i,j)>T_M
            if a_s(i,j)>=A_y-T_A && a_s(i,j)<=A_y+T_A
                Ty(i,j)=1;
            end
        end
    end
end

%-----------------------------填充空当-------------------------------------
L=25;
%水平二值图像沿x方向进行扩展
Tx_pad=padarray(Tx,[0,L-1],'post');
Tx_g=zeros(M,N);
for i=1:M
    for j=1:N
        if Tx_pad(i,j)==1 && Tx_pad(i,j+1)==0
            Block=Tx_pad(i,j+2:j+L-1);
            ind=find(Block==1);
            if ~isempty(ind)                
                ind_Last=j+2+ind(1,length(ind))-1;
                Tx_pad(i,j:ind_Last)=1;
                Tx_g(i,j:ind_Last)=1;
            end
        else
            Tx_g(i,j)=Tx_pad(i,j);
        end
    end
end
%沿垂直方向进行填充
Ty_pad=padarray(Ty,[L-1,0],'post');
Ty_g=zeros(M,N);
for j=1:N
    for i=1:M
        if Ty_pad(i,j)==1 && Ty_pad(i+1,j)==0
            Block=Ty_pad(i+2:i+L-1,j);
            ind=find(Block==1);
            if ~isempty(ind)                
                ind_Last=i+2+ind(length(ind),1)-1;
                Ty_pad(i:ind_Last,j)=1;
                Ty_g(i:ind_Last,j)=1;
            end
        else
            Ty_g(i,j)=Ty_pad(i,j);
        end
    end
end
T_g=Ty_g+Tx_g;
[g]=ImageThinning(T_g);
imshow(g)

图像细化函数,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

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值