我正在尝试使用 OpenCV (3.0) 和 Python 检测图像中的文本区域。到目前为止,我能够检测单个文本字符并在它们周围绘制边界框或矩形。我的最终目标是将单个文本字符合并到单词/文本行中,并最终合并到文本块或段落中。
我的方法是找到相邻的文本区域,然后在这些区域周围形成一个边界框。因此,在我的代码中,我稍微扩展了每个文本字符周围的边界框或矩形,以便它们彼此重叠,形成一串重叠的边界框。(请参考图片)。现在,我想根据所有边界框对之间的重叠率合并这些重叠的矩形以形成单个边界框。
我很难弄清楚如何将重叠的矩形合并为一个。在过去的 24 小时里,我尝试了不同的技术,但没有成功。其中有cv2.groupRectangles。我认为我们需要 cv2.cascade.detectMultiScale() 返回的矩形数组(即 rectList);我们还需要 haar 级联来检测图像中的对象(即在我们的例子中为矩形),并且“数据文件夹”中有许多 haar 级联,我很困惑在我的例子中使用哪一个(检测矩形)。
如果 cv2.groupRectangles 不适用于我的情况,那么我想知道什么可能是其他选项。如果您也遇到过类似的问题,欢迎分享。
这是我的工作Python代码
import numpy as np
import cv2
im = cv2.imread('headintext.png')
grayImage = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
# grayImage = cv2.imread('gates.jpg', cv2.IMREAD_GRAYSCALE)
# cv2.imwrite('gates.png', grayImage)
# cv2.imshow('image', grayImage)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
_,thresh = cv2.threshold(grayImage, 150, 255, cv2.THRESH_BINARY_INV)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
dilated = cv2.dilate(thresh, kernel, iterations = 1) # dilate
_,contours0,_ = cv2.findContours(dilated,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) # get contours
contours = [cv2.approxPolyDP(cnt, 3, True) for cnt in contours0]
# contours, hierarchy = cv2.findContours(thresh, 1, 2)
# for each contour found, draw a rectangle around it on original image
for contour in contours:
# get rectangle bounding contour
[x,y,w,h] = cv2.boundingRect(contour)
# discard areas that are too large
if h>50 and w>50:
continue
# discard areas that are too small
if h<5 or w<5:
continue
# draw rectangle around contour on original image
# slightly expand the rectangles to form a chain of overlapping bounding boxes
pad_w, pad_h = int(0.05*w), int(0.15*h)
cv2.rectangle(im,(x-pad_w,y-pad_h),(x+w+pad_w,y+h+pad_h),(255,0,255),1,shift=0)
# write original image with added contours to disk
cv2.imwrite("rectangle.png", im)
cv2.imshow('image', im)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)
我尝试了以下 cv2.groupRectangles 代码,但它根本没有产生任何效果。我注意到cascade.detectMultiScale没有找到任何矩形。
import numpy as np
import cv2
cascade = cv2.CascadeClassifier('data/haarcascades/haarcascade_frontalface_alt.xml')
img = cv2.imread('rectangle.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
rawrects = cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=1, minSize=(5, 5), flags = cv2.CASCADE_SCALE_IMAGE)
# rects, weights = cv2.groupRectangles(np.array(rawrects).tolist(), 1, 0.2)
print "nrects %d" % len(rawrects)
for i, r in enumerate(rawrects):
weight = weights[i]
rectline = "%f %f %f %f %d\n" % (r[0], r[1], r[2], r[3], weight)
print rectline
p1 = (r[0], r[1])
p2 = (r[0]+r[2], r[1]+r[3])
cv2.rectangle(img, p1, p2, (0,0,255))
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)