No setor de automação industrial e monitoramento inteligante, a leitura de medidores analógicos desempenha um papel crucial na coleta de dados. Entretanto, métodos tradicionais de leitura manual são ineficientes e suscetíveis a erros humanos. Para superar essas limitações, desenvolvemos uma solução baseada em OpenCV-Python que automatiza a identificação e leitura de escalas de medidores, aumentando significativamente a eficiência e precisão.
Análise Técnica
O projeto utiliza a biblioteca OpenCV para processamento de imagens. As etapas principais incluem:
- Pré-processamento de Imagem: Aplicação de filtros para redução de ruído, conversão para escala de cinza e binarização, visando otimizar a detecção subsequente.
- Detecção da Região do Medidor: Emprego de contornos e ajuste de formas circulares para delimitar a área do instrumento na imagem.
- Identificação do Ponteiro: Uso da Transformada de Hough para localizar linhas que representam o ponteiro do medidor.
- Cálculo da Leitura: Determinação do valor indicado com base na posição angular do potneiro em relação às marcações da escala.
Aplicações
Esta abordagem é adequada para cenários como:
- Monitoramento de equipamentos em linhas de produção industrial.
- Gestão de consumo em sistemas de energia ou água.
- Integração em sistemas de vigilância para registro automático de dados.
- Automação de leituras em ambientes laboratoriais.
Características
A solução oferece alta precisão através de algoritmos robustos de visão computacional. É escalável para processamento em lote de múltiplas imagens e possui uma interface simplificada para integração em pipelines de dados existentes.
Implementação
Para utilizar, instale as dependências necessárias:
pip install numpy opencv-python
O código a seguir exemplifica o fluxo básico. As classes e métodos foram renomeados para clareza, mantendo a funcionalidade original:
import cv2
import numpy as np
import glob
class AnalogMeterProcessor:
def __init__(self, image_path):
self.img = cv2.imread(image_path)
self.gray_img = None
self.threshold_img = None
self.pointer_angle = None
def preprocess(self):
self.gray_img = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(self.gray_img, (5, 5), 0)
_, self.threshold_img = cv2.threshold(blurred, 100, 255, cv2.THRESH_BINARY_INV)
return self.threshold_img
def detect_pointer(self):
edges = cv2.Canny(self.threshold_img, 50, 150, apertureSize=3)
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50, maxLineGap=10)
if lines is not None:
# Lógica simplificada para extrair ângulo do ponteiro
self.pointer_angle = np.arctan2(lines[0][0][3] - lines[0][0][1], lines[0][0][2] - lines[0][0][0])
return self.pointer_angle
def compute_reading(self, scale_range=(0, 100)):
# Conversão de ângulo para valor da escala
if self.pointer_angle is not None:
normalized_angle = (self.pointer_angle + np.pi) / (2 * np.pi)
reading = scale_range[0] + normalized_angle * (scale_range[1] - scale_range[0])
return round(reading, 2)
return None
if __name__ == "__main__":
# Processamento de uma única imagem
processor = AnalogMeterProcessor("exemplo.jpg")
processor.preprocess()
angle = processor.detect_pointer()
valor = processor.compute_reading()
print(f"Leitura detectada: {valor}")
# Processamento em lote (exemplo comentado)
# imagens = glob.glob("input/*.jpg")
# for caminho in imagens:
# proc = AnalogMeterProcessor(caminho)
# proc.preprocess()
# proc.detect_pointer()
# resultado = proc.compute_reading()