Brent Vaalburg
Brent Vaalburg

Reputation: 119

Matlab Image Blob Detection Using Recursive Flood Fill

I am trying to do blob detection in Matlab. How can I get rid of my infinite recursion in flood_fill().

%Input Image
blobs = im2bw(imread('Week6Image.jpg'),0.1);

disp(blobs);

[W, H] = size(blobs);

region_labeling(blobs,W,H)



function region_labeling(I,W,H)

label = 2;

for u = 1 : W
    %For loop vertical Axis
    for v = 1 : H
        if I(u,v) == 1
            flood_fill(I,u,v,label,W,H);
            label = label + 1;
        end
    end

end

end

It gets stuck in this function due to infinite recursion. What should I do so that it breaks out at the right time.

function flood_fill(I,u,v,label,W,H)

if u >= 1 && u < W && v >= 1 && v < H && I(u,v) == 1
    I(u,v) = label;
    flood_fill(I,u+1,v,label,W,H);
    flood_fill(I,u,v+1,label,W,H);
    flood_fill(I,u,v-1,label,W,H);
    flood_fill(I,u-1,v,label,W,H);


end
end

Upvotes: 0

Views: 536

Answers (1)

Cris Luengo
Cris Luengo

Reputation: 60494

I see the problem now: you are passing I into the function, but not getting the modifications back. MATLAB passes all arguments by value (with the exception of handle classes). This means that a function can change its input arguments without changing the value of those matrices in the caller's workspace. You need to modify the flood_fill function to return I.

The other issue is that blobs is a logical array, and assigning any non-zero value to it yields a value of 1. You need to cast it to some other type, either doubles with +blobs or a specific integer type as below.

This is the corrected code:

blobs = im2bw(imread('Week6Image.jpg'),0.1);
blobs = uint16(blobs); % or uint32 if you have many regions
[W, H] = size(blobs);
out = region_labeling(blobs,W,H);

function I = region_labeling(I,W,H)
label = 2;
for u = 1 : W
   %For loop vertical Axis
   for v = 1 : H
      if I(u,v) == 1
         I = flood_fill(I,u,v,label,W,H);
         label = label + 1;
      end
   end
end
end

function I = flood_fill(I,u,v,label,W,H)
if u >= 1 && u <= W && v >= 1 && v <= H && I(u,v) == 1
   I(u,v) = label;
   I = flood_fill(I,u+1,v,label,W,H);
   I = flood_fill(I,u,v+1,label,W,H);
   I = flood_fill(I,u,v-1,label,W,H);
   I = flood_fill(I,u-1,v,label,W,H);
end
end

Note also that it is beneficial, in a double loop, to have the fastest-changing index be the inner loop. MATLAB is column-major, so in I(u,v), u is the fastest-changing index. Thus, ideally you would swap the two for loops around. But, given that this is such a slow algorithm and that MATLAB is not so efficient with recursion, you will likely not see the difference in this particular piece of code.

Upvotes: 2

Related Questions