2015-12-18 24 views
11

我有一個包含幾個對話泡泡(=語音泡泡等)的漫畫頁面的灰度圖像,它們是帶有白色背景的封閉區域和包含文本的純黑色邊框,即這樣的事情:檢測圖像中的漫畫對話泡泡區域

Sample comic strip image

我要檢測這些區域,並創建一個掩碼(二進制是確定),將覆蓋對話氣泡,即像所有的內部地區:

Sample resulting mask image

相同的圖像,面膜覆蓋,是完全清楚的:

Sample image with transparent mask overlay

所以,我該算法的基本思路是這樣的:

  1. 檢測其中的文本 - 植物在每個氣泡中至少有一個像素。稍微擴大這些地區並採用門檻來獲得更好的起點;我已經做了這部分:

Text positions outlined

  • 使用傾倒填充或某種圖遍歷的,從檢測爲像素內的每個白色像素開始步驟1中的泡泡,但在初始圖像上工作時,泛白像素(應該在泡泡內)並停止在暗像素(應該是邊框或文本)上。

  • 使用某種binary_closing操作刪除氣泡中的黑色區域(即與文本對應的區域)。這部分工作正常。

  • 到目前爲止,步驟1和3的工作,但我第2步。我目前正在scikit-image工作的掙扎,我沒有看到任何現成的算法,如實施有顏色填充。很顯然,我可以使用像普遍優先遍歷這樣的小事,基本上是as suggested here,但是在Python中完成時確實很慢。我懷疑在ndimage或scikit-image中有複雜的形態,如binary_erosiongenerate_binary_structure,但我很難理解所有這些形態學術語,基本上我該如何實現這樣的自定義填充(即從第1步圖像開始,圖像併產生輸出以分離輸出圖像)。

    我接受任何建議,包括那些在OpenCV中,等

    +0

    由於這些白色背景(在文字氣泡內)是連續的,您是否嘗試過連接的組件? –

    +0

    連接組件標籤是我以後喜歡使用的*,即在生成的掩碼中枚舉特定的氣泡。我沒有看到在原始圖像上使用它的很多觀點。 – GreyCat

    +0

    洪水填充和連接組件標籤與這些圖像密切相關。如果氣泡周圍的邊緣被關閉,或者可以關閉,這應該給你一個相當不錯的初步估計。特別是因爲你可以測量這些區域的屬性,例如它們的正方形等。 –

    回答

    1

    雖然您的總體任務目標的更多,你的實際問題是關於你的第2步,如何實現對數據集洪水填充算法它已經檢測到氣泡中的文字。因爲你不提供源代碼,所以我必須從頭開始創建一些東西,希望能夠與步驟1中的輸出很好地接合。爲此,我只需要2個固定的座標,就可以將白點靠近創建的blob中心您在步驟1中提取的文本。只要您提供了正確的代碼,就可以調整該界面。

    我冒昧地填補了您找到的字母所產生的所有內部漏洞,如果您不想要,可以跳過第36行的代碼。

    對於這個解決方案,我實際上是從兩段代碼中獲得了一些想法,我在下面的剪輯中引用了這些代碼。您可以在那裏找到更多有用的信息。

    讓我們發佈您的進度!

    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

    即使你的實際問題是關於您的處理管道的第2步,我想建議另一種方法,這可能是,恕我直言,更簡單,因爲你說你是開放的建議。

    1. 使用原始步驟1中的圖像可以在氣泡中創建沒有文字的圖像。

      實施

    2. 移除文本在原始圖像上檢測邊緣。這應該適用於泡泡,因爲泡泡的邊緣非常明顯。

      邊緣檢測

    3. 最後利用邊緣圖像和最初檢測到「文本位置」,以便找到包含文本的邊緣圖像內的區域。

      Watershed-Segmentation

    我很抱歉這很普遍的答案,但在這裏,一切都太遲了,我實際的編碼,但如果這個問題仍然是開放的,你需要/想一些有關更多的提示我的建議,我會更詳細地闡述它。但你絕對可以看看scikit-image文檔中的Region based segmentation