如何使用 Tesseract 对图像进行 OCR
Posted
技术标签:
【中文标题】如何使用 Tesseract 对图像进行 OCR【英文标题】:How to OCR image with Tesseract 【发布时间】:2020-01-25 22:30:27 【问题描述】:我开始学习 OpenCV 和 Tesseract,但对于一个看似非常简单的示例却遇到了麻烦。
这是我正在尝试 OCR 的图像,上面写着“171 m”:
我做了一些预处理。由于蓝色是文本的主要颜色,我提取了蓝色通道并应用了简单的阈值。
img = cv2.imread('171_m.png')[y, x, 0]
_, thresh = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY_INV)
生成的图像如下所示:
然后将其放入 Tesseract 中,psm 7
用于单行:
text = pytesseract.image_to_string(thresh, config='--psm 7')
print(text)
>>> lim
我也尝试限制可能的字符,它变得更好了一点,但并不完全。
text = pytesseract.image_to_string(thresh, config='--psm 7 -c tessedit_char_whitelist=1234567890m')
print(text)
>>> 17m
OpenCV v4.1.1.
Tesseract v5.0.0-alpha.20190708
任何帮助表示赞赏。
【问题讨论】:
【参考方案1】:在将图像放入 Pytesseract 之前,预处理会有所帮助。所需文本应为黑色,而背景应为白色。这是一种方法
将图像转换为灰度并放大图像 高斯模糊 大津的门槛 反转图像转换为灰度后,我们使用imutils.resize()
和高斯模糊放大图像。从这里我们Otsu的阈值得到二值图像
如果您有嘈杂的图像,另外一个步骤是使用形态学运算来平滑或去除噪声。但是由于您的图像足够干净,我们可以简单地反转图像以获得我们的结果
使用--psm 6
从 Pytesseract 输出
171 米
import cv2
import pytesseract
import imutils
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
image = cv2.imread('1.png',0)
image = imutils.resize(image, width=400)
blur = cv2.GaussianBlur(image, (7,7), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
result = 255 - thresh
data = pytesseract.image_to_string(result, lang='eng',config='--psm 6')
print(data)
cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.waitKey()
【讨论】:
【参考方案2】:免责声明:这不是解决方案,只是部分解决此问题的试验。
只有在您事先知道图像中存在的字符数时,此过程才有效。这是试用代码:
img0 = cv2.imread('171_m.png', 0)
adap_thresh = cv2.adaptiveThreshold(img0, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
text_adth = pytesseract.image_to_string(adap_thresh, config='--psm 7')
自适应阈值处理后,生成的图像是这样的:
Pytesseract 给出的输出为:
171 mi.
现在,如果您提前知道存在的字符数,您可以对 pytesseract 读取的字符串进行切片,并获得所需的输出为 '171m'
。
【讨论】:
【参考方案3】:我认为您的图像不够清晰,因此我应用了How do I increase the contrast of an image in Python OpenCV 中描述的过程来首先锐化您的图像,然后提取蓝色层并运行 tesseract。
我希望这会有所帮助。
import cv2
import pytesseract
img = cv2.imread('test.png') #test.png is your original image
s = 128
img = cv2.resize(img, (s,int(s/2)), 0, 0, cv2.INTER_AREA)
def apply_brightness_contrast(input_img, brightness = 0, contrast = 0):
if brightness != 0:
if brightness > 0:
shadow = brightness
highlight = 255
else:
shadow = 0
highlight = 255 + brightness
alpha_b = (highlight - shadow)/255
gamma_b = shadow
buf = cv2.addWeighted(input_img, alpha_b, input_img, 0, gamma_b)
else:
buf = input_img.copy()
if contrast != 0:
f = 131*(contrast + 127)/(127*(131-contrast))
alpha_c = f
gamma_c = 127*(1-f)
buf = cv2.addWeighted(buf, alpha_c, buf, 0, gamma_c)
return buf
out = apply_brightness_contrast(img,0,64)
b, g, r = cv2.split(out) #spliting and using just the blue
pytesseract.image_to_string(255-b, config='--psm 7 -c tessedit_char_whitelist=1234567890m') # the 255-b here because the image has black backgorund and white numbers, 255-b switches the colors
【讨论】:
用opencv 4.1版(s, s/2)
需要(s, int(s/2))
,否则给TypeError: integer argument expected, got float
。
感谢您指出这一点,我将编辑答案。否则,它对你有用吗?你得到正确答案了吗?以上是关于如何使用 Tesseract 对图像进行 OCR的主要内容,如果未能解决你的问题,请参考以下文章
Windows下命令行及Java+Tesseract-OCR对图像进行(字母+数字+中文)识别,亲测可行
Windows安装用于OCR的Tesseract及使用命令行参数进行OCR