如何使用 Tesseract OCR 从视频帧中提取数字?

Posted

技术标签:

【中文标题】如何使用 Tesseract OCR 从视频帧中提取数字?【英文标题】:How can I extract numbers from video frames using Tesseract OCR? 【发布时间】:2021-04-26 14:44:10 【问题描述】:

我有兴趣从标准化视频(始终高清分辨率 @ 1920x1080,30 FPS)中提取数字。数字总是出现在屏幕的固定部分,并且永远不会丢失。

我的方法是:

    以 PNG 格式逐帧保存视频 加载单个 PNG 帧 选择感兴趣的领域(有四个部分我想要 从中提取数字;每个部分可能需要自己的图像处理;总是在完全相同的像素范围内) 使用 Python 和 Tesseract-OCR 提取数字 在数据框中存储值

其中两个部分的示例是:

我已经安装了 Python(我是 R 用户)和 tesseract,并且可以很好地运行 Tesseract 示例(即我已经确认我的设置有效)。

但是,当我在顶部图像上运行以下命令时 [247] Tesseract 无法提取数字,而您认为它很容易提取,因为文本非常清晰。

from PIL import Image
import pytesseract
import os
import cv2
import argparse


img = cv2.imread("C:/Users/Luc/Videos/Monza GR4 1.56.156/frames/frame1060_speed.png")

cv2.imshow("RAW", img)
cv2.waitKeyEx(0)
cv2.destroyWindow()


imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imshow("RBG", imgRGB)
cv2.waitKeyEx(0)
cv2.destroyWindow()


imgBW2WB = cv2.bitwise_not(imgRGB)
cv2.imshow("White black swapped", imgBW2WB)
cv2.waitKeyEx(0)
cv2.destroyWindow()


(thresh, blackAndWhiteImage) = cv2.threshold(imgBW2WB, 127, 255, cv2.THRESH_BINARY)
cv2.imshow("Remove some noise", blackAndWhiteImage)
cv2.waitKeyEx(0)
cv2.destroyWindow()


pytesseract.image_to_string(blackAndWhiteImage, 
                            config='--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789')

输出是:

pytesseract.image_to_string(blackAndWhiteImage, 
                            config='--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789')
Out[15]: '7\n\x0c'

【问题讨论】:

我猜你使用的是最新的 tesseract?旧的很糟糕...... 我正在使用 Tesseract V5.0.0 和 Python 3.8.5 【参考方案1】:

请相应地使用此 Python 代码:

import cv2
from pytesseract import image_to_string
import numpy as np

def getText(filename):
    img = cv2.imread(filename)
    HSV_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    h,s,v = cv2.split(HSV_img)
    v = cv2.GaussianBlur(v, (1,1), 0)
    thresh = cv2.threshold(v, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
    cv2.imwrite('.png'.format(filename),thresh)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(1, 2))
    thresh = cv2.dilate(thresh, kernel)
    txt = image_to_string(thresh, config="--psm 6 digits")
    return txt
    

text = getText('WYOtF.png')
print(text)
text = getText('0Oqfr.png')
print(text)

这里的 getText() 函数将获取 png 图像文件的路径。转换为 HSV 域后,它将值分量作为 v,然后在阈值化之前执行高斯模糊。您可以尝试根据您的图像改变扩张函数的内核大小。这两张图片是上面代码的输入,下面是输出。

输出

247
0.10.694

阈值化结果

WYOtF.png

0Oqfr.png

【讨论】:

【参考方案2】:

您需要将bytes 转换为int。 请测试:

int.from_bytes(b'7\n\x0c', byteorder='little')

看起来你从 247 中得到了 47,但不是 2。干杯。

查看这里了解更多信息Convert bytes to int?

【讨论】:

当我运行 int.from_bytes(b'7\n\x0c', byteorder='little') 我得到: Out[22]: 789047 not 47. @Luc 检查所选区域。当区域大于实际目标时,我遇到了同样的问题。 好的,我绝对可以减少顶部、右侧和底部的空间,但不能减少左侧的空间,因为值的范围是 0-999 另外,巧合的是,当我将 --psm 更改为 8 时,我得到: Out[41]: '247\n\x0c' ???将其从字节转换为整数会给出一个无意义的数字 编辑:我尝试使用不同的帧并将确切的数字 164 读取为 Out[54]: '164\n\x0c'

以上是关于如何使用 Tesseract OCR 从视频帧中提取数字?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 tesseract-ocr 从屏幕上的坐标读取?

如何使用 Python 或 Tesseract OCR 从输入图像中检测语言或脚本?

如何使用 openCV 或 OCR tesseract 从图像中提取文本? [复制]

如何在 iOS 中使用 Tesseract OCR 库从图像中识别准确的文本?

如何加速 tesseract OCR

如何使用 Google TextRecognizer 或 Tesseract 在相机帧的子集上执行 OCR