连通区域分析中常需要找出一幅图像中的连通区域,matlab自带的Belabel函数即可,在此写了一个功能相同的函数,方便以后将其移植到其他平台上,用的是Two pass算法
function [ outImg, labels ] = MyBwLabel( inputImg )
%MyBwLabel 自制的连通区域分析函数
% [ outImg, labels ] = MyBwLabel( inputImg )
% inputIg: 输入的图像,要求是二值化图像,且最大值为1
% outputImg: 输出的图像,不同的连通区域的;label不同
% labels:连通区域的个数
%
% example : a = false(400);
% a(rand(400) > 0.5) = true;
% [b , l] = MyBwLabel(a);
% imshow(b , [])
if ~islogical(inputImg)
error( '========do not support the data type!!============' )
end
labels = 1;
outImg = double( inputImg );
markFlag = false( size(inputImg) );
[height , width] = size( inputImg );
%% first pass
for ii = 1:height
for jj = 1:width
if inputImg(ii,jj) > 0 % 若是前景点,则进行统计处理
neighbors = []; % 记录符合要求的邻域中的前景点,三列依次是行、列、值
if (ii-1 > 0)
if (jj-1 > 0 && inputImg(ii-1,jj-1) > 0)
neighbors = [neighbors ; ii-1 , jj-1 , outImg(ii-1,jj-1)];
end
if inputImg(ii-1,jj) > 0
neighbors = [neighbors ; ii-1 , jj , outImg(ii-1,jj)];
end
elseif (jj-1) > 0 && inputImg(ii,jj-1) > 0
neighbors = [neighbors ; ii , jj-1 , outImg(ii,jj-1)];
end
if isempty(neighbors)
labels = labels + 1;
outImg(ii , jj) = labels;
else
outImg(ii ,jj) = min(neighbors(:,3));
end
end
end
end
%% second pass
[r , c] = find( outImg ~= 0 );
for ii = 1:length( r )
if r(ii)-1 > 0
up = r(ii)-1;
else
up = r(ii);
end
if r(ii)+1 <= height
down = r(ii)+1;
else
down = r(ii);
end
if c(ii)-1 > 0
left = c(ii)-1;
else
left = c(ii);
end
if c(ii)+1 <= width
right = c(ii)+1;
else
right = c(ii);
end
tmpM = outImg(up:down , left:right);
[r1 , c1] = find( tmpM ~= 0 );
if ~isempty(r1)
tmpM = tmpM(:);
tmpM( tmpM == 0 ) = [];
minV = min(tmpM);
tmpM( tmpM == minV ) = [];
for kk = 1:1:length(tmpM)
outImg( outImg == tmpM(kk) ) = minV;
end
end
end
u = unique(outImg);
for ii = 2:1:length(u)
outImg(outImg == u(ii)) = ii-1;
end
labels = length( u ) - 1;
end