读取彩色数字图像要控制台的数字
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
图像)并每次都得到5
。 cv2.imshow()
和 cv2.waitKey()
仅用于显示目的,不应影响控制台输出。我正在使用 Windows 10,Python: 3.7.4
,NumPy: 1.14.5
,OpenCV: 4.1.0
,pytesseract: 0.2.7
我也在使用 Windows 10,Python 3.7.4
,但我使用的是 numpy==1.18.1
,opencv-python==4.1.2.30
,pytesseract==0.3.1
,这与你的不同【参考方案2】:
鉴于可爱的常规输入,我希望您只需要与模板进行简单比较。由于您忽略了提供代码和输出,因此很难判断可能出了什么问题。
很简单...
将您的输入重新调整为大小或模板。 使用 10 个模板中的每一个计算输入的任何直接匹配评估。一个简单的匹配计数就足够了:两个图像之间匹配的像素数。 得分最高的模板为标识。您可能还想为声明匹配设置一个较低的阈值,可能基于该模板与其他每个模板的匹配程度:任何标识都必须明显超过两个不同模板之间的匹配。
【讨论】:
【参考方案3】:如果您无法使用 OCR 引擎,只需知道您可以通过 KNN 分类器构建自己的 OCR 系统。在此示例中,实现应该不是很困难,因为您只是对数字进行分类。 OpenCV 提供了一个非常简单的 KNN 实现。
分类器使用从已知类实例的样本计算的特征进行训练。在这种情况下,您有 10 个类(如果您使用数字 0 - 9),因此您可以使用数字准备一个“模板”,提取一些特征,训练分类器并使用它来分类新实例。
所有这些都可以在 OpenCV 中完成,无需额外的库,并且 KNN(对于此类应用程序)具有超过可接受的准确率。
【讨论】:
以上是关于读取彩色数字图像要控制台的数字的主要内容,如果未能解决你的问题,请参考以下文章
数字图像处理Matlab实现-图像增强-彩色图像增强(彩虹编码,热金属编码)