1

I have a binary image (see below) and I would like to mark all the points inside the central big spot as 1 (white). If I understood correctly, the best way to do it is to use a flood fill algorithm; is there any Python module you suggest to use? If not, how would you structure the script?

Thanks!

The image I am working with

albus_c
  • 6,292
  • 14
  • 36
  • 77
  • There are a few implementations [here](http://en.wikipedia.org/wiki/Flood_fill#The_algorithm). I can tell you from experience that the naive stack based recursive one is not efficient... – will Jan 22 '14 at 15:57
  • Thanks! What approach do you think would work best? – albus_c Jan 22 '14 at 15:58
  • It is pretty strongly implementation dependant. It would actualyl be a very good question to ask a class imo, at least if you couldn't get the answer to readily online... [here](http://www.codeproject.com/Articles/6017/QuickFill-An-efficient-flood-fill-algorithm) is a nice description of the various methods you could use. – will Jan 22 '14 at 16:04
  • Similar to [this question]( http://stackoverflow.com/questions/15283849/isolate-greatest-smallest-labeled-patches-from-numpy-array) if you try the answer with `array` being the binary image in your question – YXD Jan 22 '14 at 16:16
  • 1
    Basically it's a good idea to use `scipy.ndimage.label` – YXD Jan 22 '14 at 16:18
  • Hi, thanks for all the tips! I am trying to solve this using `ndimage.binary_fill_holes`. I opened a new thread on that at http://stackoverflow.com/questions/21291197/fill-shape-using-ndimage-binary-fill-holes – albus_c Jan 22 '14 at 18:42

2 Answers2

1

This here is a very naive approach to flood filling (using yout 0's and 1's as detailed in your question, but not reading an image, but with hardcoded data) circumnavigating the lack of TCO in python. Maybe it can give you some ideas:

#! /usr/bin/python3

d = '''111110001111101
110000011100000
111000010111001
111100100111111
111100000111111
111110111111111'''

def flood(grid, x, y):
    toBeFilled = {(x, y)}
    while toBeFilled:
        tbf = set()
        for x, y in toBeFilled:
            try:
                if grid[y][x]: continue #Pixel is already 1 -> no action
            except IndexError: continue #Index is out of bounds
            grid[y][x] = 1 #set Pixel to white
            for xoff, yoff in ((1, -1), (1, 0), (1, 1), (0, -1), (0, 1), (-1, -1), (-1, 0), (-1, 1)):
                tbf |= {(x + xoff, y + yoff)} #add adjacent pixels
        toBeFilled = tbf

def pprint(grid):
    print('-' * 20)
    for line in grid: print(''.join(str(i) for i in line))
    print('-' * 20)

d = [[int(c) for c in line] for line in d.split('\n')]
pprint(d)
flood(d, 4, 1)
pprint(d)

Output is:

--------------------
111110001111101
110000011100000
111000010111001
111100100111111
111100000111111
111110111111111
--------------------
--------------------
111111111111101
111111111100000
111111111111001
111111111111111
111111111111111
111111111111111
--------------------
Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
0

Since the input image is binary, a possible approach is a) Fill the empty points inside the blobs using ndimage.binary_fill_holes b) label the components following this example, built on scikit: http://scikit-image.org/docs/dev/auto_examples/segmentation/plot_label.html

albus_c
  • 6,292
  • 14
  • 36
  • 77