参考
https://en.wikipedia.org/wiki/Connected-component_labeling
http://www.mathworks.com/matlabcentral/fileexchange/45480-connected-component-labeling
This function is partly based on the two-pass algorithm, described here:
http://en.wikipedia.org/wiki/Connected-component_labeling
I did not make use of the disjoint data set structure (at least that I am aware of) to connect the linked labels.
The same functionality is available in the image processing toolbox as the function bwlabel, but this function can be useful for those who want to study the implementation of the algorithm, or those who do not have access to the toolbox.
源代码
function [ labels ] = anodeg_bwlabel( data )
%anodeg_bwlable binary image labeling
% Labels a binary image through 8-point connectivity without the need
% for any toolboxes.
[x,y] = size(data);
% expand dataset to avoid crash when searching:
data = [zeros(1,y+2);[zeros(x,1) data zeros(x,1)]];
[x,y] = size(data);
labels = zeros(size(data));
nextlabel = 1;
linked = [];
for i = 2:x % for each row
for j = 2:y-1 % for each column
if data(i,j) ~= 0 % not background
% find binary value of neighbours
neighboursearch = [data(i-1,j-1), data(i-1,j), data(i-1,j+1),data(i,j-1)];
% for 4-connectivity, replace with:
% neighboursearch = [data(i-1,j),data(i,j-1)];
% search for neighbours with binary value 1
[~,n,neighbours] = find(neighboursearch==1);
% if no neighbour is allready labeled: assign new label
if isempty(neighbours)
linked{nextlabel} = nextlabel; %#ok<*AGROW>
labels(i,j) = nextlabel;
nextlabel = nextlabel+1;
% if neighbours is labeled: pick the lowest label and store the
% connected labels in "linked"
else
neighboursearch_label = [labels(i-1,j-1), labels(i-1,j), labels(i-1,j+1),labels(i,j-1)];
L = neighboursearch_label(n);
labels(i,j) = min(L);
for k = 1:length(L)
label = L(k);
linked{label} = unique([linked{label} L]);
end
end
end
end
end
% remove the previous expansion of the image
labels = labels(2:end,2:end-1);
%% join linked areas
% for each link, look through the other links and look for common labels.
% if common labels exist they are linked -> replace both link with the
% union of the two. Repeat until there is no change in the links.
change2 = 1;
while change2 == 1
change = 0;
for i = 1:length(linked)
for j = 1:length(linked)
if i ~= j
if sum(ismember(linked{i},linked{j}))>0 && sum(ismember(linked{i},linked{j})) ~= length(linked{i})
change = 1;
linked{i} = union(linked{i},linked{j});
linked{j} = linked{i};
end
end
end
end
if change == 0
change2 = 0;
end
end
% removing redundat links
linked = unique(cellfun(@num2str,linked,'UniformOutput',false));
linked = cellfun(@str2num,linked,'UniformOutput',false);
K = length(linked);
templabels = labels;
labels = zeros(size(labels));
% label linked labels with a single label:
for k = 1:K
for l = 1:length(linked{k})
labels(templabels == linked{k}(l)) = k;
end
end
end
浙公网安备 33010602011771号