读取彩色数字图像要控制台的数字

Posted

技术标签:

【中文标题】读取彩色数字图像要控制台的数字【英文标题】:Recognizing digits with OpenCV and Python (Simple digit OCR) 【发布时间】:2020-05-04 18:29:50 【问题描述】:

所以我正在尝试创建一个程序,该程序可以查看图像的数字并在控制台中打印整数。 (我使用的是 python 3)

例如,程序识别出以下图像(程序必须检查的实际图像)为 2:

我尝试将其与其他图像进行比较,其中 2 与 cv2.matchTemplate() 但每次蓝色像素 rgb 值对于每个图像都有一点不同,并且图像可能会更大或更小.例如下图:

除了其他蓝色数字图像 (0-9) 之外,它还必须识别它,例如以下一个:

我尝试了多个匹配模板代码,并制作了一个包含数字 0-9 图像的文件夹作为模板,但每次几乎每个数字都被识别为需要识别的数字。例如,数字 5 在数字 2 的图像中被识别。如果它不能识别所有这些,它会识别错误的。

我试过的那些:

Answer from this question Both codes from this tutorial And the one from this tutorial

但就像我之前说的那样,它会带来这些问题。

我还尝试查看每张图像中蓝色的百分比,但这些数字要接近才能通过查看其中蓝色的含量来区分数字。

有人有解决办法吗?我使用cv2.matchTemplate() 是不是很愚蠢,有没有更简单的选择? (我不介意为它使用库,因为这是一段更大的代码的一部分,但我更喜欢编写它而不是库)

【问题讨论】:

我认为这太宽泛/模糊,可能不适合 Stack Overflow。 【参考方案1】:

不使用模板匹配,更好的方法是使用Pytesseract OCR 读取带有image_to_string() 的数字。但在执行 OCR 之前,您需要对图像进行预处理。为获得最佳 OCR 性能,预处理图像应具有所需的文本/数字/字符以黑色,背景为白色。一个简单的预处理步骤是将图像转换为灰度、Otsu 的阈值以获得二值图像,然后将图像反转。这是预处理步骤的可视化:

输入图像->灰度->大津阈值->倒置图像准备好进行OCR

Pytesseract OCR 的结果

2

这是其他图片的结果:

2

5

我们使用--psm 6 配置选项来假设一个统一的文本块。有关更多配置选项,请参阅here。

代码

import cv2
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, grayscale, Otsu's threshold, then invert
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
invert = 255 - thresh

# Perfrom OCR with Pytesseract
data = pytesseract.image_to_string(invert, lang='eng', config='--psm 6')
print(data)

cv2.imshow('thresh', thresh)
cv2.imshow('invert', invert)
cv2.waitKey()

注意:如果坚持使用模板匹配,则需要使用比例变体模板匹配。看看how to isolate everything inside of a contour, scale it, and test the similarity to an image? 和Python OpenCV line detection to detect X symbol in image 的一些例子。如果您确定您的图像是蓝色的,那么另一种方法是使用带有cv2.inRange() 的颜色阈值来获取二进制蒙版图像,然后在图像上应用 OCR。

【讨论】:

所以我试过你的方法,但仍然有一些数字它无法接收。例如,它将这 5 误认为是 -:imgur.com/a/a1f5PSs,这些是脱粒和倒置的图像:imgur.com/a/S4QwAg7。有没有办法让它认识到这一点? 我正在使用该输入图像将5 打印到控制台。您加载的图片是否正确? 我确定我正在加载正确的图像。您是否使用与您的 anwser 中相同的代码,或者当我将其上传到 imgur.com 时,图片中的某些内容是否发生了变化(我在您的 awnser 中使用了确切的代码,cv2.imshow()cv2.waitKey() 除外,但这不重要)?编辑:我刚刚下载了 imgur 图像,它仍然给了我- 是的,我使用的是确切的代码,我只是下载了图像(它是一个.png 图像)并每次都得到5cv2.imshow()cv2.waitKey() 仅用于显示目的,不应影响控制台输出。我正在使用 Windows 10,Python: 3.7.4NumPy: 1.14.5OpenCV: 4.1.0pytesseract: 0.2.7 我也在使用 Windows 10,Python 3.7.4,但我使用的是 numpy==1.18.1opencv-python==4.1.2.30pytesseract==0.3.1,这与你的不同【参考方案2】:

鉴于可爱的常规输入,我希望您只需要与模板进行简单比较。由于您忽略了提供代码和输出,因此很难判断可能出了什么问题。

很简单...

将您的输入重新调整为大小或模板。 使用 10 个模板中的每一个计算输入的任何直接匹配评估。一个简单的匹配计数就足够了:两个图像之间匹配的像素数。 得分最高的模板为标识。

您可能还想为声明匹配设置一个较低的阈值,可能基于该模板与其他每个模板的匹配程度:任何标识都必须明显超过两个不同模板之间的匹配。

【讨论】:

【参考方案3】:

如果您无法使用 OCR 引擎,只需知道您可以通过 KNN 分类器构建自己的 OCR 系统。在此示例中,实现应该不是很困难,因为您只是对数字进行分类。 OpenCV 提供了一个非常简单的 KNN 实现。

分类器使用从已知类实例的样本计算的特征进行训练。在这种情况下,您有 10 个类(如果您使用数字 0 - 9),因此您可以使用数字准备一个“模板”,提取一些特征,训练分类器并使用它来分类新实例。

所有这些都可以在 OpenCV 中完成,无需额外的库,并且 KNN(对于此类应用程序)具有超过可接受的准确率。

【讨论】:

以上是关于读取彩色数字图像要控制台的数字的主要内容,如果未能解决你的问题,请参考以下文章

数字图像处理Matlab实现-图像增强-彩色图像增强(彩虹编码,热金属编码)

数字图像处理--数字图像基础

数字图像处理绪论(MOOC)

数字图像处理1.绪论(mooc)

Python+OpenCV数字图像处理,彩色空间变换(HSI和RGB空间转换)

图像隐写基于matlab DCT彩色数字水印嵌入提取含Matlab源码 077期