【问题标题】:Python Extract number from simple ImagePython从简单图像中提取数字
【发布时间】:2023-03-18 01:11:02
【问题描述】:

我有以下图片

lower = np.array([175, 125, 45], dtype="uint8")
upper = np.array([255, 255, 255], dtype="uint8")

mask = cv2.inRange(image, lower, upper)
img = cv2.bitwise_and(image, image, mask=mask)

plt.figure()
plt.imshow(img)
plt.axis('off')
plt.show()

现在如果我尝试像这样转换成灰度:

gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

我明白了:

我想提取上面的数字。

建议:

gray = 255 - gray
emp = np.full_like(gray, 255)
emp -= gray
emp[emp==0] = 255
emp[emp<100] = 0
gauss = cv2.GaussianBlur(emp, (3,3), 1)
gauss[gauss<220] = 0
plt.imshow(gauss)

给出图像:

然后在任何图像上使用 pytesseract:

data = pytesseract.image_to_string(img, config='outputbase digits')

给予:

'\x0c'

另一个建议的解决方案是:

gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
thr = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV)[1]
txt = pytesseract.image_to_string(thr)
plt.imshow(thr)

这给了

'\x0c'

不是很满意...请问有人有更好的解决方案吗?

谢谢!

【问题讨论】:

  • 在 OCR 之前添加 img = PIL.ImageOps.invert(img)
  • 我试过了:img = Image.fromarray(img), img = ImageOps.invert(img), data = pytesseract.image_to_string(img),得到同样的结果...
  • @NicolasRey 您正在执行图像处理的整个过程,然后您将处理前的 raw 图像传递给pytesseractdata = pytesseract.image_to_string(img, config='outputbase digits') 替换imggauss!!!

标签: python-3.x opencv image-processing python-tesseract


【解决方案1】:

我有一个两步解决方案


对图像应用阈值处理时:

阈值化是显示图像特征的最简单方法。

现在从输出图像来看,当我们阅读时:

txt = image_to_string(thr, config="--psm 7")
print(txt)

结果将是:

| 1,625 |

现在我们为什么要将 page-segmentation-mode (psm) 模式设置为 7?

好吧,将图像视为单个文本行将给出准确的结果。

但是我们必须修改结果。由于当前结果是| 1,625 |

我们应该删除|

print("".join([t for t in txt if t != '|']))

结果:

1,625

代码:


import cv2
from pytesseract import image_to_string

img = cv2.imread("LZ3vi.png")
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thr = cv2.threshold(gry, 0, 255,
                    cv2.THRESH_BINARY_INV)[1]
txt = image_to_string(thr, config="--psm 7")
print("".join([t for t in txt if t != '|']).strip())

更新


你如何从我的原始图像中得到这张干净的黑白图像?

使用三步法

    1. 使用opencvimread函数读取图片
    • img = cv2.imread("LZ3vi.png")
      
    • 现在我们以BGR 的方式读取图像。 (不是RGB

    1. 将图像转换为灰度图
    • gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
      
    • 结果将是:

    1. 应用阈值
    • thr = cv2.threshold(gry, 0, 255, cv2.THRESH_BINARY_INV)[1]
      
    • 结果将是:

现在,如果您想了解阈值。阅读simple-threhsolding

我所有的滤镜,灰度.​​..得到奇怪的彩色图像

原因是,当你使用 pyplot 显示图像时,你需要将 color-map (cmap) 设置为灰色

plt.imshow(img, cmap='gray')

你可以阅读其他类型here

【讨论】:

  • @AlexAlex print(txt.strip('| ')) 输出为1,625 |
  • strip ('|')
  • 看起来很不错,但是你如何从我的原始图像中得到这个干净的黑白图像?我所有的滤镜,灰度.​​..得到奇怪的彩色图像
  • @NicolasRey 我已经更新了我的答案,包括了你的问题的答案。请阅读Update 部分。
【解决方案2】:

两个问题阻止了pytessract 检测您的号码:

  1. 数字周围的白色矩形(反转和填充是解决方案)。
  2. 数字形状中的噪声(高斯平滑处理)

AlexAlex 提出的解决方案如果后面跟着一个高斯滤波器,将会完美运行:

输出:1,625

import numpy as np
import pytesseract
import cv2

BGR = cv2.imread('11.png')
RGB = cv2.cvtColor(BGR, cv2.COLOR_BGR2RGB)

lower = np.array([175, 125, 45], dtype="uint8")
upper = np.array([255, 255, 255], dtype="uint8")

mask = cv2.inRange(RGB, lower, upper)
img = cv2.bitwise_and(RGB, RGB, mask=mask)

gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

gray = 255 - gray
emp = np.full_like(gray, 255)
emp -= gray

emp[emp==0] = 255
emp[emp<100] = 0

gauss = cv2.GaussianBlur(emp, (3,3), 1)
gauss[gauss<220] = 0

text = pytesseract.image_to_string(gauss, config='outputbase digits')

print(text)

【讨论】:

  • 我已经编辑了我的问题。我不知道为什么,但我无法重现您的结果...
  • @NicolasRey 因为你之前没有提供原始图像,只是灰度图像!您现在可以查看更新。
  • 我不明白为什么,但即使进行了更新,我仍然无法获得您的结果。每次滤镜后,你得到的彩色图像是否相同?我已经更新了我的结果
  • @NicolasRey 我正在使用您提供的 image 作为此 code 的输入,如果您使用不同的图像或者您使用自己的代码,我不确定是什么结果会是!
猜你喜欢
  • 1970-01-01
  • 2013-12-15
  • 2020-04-21
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 2013-11-22
相关资源
最近更新 更多