Use Pytesseract Ocr to Recognize Text from an Image

pytesseract improving OCR accuracy for blurred numbers on an image

Here's a simple approach using OpenCV and Pytesseract OCR. To perform OCR on an image, it's important to preprocess the image. The idea is to obtain a processed image where the text to extract is in black with the background in white. To do this, we can convert to grayscale, then apply a sharpening kernel using cv2.filter2D() to enhance the blurred sections. A general sharpening kernel looks like this:

[[-1,-1,-1], [-1,9,-1], [-1,-1,-1]]

Other kernel variations can be found here. Depending on the image, you can adjust the strength of the filter. From here we Otsu's threshold to obtain a binary image then perform text extraction using the --psm 6 configuration option to assume a single uniform block of text. Take a look here for more OCR configuration options.


Here's a visualization of the image processing pipeline:

Input image

Sample Image

Convert to grayscale -> apply sharpening filter

Sample Image

Otsu's threshold

Sample Image

Result from Pytesseract OCR

124,685

Code

import cv2
import numpy as np
import pytesseract

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

# Load image, grayscale, apply sharpening filter, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
sharpen = cv2.filter2D(gray, -1, sharpen_kernel)
thresh = cv2.threshold(sharpen, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# OCR
data = pytesseract.image_to_string(thresh, lang='eng', config='--psm 6')
print(data)

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

Is it possible to extract text from specific portion of image using pytesseract

There's no built in function to extract a specific portion of an image using Pytesseract but we can use OpenCV to extract the ROI bounding box then throw this ROI into Pytesseract. We convert the image to grayscale then threshold to obtain a binary image. Assuming you have the desired ROI coordinates, we use Numpy slicing to extract the desired ROI

Sample Image

From here we throw it into Pytesseract to get our result

ONLINE FOOD DELIVERY SYSTEM

Code

import cv2
import pytesseract

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

image = cv2.imread('1.jpg', 0)
thresh = 255 - cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

x,y,w,h = 37, 625, 309, 28
ROI = thresh[y:y+h,x:x+w]
data = pytesseract.image_to_string(ROI, lang='eng',config='--psm 6')
print(data)

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

Pytesseract OCR wrong text recognition

I have a two-step solution




    1. Resize the image


    1. Apply thresholding.



    1. Resizing the image
    • The input image is too small for recognizing the digits, punctuation, and character. Increasing the dimension will enable an accurate solution.


    1. Apply threshold
    • Thresholding will show the features of the image.

    • When you apply thresholding result will be:

      • Sample Image

When you read the threshold image:

7,451k

Code:



import cv2
from pytesseract import image_to_string

img = cv2.imread("4ARXO.png")
(h, w) = img.shape[:2]
img = cv2.resize(img, (w*3, h*3))
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thr = cv2.threshold(gry, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
txt = image_to_string(thr)
print(txt)


Related Topics



Leave a reply



Submit