Introdução ao Hardware e Ambiente
O Raspberry Pi 4B (4GB ou superior) é uma plataforma robusta para prototipagem de visão computacional. Para aplicações que envolvem Inteligência Artificial, como o uso de PyTorch e modelos de Deep Learning, é fundamental utilizar uma versão do sistema operacional Linux de 64 bits para garantir compatibilidade com as bibliotecas modernas.
A configuração básica envolve:
- Placa Raspberry Pi 4B.
- Cartão MicroSD de alta velocidade (Classe 10).
- Módulo de câmera CSI ou câmera USB.
- Fonte de alimentação estável (5V 3A).
Preparação do Sistema e Acesso Remoto
A gravação da imagem do sistema no cartão SD pode ser feita utilizando ferramentas como o Raspberry Pi Imager ou Win32DiskImager. Após o primeiro boot, recomenda-se configurar o acesso remoto para facilitar o desenvolvimento:
- VNC: Permite o acesso à interface gráfica de forma remota. Ative através do
raspi-config. - SSH: Essencial para transferência de arquivos via protocolos SFTP (utilizando ferramentas como WinSCP ou FileZilla) e execução de comandos via terminal.
Configuração de Visão Computacional com OpenCV
O primeiro passo para o processamento de imagem é a instalação do OpenCV e das dependências de suporte numérico. Execute os comandos abaixo no terminal do Raspberry Pi:
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install numpy --upgrade
Para validar o funcionaemnto da câmera, utilize o seguinte script Python:
import cv2
def test_camera_stream():
# Inicializa a captura (0 para câmera padrão)
video_capture = cv2.VideoCapture(0)
# Define a resolução de captura
video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
while True:
success, img_frame = video_capture.read()
if not success:
break
# Converte para tons de cinza para processamento simples
gray_view = cv2.cvtColor(img_frame, cv2.COLOR_BGR2GRAY)
cv2.imshow("Stream Original", img_frame)
cv2.imshow("Stream Cinza", gray_view)
# Sai do loop ao pressionar 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
test_camera_stream()
Detecção de Objetos com YOLOv5
O deploy do modelo YOLOv5 no Raspberry Pi requer a instalação das dependências listadas no repositório oficial do YOLOv5. O processo de inferência pode ser executado diretamente com arquivos .pt (PyTorch), mas o desempenho em processadores ARM costuma ser limitado.
# Instalação de dependências
pip install -r requirements.txt
# Execução da detecção via terminal
python detect.py --weights best.pt --source 0
Otimização de Performance com ONNX Runtime
Para obter taxas de quadros por segundo (FPS) mais altas, recomenda-se a conversão do modelo PyTorch para o formato ONNX. O formato ONNX é otimizado para inferência em CPUs.
# Exportação para ONNX
python export.py --weights best.pt --include onnx
# Instalação do runtime
pip install onnx onnxruntime
Abaixo, um exemplo de implementação de um motor de inferência utilizando ONNX Runtime para procesamento em tempo real:
import cv2
import numpy as np
import onnxruntime
import time
class DetectorYolo:
def __init__(self, path_model):
self.session = onnxruntime.InferenceSession(path_model)
self.input_layer = self.session.get_inputs()[0].name
self.labels = ['classe_A', 'classe_B'] # Substituir pelas classes reais
def transform_img(self, frame):
blob = cv2.resize(frame, (640, 640))
blob = blob[:, :, ::-1].transpose(2, 0, 1) # BGR para RGB e HWC para CHW
blob = blob.astype(np.float32) / 255.0
return np.expand_dims(blob, axis=0)
def predict(self, frame):
input_data = self.transform_img(frame)
raw_results = self.session.run(None, {self.input_layer: input_data})[0]
return raw_results
def calcular_nms(detections, threshold_iou):
# Lógica de Non-Maximum Suppression para filtrar boxes sobrepostas
x1 = detections[:, 0]
y1 = detections[:, 1]
x2 = detections[:, 2]
y2 = detections[:, 3]
scores = detections[:, 4]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
order = scores.argsort()[::-1]
keep = []
while order.size > 0:
idx = order[0]
keep.append(idx)
xx1 = np.maximum(x1[idx], x1[order[1:]])
yy1 = np.maximum(y1[idx], y1[order[1:]])
xx2 = np.minimum(x2[idx], x2[order[1:]])
yy2 = np.minimum(y2[idx], y2[order[1:]])
w = np.maximum(0, xx2 - xx1 + 1)
h = np.maximum(0, yy2 - yy1 + 1)
inter = w * h
iou = inter / (areas[idx] + areas[order[1:]] - inter)
inds = np.where(iou <= threshold_iou)[0]
order = order[inds + 1]
return keep
def run_realtime_inference(model_path):
engine = DetectorYolo(model_path)
cam = cv2.VideoCapture(0)
while cam.isOpened():
ret, frame = cam.read()
if not ret: break
start = time.time()
output = engine.predict(frame)
# Processamento simplificado de desenho (exemplo)
fps = 1.0 / (time.time() - start)
cv2.putText(frame, f"FPS: {fps:.2f}", (20, 40),
cv2.FONT_HERSHEY_DUPLEX, 1, (0, 255, 0), 2)
cv2.imshow("Inferencia ONNX", frame)
if cv2.waitKey(1) == ord('q'): break
cam.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
run_realtime_inference("best.onnx")
Ao utilizar o ONNX Runtime, o Raspberry Pi consegue gerenciar melhor os recursos da CPU, reduzindo a latência significativamente em comparação com a execução direta no framework de treinamento.