python opencv图像识别_使用python和opencv检测图像中的文本区域

有多种方法可以检测图像中的文本.

我建议查看this question here,因为它也可以回答你的情况.虽然它不在python中,但是代码可以很容易地从c转换为python(只需看看API并将方法从c转换为python,而不是很难.当我为自己的单独问题尝试代码时,我自己做了) .这里的解决方案可能不适用于您的情况,但我建议您尝试使用它们.

如果我要解决这个问题,我会做以下过程:

准备你的形象:

如果您要编辑的所有图像与您提供的图像大致相同,则实际设计包含一系列灰色,文本始终为黑色.我会先将所有非黑色(或已经是白色)的内容变白.这样做只会留下黑色文字.

# must import if working with opencv in python

import numpy as np

import cv2

# removes pixels in image that are between the range of

# [lower_val,upper_val]

def remove_gray(img,lower_val,upper_val):

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

lower_bound = np.array([0,0,lower_val])

upper_bound = np.array([255,255,upper_val])

mask = cv2.inRange(gray, lower_bound, upper_bound)

return cv2.bitwise_and(gray, gray, mask = mask)

现在你所拥有的只是黑色文本,目标是获得那些盒子.如前所述,有不同的方法可以解决这个问题.

笔画宽度变换(SWT)

查找文本区域的典型方法:您可以使用描边宽度变换找到文本区域,如Boris Epshtein,Eyal Ofek和Yonatan Wexler所描述的“Detecting Text in Natural Scenes with Stroke Width Transform “所示.说实话,如果这和我认为的一样快,可靠,那么这种方法比我的代码更有效.您仍然可以使用上面的代码来删除蓝图设计,这可能有助于swt算法的整体性能.

Here is a c library实现了他们的算法,但据说这是非常原始的,并且文档说明是不完整的.显然,为了将这个库与python一起使用,将需要一个包装器,目前我还没有看到提供的官方库.

我链接的库是CCV.它是一个用于应用程序的库,而不是重新创建的算法.因此,这是一个可以使用的工具,这违背了OP希望从“第一原则”制定它,如评论中所述.如果您不想自己编写算法代码,仍然有用,知道它存在.

家庭酿造的非SWT方法

如果你有每个图像的元数据,比如在xml文件中,它说明每个图像中标记了多少个房间,那么你可以访问该xml文件,获取有关图像中标签数量的数据,然后存储一些变量中的数字,例如num_of_labels.现在拍摄您的图像,然后通过一个以您指定的设定速率侵蚀的while循环,在每个循环中查找图像中的外部轮廓,并在您拥有与num_of_labels相同数量的外部轮廓时停止循环.然后只需找到每个轮廓的边界框,就完成了.

# erodes image based on given kernel size (erosion = expands black areas)

def erode( img, kern_size = 3 ):

retval, img = cv2.threshold(img, 254.0, 255.0, cv2.THRESH_BINARY) # threshold to deal with only black and white.

kern = np.ones((kern_size,kern_size),np.uint8) # make a kernel for erosion based on given kernel size.

eroded = cv2.erode(img, kern, 1) # erode your image to blobbify black areas

y,x = eroded.shape # get shape of image to make a white boarder around image of 1px, to avoid problems with find contours.

return cv2.rectangle(eroded, (0,0), (x,y), (255,255,255), 1)

# finds contours of eroded image

def prep( img, kern_size = 3 ):

img = erode( img, kern_size )

retval, img = cv2.threshold(img, 200.0, 255.0, cv2.THRESH_BINARY_INV) # invert colors for findContours

return cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # Find Contours of Image

# given img & number of desired blobs, returns contours of blobs.

def blobbify(img, num_of_labels, kern_size = 3, dilation_rate = 10):

prep_img, contours, hierarchy = prep( img.copy(), kern_size ) # dilate img and check current contour count.

while len(contours) > num_of_labels:

kern_size += dilation_rate # add dilation_rate to kern_size to increase the blob. Remember kern_size must always be odd.

previous = (prep_img, contours, hierarchy)

processed_img, contours, hierarchy = prep( img.copy(), kern_size ) # dilate img and check current contour count, again.

if len(contours) < num_of_labels:

return (processed_img, contours, hierarchy)

else:

return previous

# finds bounding boxes of all contours

def bounding_box(contours):

bBox = []

for curve in contours:

box = cv2.boundingRect(curve)

bBox.append(box)

return bBox

来自上述方法的结果框将在标签周围具有空间,并且如果框被应用于原始图像,则这可以包括原始设计的一部分.为了避免这种情况,可以通过新发现的盒子制作感兴趣的区域并修剪空白区域.然后保存那个roi的形状作为你的新盒子.

也许你无法知道图像中会有多少标签.如果是这种情况,那么我建议您使用侵蚀值,直到找到最适合您的情况并获得所需的斑点.

或者,您可以在删除设计后尝试在剩余内容上找到轮廓,并根据它们彼此的距离将边界框组合成一个矩形.

找到盒子后,只需使用相对于原始图像的盒子即可完成.

OpenCV 3中的场景文本检测模块

正如您对问题的评论中所提到的,在opencv 3中已经存在场景文本检测(而不是文档文本检测)的方法.我知道您无法切换版本,但对于那些具有相同问题且不受限制的人对于较旧的opencv版本,我决定将其包含在最后.可以通过简单的谷歌搜索找到场景文本检测的文档.

用于文本检测的opencv模块还带有实现tessaract的文本识别功能,tessaract是一个免费的开源文本识别模块. tessaract的垮台,以及opencv的场景文本识别模块,它不像商业应用程序那样精致,使用起来很耗时.因此降低了它的性能,但是它可以免费使用,所以它是我们在没有付钱的情况下获得的最好的,如果你想要文本识别的话.

链接:

老实说,我缺乏opencv和图像处理方面的经验和专业知识,以便提供实现文本检测模块的详细方法.与SWT算法相同.在过去的几个月里,我刚刚介绍了这些内容,但随着我的了解,我将编辑这个答案.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值