我正在使用tesseract(通过python包装器)以从文档中提取文本。这些文档不包含任何图像或表格,仅包含文本。
是否有其他选项可将标题/标题与文本区分开?理想情况下,我希望能够拥有像xml树之类的东西,而不是具有完整的字符串链(我不需要具有文档布局的外观)。
[我发现了一些似乎可以提供帮助的third party tools,但我想知道是否可以直接从tesseract进行。
您可以使用Nanonets OCR api创建用于分隔标题和文本的模型,也可以添加其他标签。
这里是使用OpenCV阈值+轮廓过滤的一种潜在方法:
获得二进制图像。加载图像,转换为灰度,高斯模糊和Otsu的阈值。
用于连接水平文本的Dilate。我们利用了这样的观察:文本是水平的,文本的一段由连续的行组成。标题或标题将没有连续的文本,因此我们可以通过创建水平内核并扩展以连接字符来区分这两种类型。
执行轮廓过滤。通过查找轮廓并使用轮廓区域进行过滤,我们使用预定的阈值来确定轮廓是标题还是文本正文。
这是一个逐步的过程。使用此输入图像:
二进制图像
扩展以连接文本
检测到的节,标题/标题为绿色,正文为红色
代码
import cv2
# Load image, grayscale, blur, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Dilate
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,5))
dilate = cv2.dilate(thresh, kernel, iterations=3)
# Contour area filtering
header_threshold = 20000
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
area = cv2.contourArea(c)
# Header/Title
if area < header_threshold:
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
# Body Text
else:
cv2.rectangle(image, (x, y), (x + w, y + h), (0,0,255), 2)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.imshow('dilate', dilate)
cv2.waitKey()