Pytesseract 不识别小数点
Pytesseract doesn't recognize decimal points
我正在尝试阅读此图片中的文本,其中还包含小数点和小数
这样:
img = cv2.imread(path_to_image)
print(pytesseract.image_to_string(img))
我得到的是:
73-82
Primo: 50 —
我也尝试指定意大利语,但结果非常相似:
73-82 _
Primo: 50
在 Whosebug 上搜索其他问题,我发现使用白名单可以改善十进制数字的读取,在这种情况下 tessedit_char_whitelist='0123456789.'
,但我也想读取图像中的文字。关于如何改进十进制数字的阅读有什么想法吗?
我建议将每一行文本作为单独的图像传递 tesseract。
出于某种原因,它似乎可以解决小数点问题...
- 使用
cv2.threshold
. 将图像从灰度转换为黑白
- 使用
cv2.dilate
具有非常长的水平内核的形态学操作(合并水平方向的块)。
- 使用查找轮廓 - 每个合并的行都将位于单独的轮廓中。
- 找到轮廓的边界框。
- 根据 y 坐标对边界框进行排序。
- 迭代边界框,并将切片传递给
pytesseract
。
代码如下:
import numpy as np
import cv2
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # I am using Windows
path_to_image = 'image.png'
img = cv2.imread(path_to_image, cv2.IMREAD_GRAYSCALE) # Read input image as Grayscale
# Convert to binary using automatic threshold (use cv2.THRESH_OTSU)
ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# Dilate thresh for uniting text areas into blocks of rows.
dilated_thresh = cv2.dilate(thresh, np.ones((3,100)))
# Find contours on dilated_thresh
cnts = cv2.findContours(dilated_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # Use index [-2] to be compatible to OpenCV 3 and 4
# Build a list of bounding boxes
bounding_boxes = [cv2.boundingRect(c) for c in cnts]
# Sort bounding boxes from "top to bottom"
bounding_boxes = sorted(bounding_boxes, key=lambda b: b[1])
# Iterate bounding boxes
for b in bounding_boxes:
x, y, w, h = b
if (h > 10) and (w > 10):
# Crop a slice, and inverse black and white (tesseract prefers black text).
slice = 255 - thresh[max(y-10, 0):min(y+h+10, thresh.shape[0]), max(x-10, 0):min(x+w+10, thresh.shape[1])]
text = pytesseract.image_to_string(slice, config="-c tessedit"
"_char_whitelist=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-:."
" --psm 3"
" ")
print(text)
我知道这不是最通用的解决方案,但它设法解决了您发布的示例。
请将答案视为概念性解决方案 - 找到可靠的解决方案可能非常具有挑战性。
结果:
膨胀后的阈值图像:
第一片:
第二个切片:
第三片:
输出文本:
7.3-8.2
Primo:50
您可以通过down-sampling图像轻松识别。
如果您将采样率降低 0.5,结果将是:
现在如果你阅读:
7.3 - 8.2
Primo: 50
我使用pytesseract 0.3.7版本(current)得到了结果
代码:
# Load the libraries
import cv2
import pytesseract
# Load the image
img = cv2.imread("s9edQ.png")
# Convert to the gray-scale
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Down-sample
gry = cv2.resize(gry, (0, 0), fx=0.5, fy=0.5)
# OCR
txt = pytesseract.image_to_string(gry)
print(txt)
解释:
输入图像包含一点伪像。您可以在图像的右侧部分看到它。另一方面,当前图像非常适合 OCR 识别。当图像中的数据不可见或损坏时,您需要使用预处理方法。请阅读以下内容:
我正在尝试阅读此图片中的文本,其中还包含小数点和小数
这样:
img = cv2.imread(path_to_image)
print(pytesseract.image_to_string(img))
我得到的是:
73-82
Primo: 50 —
我也尝试指定意大利语,但结果非常相似:
73-82 _
Primo: 50
在 Whosebug 上搜索其他问题,我发现使用白名单可以改善十进制数字的读取,在这种情况下 tessedit_char_whitelist='0123456789.'
,但我也想读取图像中的文字。关于如何改进十进制数字的阅读有什么想法吗?
我建议将每一行文本作为单独的图像传递 tesseract。
出于某种原因,它似乎可以解决小数点问题...
- 使用
cv2.threshold
. 将图像从灰度转换为黑白
- 使用
cv2.dilate
具有非常长的水平内核的形态学操作(合并水平方向的块)。 - 使用查找轮廓 - 每个合并的行都将位于单独的轮廓中。
- 找到轮廓的边界框。
- 根据 y 坐标对边界框进行排序。
- 迭代边界框,并将切片传递给
pytesseract
。
代码如下:
import numpy as np
import cv2
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # I am using Windows
path_to_image = 'image.png'
img = cv2.imread(path_to_image, cv2.IMREAD_GRAYSCALE) # Read input image as Grayscale
# Convert to binary using automatic threshold (use cv2.THRESH_OTSU)
ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# Dilate thresh for uniting text areas into blocks of rows.
dilated_thresh = cv2.dilate(thresh, np.ones((3,100)))
# Find contours on dilated_thresh
cnts = cv2.findContours(dilated_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # Use index [-2] to be compatible to OpenCV 3 and 4
# Build a list of bounding boxes
bounding_boxes = [cv2.boundingRect(c) for c in cnts]
# Sort bounding boxes from "top to bottom"
bounding_boxes = sorted(bounding_boxes, key=lambda b: b[1])
# Iterate bounding boxes
for b in bounding_boxes:
x, y, w, h = b
if (h > 10) and (w > 10):
# Crop a slice, and inverse black and white (tesseract prefers black text).
slice = 255 - thresh[max(y-10, 0):min(y+h+10, thresh.shape[0]), max(x-10, 0):min(x+w+10, thresh.shape[1])]
text = pytesseract.image_to_string(slice, config="-c tessedit"
"_char_whitelist=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-:."
" --psm 3"
" ")
print(text)
我知道这不是最通用的解决方案,但它设法解决了您发布的示例。
请将答案视为概念性解决方案 - 找到可靠的解决方案可能非常具有挑战性。
结果:
膨胀后的阈值图像:
第一片:
第二个切片:
第三片:
输出文本:
7.3-8.2
Primo:50
您可以通过down-sampling图像轻松识别。
如果您将采样率降低 0.5,结果将是:
现在如果你阅读:
7.3 - 8.2
Primo: 50
我使用pytesseract 0.3.7版本(current)得到了结果
代码:
# Load the libraries
import cv2
import pytesseract
# Load the image
img = cv2.imread("s9edQ.png")
# Convert to the gray-scale
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Down-sample
gry = cv2.resize(gry, (0, 0), fx=0.5, fy=0.5)
# OCR
txt = pytesseract.image_to_string(gry)
print(txt)
解释:
输入图像包含一点伪像。您可以在图像的右侧部分看到它。另一方面,当前图像非常适合 OCR 识别。当图像中的数据不可见或损坏时,您需要使用预处理方法。请阅读以下内容: