Существует возможный подход, который не очень далек от того, что вы пытались. Предположим, фоновым пикселям назначена метка 0, а объектным пикселям присвоено значение 1.
сканирование изображения строка за строкой;
когда вы встретите пиксель 1, установите новую метку и выполните операцию заливки, заменив 1 новой меткой.
Заполнение потока может быть реализовано очень просто:
https://en.wikipedia.org/wiki/Flood_fill
Код этой версии довольно прост. Но вы заметите, что он может легко переполнить стек, потому что количество ожидающих заливок может достигать размера изображения.
def FloodFill(X, Y, Label):
I[X,Y]= Label
for all 8-way neighbors (X'=X±1, Y'=Y±1, inside image):
if I[X',Y'] == 1:
FloodFill(X', Y', Label)
def CCL(Image I):
Label= 1
for Y in range(I.Height):
for X in range(I.Width):
if I[X, Y] == 1:
Label+= 1
FloodFill(X, Y, Label)
Поэтому я бы порекомендовал версию scanline, которая немного сложнее.
https://en.wikipedia.org/wiki/Flood_fill#Scanline_fill