Barceló
Barceló

Reputation: 11

how get digits recognize from electric meter with minimum libs?

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

Answers (3)

energy1991
energy1991

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

Ahx
Ahx

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.

    1. Performing color-segmentation: We convert the loaded image to the HSV format define lower/upper ranges and perform color segmentation using cv2.inRange to obtain a binary mask.
    1. Extracting digits: After obtaining binary mask we will use it to remove the background and separate digit part from the rest of the image using cv2.bitwise_and. Arithmetic operation and is highly useful for defining roi in hsv colored images.
    1. OCR with tesseract: We will set page-segmentation-mode to 6 (see all) to get an accurate output.

  • Color segmentation for getting binary mask

    • enter image description here

    • 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)
      
  • Extracting digit using binary mask

    • enter image description here

    • krn = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
      dlt = cv2.dilate(msk, krn, iterations=5)
      res = 255 - cv2.bitwise_and(dlt, msk)
      
  • 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

  • enter image description here

Upvotes: 1

Barceló
Barceló

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)

test image

Upvotes: 0

Related Questions