É possível incorporar modelos de reconhecimento de objectos como o Yolo num Raspberry Pi. Naturalmente, devido ao seu baixo desempenho em comparação com os computadores, o desempenho é inferior em termos de reconhecimento em tempo real. No entanto, é perfeitamente possível desenvolver algoritmos que utilizem o reconhecimento de objectos para aplicações que não necessitem de reconhecimento em tempo real.
Hardware
- Raspberry Pi 4
- Ecrã+rato+teclado
- Cartão SD com o sistema operativo Raspbian 64bits
Configuração
Para utilizar o Yolo, é necessário instalar a versão de 64 bits do Raspberry Pi OS. Esta versão está disponível no software Raspberry Pi Imager, no menu Raspberry Pi OS (outros).
As versões compatíveis do Python são >=3.9
As bibliotecas a serem instaladas são
pip install numpy imutils opencv-python pip install ultralytics
Código de deteção de objectos
O código para a deteção de objectos com o Yolo é o mesmo que num computador
O modelo Yolo é inicializado (o ficheiro .pt é descarregado no início do programa).
model = YOLO("yolov5nu.pt")
Em seguida, abra um fluxo de vídeo (ou um ficheiro de vídeo ou imagem)
vs = VideoStream(src=0, resolution=(640, 640)).start() #video_cap = cv2.VideoCapture(0)
O modelo é então executado em cada imagem
detections = model(frame)[0]
Por fim, traçamos os resultados da deteção na imagem e apresentamo-los.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import datetime
from ultralytics import YOLO
import cv2
from imutils.video import VideoStream
import screeninfo
# define some constants
CONFIDENCE_THRESHOLD = 0.7
GREEN = (0, 255, 0)
model = YOLO("yolov5nu.pt")
#model = YOLO("./runs/detect/yolov8n_v8_50e2/weights/best.pt") # test trained model
print(model.names)
# initialize the video capture object
vs = VideoStream(src=0, resolution=(640, 640)).start()
#video_cap = cv2.VideoCapture(0)
#video_cap = cv2.VideoCapture("datasets\\Splash - 23011.mp4")
while True:
# start time to compute the fps
start = datetime.datetime.now()
frame = vs.read(); ret=True
#ret, frame = video_cap.read()
# if there are no more frames to process, break out of the loop
if not ret:
break
# run the YOLO model on the frame
detections = model(frame)[0]
# loop over the detections
#for data in detections.boxes.data.tolist():
for box in detections.boxes:
#extract the label name
label=model.names.get(box.cls.item())
# extract the confidence associated with the detection
data=box.data.tolist()[0]
confidence = data[4]
# filter out weak detections
if float(confidence) < CONFIDENCE_THRESHOLD:
continue
# draw the bounding box on the frame
xmin, ymin, xmax, ymax = int(data[0]), int(data[1]), int(data[2]), int(data[3])
cv2.rectangle(frame, (xmin, ymin) , (xmax, ymax), GREEN, 2)
#draw confidence and label
y = ymin - 15 if ymin - 15 > 15 else ymin + 15
cv2.putText(frame, "{} {:.1f}%".format(label,float(confidence*100)), (xmin, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, GREEN, 2)
# end time to compute the fps
end = datetime.datetime.now()
# show the time it took to process 1 frame
total = (end - start).total_seconds()
print(f"Time to process 1 frame: {total * 1000:.0f} milliseconds")
# calculate the frame per second and draw it on the frame
fps = f"FPS: {1 / total:.2f}"
cv2.putText(frame, fps, (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 2)
# show the frame to our screen
cv2.imshow("Frame", frame)
#press key Q to exit
if cv2.waitKey(1) == ord("q"):
break
#video_cap.release()
vs.stop()
cv2.destroyAllWindows()
Os resultados deste código mostram a deteção de objectos a uma velocidade de cerca de um fotograma por segundo (1 FPS, em comparação com 10FPS para um computador).
Velocidade melhorada
Executar um modelo de reconhecimento de objectos num Raspberry Pi é um verdadeiro desafio. Mas há formas de melhorar os resultados.
O nosso resultado básico é obtido utilizando o modelo yolov5nu com deteção a 1 fotograma por segundo (1 FPS).
Mudança de cartões
Para obter resultados de alto desempenho, é preferível recorrer a microcomputadores concebidos para trabalhar com inteligência artificial. Entre outras coisas, estas placas têm microprocessadores adaptados a estes volumes de cálculos (por exemplo, Nvidia Jetson).
Alterar a língua
O código aqui proposto é escrito em Python, mas existem versões lite escritas em C++ que aumentam consideravelmente a velocidade de execução.
Reduzir o número de imagens processadas
É possível reduzir a carga de processamento saltando imagens.
if img_counter % 5 == 0 :
detections = model(frame)[0]
img_counter+=1
