1
votes

My boss just gave me 9000 images showing a multi-meter output, and he wants me to read them all and write the voltage output on a text file for Monday morning!

There's no way I can do it manually , so I desperately need your help to automate the process.

enter image description here

I have already done a bit of coding. The multimeter screen position is fixed over the 9000 images, so I just cropped the pictures and zoomed on the screen.

Here's my code so far :

import pytesseract as tess
tess.pytesseract.tesseract_cmd = r'D:\Programs\Tesseract-OCR\tesseract.exe'
from PIL import Image
from matplotlib import pyplot as plt
import cv2
import numpy as np

img = cv2.imread('test1.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
ret, BW = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)

plt.imshow(BW)
plt.show()

print(tess.image_to_string(img,config='digits --oem 3'))

My code outputs this kind of picture:enter image description here

For this picture, tesseract reads the following number: 138

I have two problems here: the first one is I don't know how to properly pre-process my pictures for tesseract to easily read them.

Second problem: I don't know how to process the decimal dot. In fact, on some picture there is no decimal dot, so I need to find a way to make tesseract read it.

Do you think I'll need to manually "train" tesseract, so that I reach a near 100% accuracy?

Thank you sooo much for your help, I'll continue my research meanwhile on the OpenCv functions!

here's one of the originals: enter image description here

UPDATED VERSION:

Ok so I updated a bit my code so far :

# Loading the picture
img = cv2.imread('test1.JPG')

# Crop - Rotate - Scale up
x = 1400
y = 1375
h = 325
w = 800
img = img[y:y+h, x:x+w]
image = cv2.rotate(img, cv2.ROTATE_180)

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

thresh = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,10))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)

cv2.imshow('close', close)

x = 0
y = 0
h = 300
w = 750
img = close[y:y+h, x:x+w]

plt.imshow(img)
plt.show()

print(tess.image_to_string(img,config='--psm 7 -c tessedit_char_whitelist=0123456789 --oem 0'))

I get a finer image for tesseract to analyse. But still no luck with the decimal dot :/.

enter image description here

1
This is helpful for the pre-processing part.MohammadHosseinZiyaaddini
Can you post an original size image without the zoom with or without the cropfmw42
Yup, done. I added at the end of my post on original. I already added on my code functions to rotate the picture and crop the screen.ospreys
Tesseract does not like that decimal point. I tried a few tricks in Gimp to improve with no luck. There is a way to get tesseract to give you an array of locations of every character. That covers the numbers. What about template matching to find the decimal point? Between the two, you can reconstruct the kohm value.bfris
image_to_boxes is the function for finding character positions.bfris

1 Answers

-1
votes

you need around 3-4 hours to type them manually, just spend 1 extrahour to write a wrapper that opens the image and let's you input a value.

when automating, my biggest concern would be if all the measurements have the same unit of kilo-ohm, you should really include that check in your open-cv code.

good luck!