Home > Software design >  Poor Result in Detecting Meter Reading Using Pytesseract
Poor Result in Detecting Meter Reading Using Pytesseract

Time:12-15

I am trying to develop a meter reading detection system. This is the picture enter image description here

I need to get the meter reading 27599 as the output. I used this code:

import pytesseract
import cv2

image = cv2.imread('read2.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
(H, W) = gray.shape

rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20, 7))

gray = cv2.GaussianBlur(gray, (1, 3), 0)
blackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKernel)

res = cv2.threshold(blackhat, 0, 255, cv2.THRESH_BINARY_INV    cv2.THRESH_OTSU)[1]

pytesseract.image_to_string(res, config='--psm 12 --oem 3 digits')

I get this output:

'.\n\n-\n\n3\n\n7\n\n7\n\n3\n\n-2105 566.261586\n\n161200\n\n310010\n\n--\n\n.-\n\n.\n\n5\n\x0c'

This is my first OCR project. Any help will be appreciated.

CodePudding user response:

Well, there are a lot of texts there that can be removed before we start reading the actual meter number. On the other hand, we can limit our OCR to just numbers in order to prevent false positives (As a few 7-segment numbers are like alphabetical letters).

Since tesseract is not working well enough on 7-segment numbers. I will use EasyOCR.

So the procedure would be like this:

  1. There are large spaces around the actual counter which can be cropped.
  2. we blur the image and run a Hough transform to get the circular meter.
  3. We for sure know that the number is in the upper half of that circle so we again crop based on the center and radius of the detected circle.
  4. the cropped image then can be fed to EasyOCR and as i said previously only limited to the English language and numbers.

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import easyocr

cropped = orig_image[300:850,:][:,200:680]
cropped_height, cropped_width, _ = cropped.shape

gray = cv.cvtColor(cropped, cv.COLOR_BGR2GRAY)
blurred = cv.GaussianBlur(gray, (17,17),0)

enter image description here

minDist = 100
param1 = 30 
param2 = 50
minRadius = 100
maxRadius = 300

circle_img = cropped.copy()
circles = cv.HoughCircles(blurred, cv.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
print(f"{len(circles)} circles detected", circles[0,:][0])
if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        cv.circle(circle_img, (i[0], i[1]), i[2], (0, 255, 0), 2)

circle = circles[0,:][0]
circle_center = (circle[0], circle[1]) # x, y
circle_radius = circle[2]

color_cropped = cropped[circle_center[1] - circle_radius : circle_center[1],:]

enter image description here

reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext(color_cropped, allowlist ='0123456789')
if result:
    print("detected number: ", result[0][1])

detected number: 27599

  • Related