Skip to content

Instantly share code, notes, and snippets.

@fesor
Created February 23, 2014 22:46
Show Gist options
  • Save fesor/9178450 to your computer and use it in GitHub Desktop.
Save fesor/9178450 to your computer and use it in GitHub Desktop.
Breadth First Search optimisation of recursive connected components labeling algorithm
import Image
import Queue
def select_label(used):
"""
:type used: set
:return: int
"""
prev = 0
for label in used:
if label-1 is not prev:
used.add(prev+1)
return prev+1
else:
prev = label
if prev+1 not in used:
used.add(prev+1)
return prev+1
def __fill(data, labels, size, q, args):
i, label = args
width, height = size
col, row = i % width, int(i / height) + 1
if data[i] is 0 or labels[i] is not 0:
return False
labels[i] = label
if col > 0:
q.put((i-1, label))
if col < width - 1:
q.put((i+1, label))
if row > 0:
q.put((i-width, label))
if row < height - 1:
q.put((i+width, label))
return True
def recursive_labeling(bin_img):
"""
:type bin_img: Image.Image
:return: Image.Image
"""
#Breadth First Search optimisation
q = Queue.Queue()
l_img = Image.new('L', bin_img.size)
data = list(bin_img.getdata())
labels = list(l_img.getdata())
used_labels = set()
l = select_label(used_labels)
for i in xrange(len(data)-1):
if __fill(data, labels, bin_img.size, q, (i, l)):
l = select_label(used_labels)
while not q.empty():
args = q.get()
__fill(data, labels, bin_img.size, q, args)
l_img.putdata(labels)
return l_img
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment