首页 > 解决方案 > 如何从 pytesseract 获得最佳结果?

问题描述

我正在尝试使用 OpenCV 和 Pytesseract 从图像中读取文本,但结果很差。

我对阅读文本感兴趣的图像是:https ://www.lubecreostorepratolapeligna.it/gb/img/logo.png

这是我正在使用的代码:

 pytesseract.pytesseract.tesseract_cmd = r'D:\Program Files\pytesseract\tesseract.exe'
 image = cv2.imread(path_to_image)
 # converting image into gray scale image
 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 cv2.imshow('grey image', gray_image)
 cv2.waitKey(0)
 # converting it to binary image by Thresholding
 # this step is require if you have colored image because if you skip this part
 # then tesseract won't able to detect text correctly and this will give incorrect result
 threshold_img = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
 # display image
 cv2.imshow('threshold image', threshold_img)
 # Maintain output window until user presses a key
 cv2.waitKey(0)
 # Destroying present windows on screen
 cv2.destroyAllWindows()
 # now feeding image to tesseract
 text = pytesseract.image_to_string(threshold_img)
 print(text)

执行的结果是: ["cu"," ","LUBE"," ","STORE","PRATOLA PELIGNA"]

但结果应该是这 7 个词:[“cucine”、“LUBE”、“CREO”、“kitchens”、“STORE”、“PRATOLA”、“PELIGNA”]

有没有人可以帮我解决这个问题?

标签: pythonpython-3.xopencvpython-tesseract

解决方案


编辑,17.12.2020:现在使用预处理它可以识别除 CREO 中的“O”之外的所有内容。请参阅 ocr8.py 中的阶段。然后 ocr9.py 演示(但尚未自动化)通过从 pytesseract.image_to_boxes() 返回的坐标、字母的适当大小和符号间距离来查找文本行,然后向前推断一步并搜索单个字符( --psm 8)。

碰巧 Tesseract 实际上已经识别出 CREO 中的“O”,但它读作,可能被下面的小“k”等混淆了。

由于它是一种罕见且“奇怪”/意外的符号,它可以被更正 - 自动替换(参见函数 Correct())。

有一个技术细节:Tesseract 返回 ANSI/ASCII 符号 12,(0x0C),而我的编辑器中的代码是 Unicode/UTF-8 - 9792。所以我在里面将它编码为 chr(12)。

最新版本:ocr9.py

原始图像

在此处输入图像描述

在此处输入图像描述

您提到 PRATOLA 和 PELIGNA 必须单独给出 - 只需用“”分隔:

 splitted = text.split(" ")

公认的

美食

润滑油

店铺

普拉托拉佩利尼亚

CRE [+O 修正和外推线]

厨房

...
C 39 211 47 221 0
U 62 211 69 221 0
C 84 211 92 221 0
I 107 211 108 221 0
N 123 211 131 221 0
E 146 211 153 221 0
L 39 108 59 166 0
U 63 107 93 166 0
B 98 108 128 166 0
E 133 108 152 166 0
S 440 134 468 173 0
T 470 135 499 173 0
O 500 134 539 174 0
R 544 135 575 173 0
E 580 135 608 173 0
P 287 76 315 114 0
R 319 76 350 114 0
A 352 76 390 114 0
T 387 76 417 114 0
O 417 75 456 115 0
L 461 76 487 114 0
A 489 76 526 114 0
P 543 76 572 114 0
E 576 76 604 114 0
L 609 76 634 114 0
I 639 76 643 114 0
G 649 75 683 115 0
N 690 76 722 114 0
A 726 76 764 114 0
C 21 30 55 65 0
R 62 31 93 64 0
E 99 31 127 64 0
K 47 19 52 25 0
I 61 19 62 25 0
T 71 19 76 25 0
C 84 19 89 25 0
H 96 19 109 25 0
E 113 19 117 25 0
N 127 19 132 25 0
S 141 19 145 22 0

这些来自获得“盒子”。

初始消息:

我猜对于“cucine”所在的区域,自适应阈值可能会更好地对其进行分割,或者可能首先应用一些边缘检测。

厨房似乎很小,尝试扩大那个区域/距离怎么样。

对于 CREO,我猜它与相邻字幕的大小相混淆。对于 creo 中的“O”,您可以应用 dilate 以缩小“O”的间隙。

编辑:我玩了一点,但没有 Tesseract,它需要更多的工作。我的目标是使字母更具对比性,可能需要仅在 Cucine 上选择性地应用其中一些处理,可能在两遍中应用识别。当获得那些部分单词“Cu”时,应用自适应阈值等(如下)和 OCR 在“CU...”周围的顶部矩形上

二进制阈值: 在此处输入图像描述

自适应阈值、中值模糊(清除噪声)和反转: 在此处输入图像描述

扩张连接小间隙,但它也破坏了细节。

import cv2
import numpy as np
#pytesseract.pytesseract.tesseract_cmd = r'D:\Program Files\pytesseract\tesseract.exe'
path_to_image = "logo.png"
#path_to_image = "logo1.png"
image = cv2.imread(path_to_image)
h, w, _ = image.shape
w*=3; h*=3
w = (int)(w); h = (int) (h)
image = cv2.resize(image, (w,h), interpolation = cv2.INTER_AREA) #Resize 3 times
# converting image into gray scale image
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('grey image', gray_image)
cv2.waitKey(0)
# converting it to binary image by Thresholding
# this step is require if you have colored image because if you skip this part
# then tesseract won't able to detect text correctly and this will give incorrect result
#threshold_img = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# display image
threshold_img = cv2.adaptiveThreshold(gray_image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
            cv2.THRESH_BINARY,13,3) #cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11,2)[1]
cv2.imshow('threshold image', threshold_img)            
cv2.waitKey(0)
#threshold_img = cv2.GaussianBlur(threshold_img,(3,3),0)
#threshold_img = cv2.GaussianBlur(threshold_img,(3,3),0)
threshold_img = cv2.medianBlur(threshold_img,5)
cv2.imshow('medianBlur', threshold_img)            
cv2.waitKey(0)
threshold_img  = cv2.bitwise_not(threshold_img)
cv2.imshow('Invert', threshold_img)            
cv2.waitKey(0)
#kernel = np.ones((1, 1), np.uint8)   
#threshold_img = cv2.dilate(threshold_img, kernel)  
#cv2.imshow('Dilate', threshold_img)            
#cv2.waitKey(0)
cv2.imshow('threshold image', thrfeshold_img)
# Maintain output window until user presses a key
cv2.waitKey(0)
# Destroying present windows on screen
cv2.destroyAllWindows()
# now feeding image to tesseract
text = pytesseract.image_to_string(threshold_img)
print(text)

推荐阅读