Reputation: 11
I am developing an application for android with python3 and kivy to which I want to add a functionality to automatically recognize the digits of the electric meter from the camera of the device, for which I have found a variety of solutions using opencv with numpy, mahotas, pytesseract, scipy, scikit_learn among other packages.
Trying:
https://github.com/VAUTPL/NUMBERS_DETECTION_1
https://github.com/spidgorny/energy-monitor
But, I need to be able to achieve this efficiently with the minimum of libraries because when generating the apk with buildozer I must add all the libraries used and this generates a file too big in size, just to add this functionality.
What do you recommend to achieve this goal with the minimum number of libraries?
the idea: non-digital
EDIT 1: I need extract digits from meters digital and non-digital : digital meter
Upvotes: 0
Views: 3237
Reputation: 1
You maye use digits detection. And use the display rules of meter to avoid mistake charactors. Finally, you will get right value.
Upvotes: 0
Reputation: 7985
One approach is combining image-processing methods with pytesseract
. Python-tesseract is an optical character recognition (OCR) tool for python For the current example, you need to perform color-segmentation to get the binary-mask. Next, you need to use the binary-mask to remove the background, then read the OCR digits using tesseract.
cv2.inRange
to obtain a binary mask.cv2.bitwise_and
. Arithmetic operation and is highly useful for defining roi in hsv colored images.Color segmentation for getting binary mask
Extracting digit using binary mask
OCR
15753 .
txt = pytesseract.image_to_string(res, config="--psm 6 digits")
print(txt)
If you want to remove .
or any other non-alpha character, you could do
txt = pytesseract.image_to_string(res, config="--psm 6 digits")
print(''.join(t for t in txt if t.isalnum()))
Result will be 15753
Code:
import cv2
import numpy as np
import pytesseract
# Load the image
img = cv2.imread("input.png")
# Color-segmentation to get binary mask
lwr = np.array([43, 0, 71])
upr = np.array([103, 255, 130])
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
msk = cv2.inRange(hsv, lwr, upr)
cv2.imwrite("/Users/ahx/Desktop/msk.png", msk)
# Extract digits
krn = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
dlt = cv2.dilate(msk, krn, iterations=5)
res = 255 - cv2.bitwise_and(dlt, msk)
cv2.imwrite("/Users/ahx/Desktop/res.png", res)
# Displaying digits and OCR
txt = pytesseract.image_to_string(res, config="--psm 6 digits")
print(''.join(t for t in txt if t.isalnum()))
cv2.imshow("res", res)
cv2.waitKey(0)
To find lower and upper boundaries of the mask, you may find useful: HSV-Threshold-script *
Update:
If the same technique is applied to the digital-meter numbers, result will be
Upvotes: 1
Reputation: 11
I try take picture from webcam but the result is not the same.
print("PRESS 'c' FOR TAKE THE PICTURE")
camara=cv2.VideoCapture(0)
while True:
(grabacion, img) = camara.read()
imagen = cv2.resize(img, (200, 120))
cv2.rectangle(imagen, (xf, rois), (xf+197, rois+50), (0, 255, 0), 2)cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 2)
cv2.imshow("CAMARA",imagen)
tecla=cv2.waitKey(1)
if tecla==ord('c'):
image=img
break
if tecla==ord('x'):
break
# Color-segmentation to get binary mask
lwr = np.array([43, 0, 71])
upr = np.array([103, 255, 130])
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
msk = cv2.inRange(hsv, lwr, upr)
cv2.imwrite("/home/barcelo/projects-kivy/ocr1/msk.png", msk)
# Extract digits
krn = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
dlt = cv2.dilate(msk, krn, iterations=5)
res = 255 - cv2.bitwise_and(dlt, msk)
cv2.imwrite("/home/barcelo/projects-kivy/ocr1/res.png", res)
# Displaying digits and OCR
txt = pytesseract.image_to_string(res, config="--psm 6 digits")
print(''.join(t for t in txt if t.isalnum()))
cv2.imshow("res", res)
cv2.waitKey(0)
Upvotes: 0