Trying to implement Connected Component Labeling in MATLAB

泄露秘密 提交于 2020-01-25 06:39:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!