2015-12-18 29 views
11

Mam obraz w skali szarości na stronie z komiksem, który zawiera kilka dymków dialogowych (= dymki, itp.), Które są zamkniętymi obszarami z białym tłem i pełnymi czarnymi ramkami, które zawierają tekst wewnątrz, czyli coś takiego:Wykrywanie regionów bąbelków dialogowych w obrazach

Sample comic strip image

Chcę wykryć te regiony i utworzyć maskę (binarny jest ok), który obejmie wszystkie wewnątrz regionów pęcherzyków dialogu, czyli coś jak:

Sample resulting mask image

Ten sam obraz, maski nakładane, aby być całkowicie jasne:

Sample image with transparent mask overlay

Więc moja podstawowa idea algorytmu było coś takiego:

  1. Detect, gdzie tekst jest - zakład na co najmniej jeden piksel w każdej bańce. Dylatuj te regiony nieco i zastosuj próg, aby uzyskać lepszy grunt startowy; Zrobiłem tę część:

Text positions outlined

  1. Zastosowanie wypełnienie powodzi lub jakiś wykres przechodzenie, począwszy od każdego piksela białego wykrywany jako piksel wewnątrz -bubble w kroku 1, ale pracując nad początkowym obrazem, zalewając białe piksele (które powinny znajdować się wewnątrz bańki) i zatrzymując się na ciemnych pikselach (które mają być obramowaniem lub tekstem).

  2. Użyj jakiejś operacji binary_closing, aby usunąć ciemne obszary (tj. Obszary odpowiadające tekstowi) wewnątrz bąbelków). Ta część działa dobrze.

Dotychczas kroki 1 i 3 prace, ale mam zmaga się z kroku 2. Obecnie pracuję z scikit-image, a ja nie widzę żadnych gotowych algorytmów, takich jak wypełnienie przeciwpowodziowej realizowanej tam. Oczywiście, mogę użyć czegoś trywialnego, takiego jak szerokość-pierwsze przejście, w zasadzie as suggested here, ale to naprawdę powolne, gdy zrobione w Pythonie. Podejrzewam, że skomplikowane morfologie, takie jak binary_erosion lub generate_binary_structure w ndimage lub obrazie scikit, ale mam trudności ze zrozumieniem całej tej terminologii morfologicznej iw zasadzie jak mogę zaimplementować takie niestandardowe wypełnienie powodziowe (tj. Zaczynając od obrazu kroku 1, pracując nad oryginalnym obraz i wyjście do oddzielnego obrazu wyjściowego).

Jestem otwarty na wszelkie propozycje, w tym te w OpenCV itp

+0

Ponieważ te białe tło (wewnątrz bąbelków tekstu) sąsiadują ze sobą, czy próbowałeś podłączonych komponentów? –

+0

Etykietowanie podłączonych komponentów jest tym, co chciałbym użyć * później *, tj. Na wynikowej masce, aby wyliczyć konkretne bąbelki. Nie widzę sensu używać go na oryginalnym obrazie. – GreyCat

+0

Napełnianie zalewaniem i etykietowanie elementów łączonych jest bardzo ściśle związane z takimi obrazami. Jeśli krawędzie wokół bąbelków są zamknięte lub można je zamknąć, powinno to dać całkiem przyzwoite pierwsze oszacowanie. Zwłaszcza, że ​​możesz zmierzyć właściwości takich regionów, np. jak kwadratowe, itp. –

Odpowiedz

1

Choć ogólny zadanie zmierza dalej, rzeczywiste pytanie dotyczy kroku 2, jak zaimplementować algorytm wypełniania jednolitego zbioru danych który wykrył tekst w bąbelkach.

Ponieważ nie podajesz kodu źródłowego, musiałem stworzyć coś od podstaw, co, mam nadzieję, będzie dobrze pasować do twoich danych wyjściowych z kroku 1. Do tego po prostu wziąłem 2 stałe współrzędne, zabrałbyś białe punkty w pobliżu centrów kropelkowych utworzonych z tekst wyodrębniony w kroku 1. Po podaniu odpowiedniego kodu można dostosować ten interfejs.

Pozwoliłem sobie wypełnić wszystkie wewnętrzne dziury utworzone przez znalezione litery. Jeśli tego nie chcesz, możesz pominąć kod z wiersza 36.

Dla rozwiązania, które faktycznie brałem pomysły z dwóch kawałków kodu, które cytowałem w poniższym poniżej. Możesz tam znaleźć więcej przydatnych informacji.

Wysyłajcie nam wiadomości o swoich postępach!

import cv2 
import numpy as np 

# with ideas from: 
# http://www.learnopencv.com/filling-holes-in-an-image-using-opencv-python-c/ 
# http://stackoverflow.com/questions/10316057/filling-holes-inside-a-binary-object 
print cv2.__file__ 

# Read image 
im_in = cv2.imread("gIEXY.png", cv2.IMREAD_GRAYSCALE); 

# Threshold. 
# Set values equal to or above 200 to 0. 
# Set values below 200 to 255. 

th, im_th = cv2.threshold(im_in, 200, 255, cv2.THRESH_BINARY_INV); 

# Copy the thresholded image. 
im_floodfill = im_th.copy() 

# Mask used to flood filling. 
# Notice the size needs to be 2 pixels than the image. 
h, w = im_th.shape[:2] 
mask = np.zeros((h+2, w+2), np.uint8) 

# Floodfill from points inside baloons 
cv2.floodFill(im_floodfill, mask, (80,400), 128); 
cv2.floodFill(im_floodfill, mask, (610,90), 128); 

# Invert floodfilled image 
im_floodfill_inv = cv2.bitwise_not(im_floodfill) 

# Combine the two images to get the foreground 
im_out = im_th | im_floodfill_inv 

# Create binary image from segments with holes 
th, im_th2 = cv2.threshold(im_out, 130, 255, cv2.THRESH_BINARY) 

# Create contours to fill holes 
im_th3 = cv2.bitwise_not(im_th2) 
contour,hier = cv2.findContours(im_th3,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE) 

for cnt in contour: 
    cv2.drawContours(im_th3,[cnt],0,255,-1) 

segm = cv2.bitwise_not(im_th3) 


# Display image 
cv2.imshow("Original", im_in) 
cv2.imshow("Segmented", segm) 
cv2.waitKey(0) 
2

Chociaż rzeczywisty pytanie dotyczące Krok 2 z twojej rurociągu przetwarzania, chciałbym zaproponować inne podejście, które może być, imho, prostsze i jak można stwierdzić, że jesteś otwarty na sugestie.

  1. Za pomocą obrazu z oryginalnego kroku 1 można utworzyć obraz bez tekstu w bąbelkach.

    Zaimplementowane

  2. Wykrywanie krawędzi na obrazie oryginalnym z tekstem usuwanego. To powinno dobrze działać dla bąbelków mowy, ponieważ krawędzie bąbelków są dość wyraźne.

    wykrywanie krawędzi

  3. Wreszcie użyć obrazu krawędzią i początkowo wykrytych „Rozmieszczenie tekstu”, aby znaleźć te obszary w obrazie krawędzi, które zawierają tekst.

    Watershed-Segmentation

mi przykro za to bardzo ogólny odpowiedź, ale tutaj jest to zbyt późno dla rzeczywistej kodowania dla mnie, ale jeśli sprawa jest nadal otwarta i trzeba/chcę kilka wskazówek dotyczących moja sugestia, opiszę to bardziej szczegółowo. Ale możesz zdecydowanie rzucić okiem na Region based segmentation w dokumentach z obrazem scikit.