Rosenfeld细化算法 matlab(速度超慢)

其中Rosenfeld细化算法为并行算法,可以将图像进行分割计算

clear
clc
close all
tic;
img = rgb2gray(imread('3.png'));
bw = imbinarize(img);%注意二值化后应使得白色为前景,黑色为背景
figure;
imshow(bw)
toc;

[m,n] = size(bw);
% 矩阵边界往外扩充一个像素
bw1 = zeros(m+2,n+2);
bw1(2:m+1,2:n+1) =bw;
bw1(1,:) = bw1(2,:);
bw1(end,:) = bw1(end-1,:);
bw1(:,1) = bw1(:,2);
bw1(:,end) = bw1(:,end-1);
figure;
imshow(bwskel(logical(bw1)));
title('骨架化,距离变换(matlab自带细化算法)')

temp1=zeros(size(bw1));%初始化temp1
bw2=bw1; %初始化图像保留模板
mm=[2 8 4 6];%4个方向
while sum(sum(bw1 - temp1)) ~=0  %没有变化的点(没有删除点),则退出循环
    temp1 =bw1; % temp1用于判断是否不再有可删除的点
    for q =1:4 %遍历4个边界
        for i =2:m+1 %遍历所有行
            for j = 2:n+1 %遍历所有列
                if bw2(i,j) ~= 0 %该像素点是否为前景点
                    temp = linyu(bw2,i,j);%获取8邻域
                    if temp(mm(q))==0 && duandian(temp)==1 && simple8(temp)==1 
                        %其中如果在判断边缘点时,将4个方向边界同时判断,则会出现断线,需要分成4次方向
                         bw1(i,j) =0;
                    end
                end 
            end
        end
        bw2=bw1;%放在这里,表示每次只变化一个方向的一层边界,并进行保留,放在4个边界循环的外边,等同于4个方向边界同时判断
    end
end
toc;
figure ;
imshow(bw1)
title('Rosenfeld细化算法结果')

%% 需单独建一个simple8.m
function [d] =simple8(temp)%输入为1*9的序列
%判断8simple ,将temp(i,j)置为0,不改变领域中8个像素点之间的连通性。
%其中temp(i,j)0时,所有8邻域有值像素点能够保持一个8连通
%则temp(i,j)值从1置为0后则不会影响8邻域像素点的8连通性。
temp(5)=0;
temp = reshape(temp,3,3);
CC1  = bwconncomp(temp,4);
if CC1.NumObjects == 1
    d=1;%是8simple 删除不影响结构
else
    d=0;
end
end
%% 需单独建一个linyu.m
function [a] = linyu(temp,i,j)%获取temp矩阵 i行j列像素点的8邻域
a=[];%a为返回的1*9序列 ,顺序为 先第一行 1 2 3列,在第二行 1 2 3for m =-1:1:1
    for n =-1:1:1
       a = [a temp(i+m,j+n) ];
    end
end
end
%% 需单独建一个duandian.m
function[c] = duandian(temp)%输入为1*9的序列
if sum(temp)<=2
    c=0;%表示为端点或者孤立点 不能删除
else
    c=1;%c=0表示不是端点也是孤立点,可以删除
end
end

图片: Rosenfeld细化算法 matlab(速度超慢)_第1张图片

你可能感兴趣的:(matlab)