Suppose I have a 2D matrix, with some random integers being either a 0
or a 1
. How do I flood-fill a continuous region in my array?
This algorithm can especially be used in image processing to fill a color with another color in an enclosed region like the paint-bucket tool.
Suppose my array is:
1 0 1 1 1 1 0
0 0 1 1 1 1 1
0 0 0 1 1 1 1
0 1 0 0 0 1 1
0 0 0 1 1 1 1
I want to fill the region of 1
s in the top-right corner with something else like an 8
. How do I implement this? I know the indices of any 1
in that region, and I have the indices of any one of the 1
s.
After filling with 8
s, the array should look like this:
1 0 8 8 8 8 0
0 0 8 8 8 8 8
0 0 0 8 8 8 8
0 1 0 0 0 8 8
0 0 0 8 8 8 8
I have tried the following methods:
1
, replacing it with an 8
. Clearly this didn’t work since it simply replaced all the 1
s with 8
s. Even the 1
s outside the region were converted to 8
s.1
s, and replacing with 8
s for the initial indices we are given. In short, replacing all neighbors whose values are 1
with an 8
. This also did not work since it only replaced the nearest 8 neighbors and did not fill the region as I wanted.Voila! The answer lied in recursion:
The function takes in your array as arr
, and the coordinates (or indices) of the 1
you know in the form of a tuple (x, y)
as arguments.
When using relative coordinates, we call the flood_fill function on each of them:
function flood_fill(arr, (x, y))
# check every element in the neighborhood of the element at (x, y) in arr
for x_off in -1:1
for y_off in -1:1
# put the next part in a try-catch block so that if any index
# is outside the array, we move on to the next element.
try
# if the element is a 1, change it to an 8 and call flood_fill
# on it so it fills it's neighbors
if arr[x + x_off, y + y_off] == 1
arr[x + x_off, y + y_off] = 8
flood_fill(arr, (x + x_off, y + y_off))
end
catch
continue
end
end
end
end