检测图像中的漫画对话泡泡区域
我有一个带有几个对话泡泡(=语音聊天室等)的漫画页面的灰度图像,它们是带有白色背景的封闭区域和包含文本的纯黑色边框,即类似的东西:
我想检测这些区域并创建一个掩码(二进制就可以),它将覆盖对话气泡的所有内部区域,例如:
相同的图像,掩码覆盖,要完全清楚:
所以,我对算法的基本概念是这样的:
使用填充或某种图形遍历,从在步骤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++