我尝试使用tesseract ocr tool从视频游戏中提取ocr文本(我预先处理屏幕截图并将其传递给命令行工具tsv输出并解析它)。
我希望将它用于测试自动化,与硒网测试不同。 这就是我希望能够等待元素出现而不是睡觉并点击按钮(主要是菜单)。
为了能够做到这一点,我需要能够始终如一地找到相同的按钮文本,并在一系列视频游戏中找到尽可能多的文本。 为了抽象,我更喜欢每个游戏的预处理/ tesseract选项都是相同的。
我可以添加每个游戏中遇到的每个单词的字典,但我不愿意。
我已经设置了一个设置,我可以测试预处理/ tesseract选项的多种不同组合,并查看生成的单词。
我已经尝试将屏幕截图(70-90 dpi)吹了5次,并在将其传递给tesarect之前将其设置为灰度。
我可以使用哪些其他技巧来提高结果的数量和准确性?我应该看哪些tesseract旋钮?我可以添加任何其他有用的预处理吗?
P.S。我发现,如果我将图片放大到两倍长/宽,tesseract似乎就会爆炸,因为图像的内存耗尽。有静态限制吗?我可以找到它,所以我可以炸掉最大尺寸附近的图像吗?我可以调整吗?
答案 0 :(得分:6)
这是迄今为止从我的tesseract经验中学到的最重要的一课。开箱即用的tesseract非常适合识别扫描的书籍和报纸文字,但是当你尝试使用与标准书籍和报纸字体(如Times New Roman)不相似的字体时,我的体验准确度会大大降低。过去训练要困难得多,但现在tesstrain.sh让人感到很紧张。您必须收集视频游戏字体(或至少与它们相似的字体),并将它们作为训练脚本的输入。即使您的字体差别很大,tesseract也能够在运行时以惊人的精确度为所提供的图像选择正确的字体。此外,我知道这很乏味,但将视频游戏中遇到的所有单词的词汇表提供给训练脚本是有益的。使用您自己的字体和您自己的单词列表训练tesseract将为您提供近乎完美的准确性,而无需做任何其他事情。
如果可以,请进行自己的布局分析,并将图像裁剪为包含文本的部分。 Teseract内置了一个页面分割引擎,但它必须涵盖如此广泛的用例,它很可能无法满足您的特定需求。另外,根据我的经验,如果将图像分成单行文本并使用分割模式7(将图像视为单个文本行),它还可以提高准确性。
如果您将输入文本的x高度增加到用于训练tesseract的相同高度(IIRC,在我的情况下这是70像素),这会有所帮助。
Tesseract really likes 300 DPI。请注意,更改图像的DPI与更改其大小不同。 (例如,使用ImageMagick,您可以use the -density option更改图像的DPI。)
根据我的经验,调整与匹配字典单词有关的不同“惩罚”设置对提高准确性影响最大。适合我的设置:
language_model_penalty_non_dict_word 0.975
language_model_penalty_non_freq_dict_word 0.575
segment_penalty_dict_case_bad 1.3125
segment_penalty_dict_case_ok 1.1
segment_penalty_dict_nonword 10.25
但你显然应该做自己的调整。另外,我发现x-height设置在运行时非常有用:textord_min_xheight
和min_sane_x_ht_pixels
。
我不知道tesseract的任何内存大小限制。你是否可以通过一个有自己限制的包装器来使用tesseract?
注意:这个答案假设您正在使用最新稳定版本的tesseract,这将是tesseract 3.05。如果您使用的是tesseract 4.0,那么您自己的培训和细分仍然适用,但答案的其他部分可能是OBE。
答案 1 :(得分:1)
您可能无法从tesseract
获得适当的质量输出。重要的是要注意,除非您使用非常不寻常的字体或新语言再培训tesseract
不太可能有所帮助。
因此,请查看ImproveQuality
工具,了解以下任务:重新缩放,二值化,去除噪音,旋转/去歪斜和删除边框。
例如,这是一个脚本,您可以在其中找到颜色转换,转换和绘图操作:
from __future__ import division, print_function
from skimage.transform import radon
from PIL import Image
from numpy import asarray, mean, array, blackman
import numpy
from numpy.fft import rfft
import matplotlib.pyplot as plt
from matplotlib.mlab import rms_flat
try:
# More accurate peak finding from
# https://gist.github.com/endolith/255291#file-parabolic-py
from parabolic import parabolic
def argmax(x):
return parabolic(x, numpy.argmax(x))[0]
except ImportError:
from numpy import argmax
filename = 'skew-linedetection.png'
# Load file, converting to grayscale
I = asarray(Image.open(filename).convert('L'))
I = I - mean(I) # Demean; make the brightness extend above and below zero
plt.subplot(2, 2, 1)
plt.imshow(I)
# Do the radon transform and display the result
sinogram = radon(I)
plt.subplot(2, 2, 2)
plt.imshow(sinogram.T, aspect='auto')
plt.gray()
# Find the RMS value of each row and find "busiest" rotation,
# where the transform is lined up perfectly with the alternating dark
# text and white lines
r = array([rms_flat(line) for line in sinogram.transpose()])
rotation = argmax(r)
print('Rotation: {:.2f} degrees'.format(90 - rotation))
plt.axhline(rotation, color='r')
# Plot the busy row
row = sinogram[:, rotation]
N = len(row)
plt.subplot(2, 2, 3)
plt.plot(row)
# Take spectrum of busy row and find line spacing
window = blackman(N)
spectrum = rfft(row * window)
plt.plot(row * window)
frequency = argmax(abs(spectrum))
line_spacing = N / frequency # pixels
print('Line spacing: {:.2f} pixels'.format(line_spacing))
plt.subplot(2, 2, 4)
plt.plot(abs(spectrum))
plt.axvline(frequency, color='r')
plt.yscale('log')
plt.show()
答案 2 :(得分:0)
我不是Tesseract的专家,但我会尝试两种不同的答案:
首先,您需要获取文本吗?如果图像比较(模板匹配)足够,那么像SikuliX或KantuX Chromium浏览器这样的工具可以提供帮助。
如果您需要文字,是否正在使用online ocr选项?如果是这样,那么就有Google Cloud愿景,Azure OCR或免费的OCR.space(25000转换/月免费)。明显的缺点是速度要慢得多,因为你需要上传截图。但是这些OCR服务开箱即用,特别是在丰富多彩的视频游戏中的文字#34; (或youtube)背景。正如mnistic所提到的,默认情况下,Tesseract针对书籍扫描进行了优化(白色背景)。
答案 3 :(得分:0)
您是否尝试过使用深度学习方法,特别是对象识别算法来检测https://matthewearl.github.io/2016/05/06/cnn-anpr/中的按钮文本?
答案 4 :(得分:0)
Google云为视频提供OCR。因此,您不必截屏。您可以将整个游戏视频更新为GCP,然后调用API进行处理。 API将为视频中的每个文本返回时间戳和边界框。它处理非常快,并且产生的结果非常密集且一致。您可以在官方文档中查看详细信息:https://cloud.google.com/video-intelligence/docs/text-detection