首页 > 解决方案 > 如何使用 PyTesseract 去除图像噪声以改善结果?

问题描述

我正在尝试从视频的左上角获取文本“P1”和“P2”。

P1

P2

我拍摄了一个框架并将它们裁剪为以下图像,然后应用此处找到的图像处理:

P1 裁剪

P2 裁剪

使用 pytesseract 从图像中识别文本

虽然它适用于我使用图像编辑器手动编辑的裁剪静止图像,但在使用 cv2 从视频中获取帧时它不起作用。

我不确定这是为什么,但我怀疑它与下图中的黑白背景有关,但我不知道如何在不删除文本的情况下摆脱它。

P1 后期图像处理

这是我的代码

import cv2
import pytesseract
import re
from difflib import SequenceMatcher
def determineWinner(video):
    winnerRect = [(70,95),(146,152)]
    cap = cv2.VideoCapture(video)
    if(cap.isOpened() == False):
        print("No dice")
        return
    fps = cap.get(cv2.CAP_PROP_FPS)
    frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
    print(fps)
    print(frames)
    desiredSeek = frames - int(fps * 9)
    print(desiredSeek)
    seconds = desiredSeek/fps
    print(seconds)
    minutes = seconds/60
    print(minutes)
    partial = minutes - int(minutes)
    print(partial)
    seconds = partial * 60
    print(seconds)
    print(str(int(minutes)) +":"+ str(seconds))

    cap.set(cv2.CAP_PROP_POS_FRAMES,(desiredSeek))

    ret,img = cap.read()
    winTxt = []
    p1Count = 0
    p2Count = 0

    cv2.namedWindow("",cv2.WINDOW_NORMAL)

    ret,img = cap.read()
    while ret:
        key = cv2.waitKey(1)
        if key == ord('q'):
            break
        if key == ord('e'):
            ret,img = cap.read()
            if ret:
                winROI = img[winnerRect[0][1]:winnerRect[1][1],winnerRect[0][0]:winnerRect[1][0]]
                gray = cv2.cvtColor(winROI, cv2.COLOR_BGR2GRAY)
                blur = cv2.GaussianBlur(gray, (3,3), 0)
                thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

                # Morph open to remove noise and invert image
                kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
                opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)
                invert = 255-opening
                invert=cv2.resize(invert,None,fx=2,fy=2)
                wConfig='-l eng --oem 1 --psm 10 -c tessedit_char_whitelist=P12'
                winTxt = pytesseract.image_to_string(invert,config=wConfig)
                cv2.rectangle(img,winnerRect[0],winnerRect[1],(255,0,0),2)
                cv2.imshow("winroi",invert)
                cv2.imshow("",img)
                cv2.resizeWindow("",800,600)
                print(winTxt)
                desiredSeek+=1
                seconds = desiredSeek/fps
                minutes = seconds/60
                partial = minutes - int(minutes)
                seconds = partial * 60
                print(str(int(minutes)) +":"+ str(seconds))
            else:
                break

    cap.release()
    cv2.destroyAllWindows()

标签: python-3.xopencvtextocrpython-tesseract

解决方案


此代码用作测试脚本。我只提取了包含P1. 要在新图像上应用过滤器,只需擦除预定义的阈值,如下所示:

从:

low_blue, low_green, low_red, upper_blue, upper_green, upper_red = (115, 0, 0, 255, 178, 255)

到:

low_blue, low_green, low_red, upper_blue, upper_green, upper_red = (0, 0, 0, 255, 255, 255)

并开始修改参数,如下所述。确定参数后,按esc退出程序,取控制台显示的参数,粘贴到thresholds元组中。


如何使用它:

  • 很重要。要使其正常工作,您必须单击鼠标左键选择来自 的窗口cv2.imshow(),在这种情况下Original imageBinary image

  • q增加和w减少下蓝色阈值

  • a增加和s减少绿色阈值下限
  • ... 对于上下颜色 ( BGR) 阈值,依此类推

import numpy as np
import cv2

low_blue, low_green, low_red, upper_blue, upper_green, upper_red = (115, 0, 0, 255, 178, 255)

# Get picture
path = "C:\\Users\\asd\\asd\\P1.png"
frame = cv2.imread(path)

while 1:

    lower_color = np.array((low_blue, low_green, low_red))
    upper_color = np.array((upper_blue, upper_green, upper_red))

    # extract binary image with active blue regions
    binary_image = cv2.inRange(frame, lower_color, upper_color)

    cv2.imshow('Original image', binary_image)

    #erode for the little white contour to dissapear
    binary_image = cv2.erode(binary_image, cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)))
    binary_image = cv2.dilate(binary_image, cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)))

    cv2.imshow('Binary image  ', binary_image)

    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break
    if k == ord('q'):
        low_blue += 1
    if k == ord('w'):
        low_blue -= 1
    if k == ord('a'):
        low_green += 1
    if k == ord('s'):
        low_green -= 1
    if k == ord('z'):
        low_red += 1
    if k == ord('x'):
        low_red -= 1
    if k == ord('e'):
        upper_blue += 1
    if k == ord('r'):
        upper_blue -= 1
    if k == ord('d'):
        upper_green += 1
    if k == ord('f'):
        upper_green -= 1
    if k == ord('c'):
        upper_red += 1
    if k == ord('v'):
        upper_red -= 1

    print("low_blue=", low_blue, "low_green=", low_green, "low_red=",low_red, "upper_blue", upper_blue, "upper_green=",
          upper_green, "upper_red=",upper_red)


cv2.destroyAllWindows()

结果

来自

在此处输入图像描述

到:

在此处输入图像描述


推荐阅读