检测图像中的漫画对话泡泡区域

我有一个带有几个对话泡泡(=语音聊天室等)的漫画页面的灰度图像,它们是带有白色背景的封闭区域和包含文本的纯黑色边框,即类似的东西:

样本漫画图像

我想检测这些区域并创建一个掩码(二进制就可以),它将覆盖对话气泡的所有内部区域,例如:

相同的图像,掩码覆盖,要完全清楚:

具有透明遮罩覆盖图的示例图像

所以,我对算法的基本概念是这样的:

  • 检测文本的位置 - 在每个气泡中至少放置一个像素。 稍微扩大这些地区并采用门槛来获得更好的起点; 我已经完成了这部分:
  • 使用填充或某种图形遍历,从在步骤1中作为像素内部像素检测到的每个白色像素开始,但是在初始图像上工作,淹没白色像素(应该在泡泡内)并停止暗像素(应该是边框或文字)。

  • 使用某种binary_closing操作去除气泡内的黑色区域(即与文本对应的区域)。 这部分工作正常。

  • 到目前为止,第1步和第3步都可以工作,但是我正在为第2步努力工作。目前我正在使用scikit-image,并且我没有看到任何现成的算法,例如在那里实现的填充填充。 显然,我可以使用一些像普遍优先遍历这样的小事,基本上就像这里提到的那样,但是在Python中完成时确实很慢。 我怀疑像ndimage或scikit-image中的binary_erosion或generate_binary_structure这样复杂的形态学东西,但我很难理解所有这些形态学术语,并且基本上我该如何实现这样的自定义填充填充(即从第1步图像开始,处理原始图像图像并产生输出以分离输出图像)。

    我愿意接受任何建议,包括OpenCV中的建议等。


    即使您的实际问题涉及您的处理流程的第2步,我想提出另一种方法,可能是imho,更简单,并且您声明您愿意接受建议。

  • 使用原始步骤1中的图像,可以在气泡中创建没有文字的图像。

    实施

  • 删除文字,检测原始图像上的边缘。 这应该适用于泡泡,因为泡泡的边缘非常明显。

    边缘检测

  • 最后使用边缘图像和最初检测到的“文本位置”,以便在边缘图像中找到包含文本的区域。

    分水岭分割

  • 对于这个非常普遍的答案,我很抱歉,但是现在为我编写实际的代码为时已晚,但如果问题仍然存在,并且您需要/希望得到关于我的建议的更多提示,我会详细阐述它。 但你绝对可以看看scikit-image文档中基于区域的分割。


    虽然您的整体任务的目标是进一步,但您的实际问题是关于您的第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)
    
    链接地址: http://www.djcxy.com/p/61071.html

    上一篇: Detecting comic strip dialogue bubble regions in images

    下一篇: c++