简体   繁体   English

使用 Python 和 OpenCV 从点阵显示图像中读取 OCR 文本

[英]Reading OCR text from a dot matrix display image with Python and OpenCV

I am looking to extract some text from a meter display using Python 3 and OpenCV.我希望使用 Python 3 和 OpenCV 从仪表显示中提取一些文本。 I have had some success with a lot of help from SO on the code below, and I can print text from a basic and 'tidy' image file.在下面的代码中,我在 SO 的大量帮助下取得了一些成功,我可以从基本和“整洁”的图像文件中打印文本。 However when I look to extract from the attached dot matrix image the script is unable to pick out any text at all.但是,当我希望从附加的点阵图像中提取时,脚本根本无法挑选出任何文本。

Is there a limitation to extracting in this kind of dot matrix text?在这种点阵文本中提取有限制吗?

Here's what I am working with:这是我正在使用的内容:

import cv2
import numpy as np
import pytesseract
from PIL import Image
from cv2 import boundingRect, countNonZero, cvtColor, drawContours, findContours, getStructuringElement, \
    imread, morphologyEx, pyrDown, rectangle, threshold

img = imread('test.JPG')
# down sample and use it for processing
adjusted = pyrDown(img)
# gray-scale image
img_gray = cvtColor(adjusted, cv2.COLOR_BGR2GRAY)

# morph gradient
morph_kernel = getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
grad = morphologyEx(img_gray, cv2.MORPH_GRADIENT, morph_kernel)

# change to binary and morph
_, bw = threshold(src=grad, thresh=0, maxval=255, type=cv2.THRESH_BINARY+cv2.THRESH_OTSU)
morph_kernel = getStructuringElement(cv2.MORPH_RECT, (9, 1))
connected = morphologyEx(bw, cv2.MORPH_CLOSE, morph_kernel)
applyMask = np.zeros(bw.shape, np.uint8)

# get contours
im2, contour, hierarchy = findContours(connected, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
# filter contours
for index in range(0, len(hierarchy[0])):
    rect = x, y, rectangle_width, rectangle_height = boundingRect(contour[index])

    # draw contour
    mask = drawContours(applyMask, contour, index, (255, 255, 2555), cv2.FILLED)

    # find non-zero pixels ratio
    r = float(countNonZero(applyMask)) / (rectangle_width * rectangle_height)
    if r > 0.5 and rectangle_height > 8 and rectangle_width > 8:
        rec_img = rectangle(adjusted, (x, y+rectangle_height), (x+rectangle_width, y), (0, 255, 0), 3)

        text = pytesseract.image_to_string(Image.fromarray(rec_img))
        print(text)

And here's the image I am trying to extract from:这是我试图从中提取的图像:

在此处输入图片说明

In my experience, pytesseract doesn't work well in real word.根据我的经验,pytesseract 在现实世界中效果不佳。 Block Binary Pixel Sum could be better in your case.在您的情况下,Block Binary Pixel Sum 可能会更好。

This is the best solution I could find.这是我能找到的最好的解决方案。 Try blurring the image and then use OpenCV to pull the text.尝试模糊图像,然后使用 OpenCV 提取文本。 I was able to successfully pull out "Meter Input" but you may need another method to pull out the numbers.我能够成功拉出“仪表输入”,但您可能需要另一种方法来拉出数字。

import PIL
from PIL import Image
import PIL.ImageOps
import cv2 as cv
import pytesseract
from PIL import ImageFilter
from pytesseract import image_to_string
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

#open the image and check it out
image = Image.open('dotMatrixScreen.jpg')
display(image)

cropped_img = image.crop((230, 350, 1000, 570))
display(cropped_img)

full_pannel_blur = cropped_img.filter(ImageFilter.BoxBlur(radius=4))    
display(full_pannel_blur)

full_pannel_blur_grey = full_pannel_blur.convert("L")
full_pannel_blur_bw = full_pannel_blur_grey.point(lambda x: 0 if x<122 else 255, '1')
full_pannel_blur_bw.save("full_pannel_blur_bw.png")
display(full_pannel_blur_bw)

full_pannel_bw = full_pannel_blur_bw.convert("L")
full_pannel_bw.save("full_pannel_bw.png")

full_pannel_bw_cv = cv.imread("full_pannel_bw.png", 0)
display(Image.fromarray(full_pannel_bw_cv))

text = image_to_string(full_pannel_bw_cv)
print("Pytesseract got: ", '"' + text + '"')

Out: Pytesseract got: "Meter Index hes. S46m3"输出:Pytesseract 得到:“Meter Index hes. S46m3”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM