问题
I am trying to implement the two pass CCL algorithm in MATLAB without using the union-find data structure, here's my code:
clear;
clc;
original_image = [ ...
0 0 0 0 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 1 0
0 0 0 0 1 0 0 1 1 0
0 0 0 0 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0];
original_image = im2bw(original_image);
[image_height, image_width] = size(original_image);
bigger_image = zeros(size(original_image) + 2);
bigger_image(2:image_height + 1, 2:image_width + 1) = original_image;
[bigger_image_height, bigger_image_width] = size(bigger_image);
labeled_image_4 = zeros(size(bigger_image));
ref = bwlabel(original_image);
counter = 1;
equivalency_list = [ ];
% 4-connectivity
for i = bigger_image_height - image_height:bigger_image_height - 1
for j = bigger_image_width - image_height:bigger_image_width - 1
if (bigger_image(i, j) == 1)
left = labeled_image_4(i, j - 1);
top = labeled_image_4(i - 1, j);
if (left == 0 && top == 0) % create new label.
labeled_image_4(i, j) = counter;
counter = counter + 1;
end
if (left >= 1 && top == 0) % assign left to pixe.
labeled_image_4(i, j) = left;
end
if (left == 0 && top >= 1) % assign top to pixel.
labeled_image_4(i, j) = top;
end
if (left >= 1 && top >= 1)
labeled_image_4(i, j) = min(left, top);
end
end
end
end
%4-conn second scan
for i = bigger_image_height - image_height:bigger_image_height - 1
for j = bigger_image_width - image_height:bigger_image_width - 1
% go through the pixels one by one.
% if we see 0 (background-pixel) then skip.
if (labeled_image_4(i, j) >= 1)
% get 4-neighbors of the current pixel. (left, top, right, bottom)
u = [labeled_image_4(i, j - 1), labeled_image_4(i - 1, j), labeled_image_4(i, j + 1), labeled_image_4(i + 1, j)];
% if neighbors are 0 / hold the same label as the current label then skip (negate what i said is written in if)
if (find(u(u >= 1))) % if neighbors are not zeros and 1s
% let us say we hold a specific label. What we do is check its 4-neighbors for the smallest value
smallest_neighbor = min(u(u ~= 0)); % get non zero smallest
% get the current label
current_label = labeled_image_4(i, j);
% Search the whole picture again for the current label and if we encounter the current label change it with smallest_neighbor
for m = bigger_image_height - image_height:bigger_image_height - 1
for n = bigger_image_width - image_width:bigger_image_width - 1
if (labeled_image_4(m, n) == current_label)
labeled_image_4(m, n) = smallest_neighbor;
end
end
end
end
end
end
end
unq_4 = unique(labeled_image_4(labeled_image_4 > 0));
size(unq_4, 1)
labeled_image_8 = zeros(size(bigger_image));
counter = 1;
% 8-connectivity
for i = bigger_image_height - image_height:bigger_image_height - 1
for j = bigger_image_width - image_width:bigger_image_width - 1
if (bigger_image(i, j) == 1)
left = labeled_image_8(i, j - 1);
top = labeled_image_8(i - 1, j);
top_left = labeled_image_8(i - 1, j - 1);
top_right = labeled_image_8(i - 1, j + 1);
a = [left, top, top_left, top_right];
if (nnz(a) == 0) % assign new label. if all are zero
labeled_image_8(i, j) = counter;
counter = counter + 1;
end
if (nnz(a) == 1)
x = find(a);
labeled_image_8(i, j) = a(x);
end
if (nnz(a) > 1)
b = a(a ~= 0);
c = sort(b);
labeled_image_8(i, j) = c(1);
end
end
end
end
% 8-conn second scan
for i = bigger_image_height - image_height:bigger_image_height - 1
for j = bigger_image_width - image_height:bigger_image_width - 1
% go through the pixels one by one.
% if we see 0 (background-pixel) then skip.
if (labeled_image_8(i, j) >= 1)
% get 8-neighbors of the current pixel. (top-left, top, top-right, left, right, bottom-left, bottom, bottom-right)
u = [labeled_image_8(i - 1, j - 1), labeled_image_8(i - 1, j), labeled_image_8(i + 1, j + 1), labeled_image_8(i, j - 1), labeled_image_8(i, j + 1), labeled_image_8(i + 1, j - 1), labeled_image_8(i + 1, j), labeled_image_8(i + 1, j + 1)];
% if neighbors are 0 / hold the same label as the current label then skip (negate what i said is written in if)
if (find(u(u >= 1))) % if neighbors are not zeros and 1s
% let us say we hold a specific label. What we do is check its 8-neighbors for the smallest value
smallest_neighbor = min(u(u ~= 0)); % get non zero smallest
% get the current label
current_label = labeled_image_8(i, j);
% Search the whole picture again for the current label and if we encounter the current label change it with smallest_neighbor
for m = bigger_image_height - image_height:bigger_image_height - 1
for n = bigger_image_width - image_width:bigger_image_width - 1
if (labeled_image_8(m, n) == current_label)
labeled_image_8(m, n) = smallest_neighbor;
end
end
end
end
end
end
end
unq_8 = unique(labeled_image_8(labeled_image_8 > 0));
size(unq_8, 1)
It should calculate the number of objects for 4-connectivity and 8-connectivity, however some images are reporting incorrect numbers! Basically what I am doing is creating a bigger matrix for the original image, and placing the original image inside that bigger matrix, this way I easily calculate the left, right ... values without the need for longer if conditions.
来源:https://stackoverflow.com/questions/58890281/trying-to-implement-connected-component-labeling-in-matlab