简体   繁体   English

如何从具有最小库的电表中识别数字?

[英]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. 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 等软件包。

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.但是,我需要能够用最少的库有效地实现这一点,因为当使用 buildozer 生成 apk 时,我必须添加所有使用的库,这会生成一个太大的文件,只是为了添加这个功能。

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编辑1:我需要从数字和非数字仪表中提取数字:数字仪表

One approach is combining image-processing methods with pytesseract .一种方法是将图像处理方法与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. Python-tesseract 是 python 的光学字符识别 (OCR) 工具对于当前示例,您需要执行颜色分割以获取二进制掩码。 Next, you need to use the binary-mask to remove the background, then read the OCR digits using tesseract.接下来,您需要使用二进制掩码去除背景,然后使用 tesseract 读取 OCR 数字。

    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.执行颜色分割:我们将加载的图像转换为 HSV 格式,定义下限/上限范围,并使用cv2.inRange执行颜色分割以获得二进制掩码。
    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 .提取数字:获得二进制掩码后,我们将使用 cv2.bitwise_and 将其从图像的cv2.bitwise_and中去除背景并分离数字部分。 Arithmetic operation and is highly useful for defining roi in hsv colored images.算术运算,对于在 hsv 彩色图像中定义 roi 非常有用。
    1. OCR with tesseract: We will set page-segmentation-mode to 6 ( see all ) to get an accurate output. OCR with tesseract:我们将 page-segmentation-mode 设置为 6( 查看全部)以获得准确的 output。

  • Color segmentation for getting 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)
  • Extracting digit using binary mask使用二进制掩码提取数字

    • 在此处输入图像描述

    •  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结果将是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 *要找到掩码的上下边界,您可能会发现有用: HSV-Threshold-script *


Update:更新:


If the same technique is applied to the digital-meter numbers, result will be如果将相同的技术应用于数字仪表编号,结果将是

  • 在此处输入图像描述

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测试图像

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM