Die Objekterkennung wird zunehmend in alltäglichen Anwendungen eingesetzt, sei es in sicherheitskritischen Bereichen oder bei präzisen Aufgaben wie der Erkennung von Sicherheitshelmen. Während die Arbeit mit neuronalen Netzwerken früher als hochspezialisiertes Feld galt, gibt es heute dank rascher technologischer Fortschritte viele leistungsstarke vortrainierte Modelle wie Ultralytics YOLO und MobileNet SSD.
Bis vor kurzem war es eine Herausforderung, Objekterkennungsalgorithmen auf ressourcenbeschränkten Geräten wie dem Raspberry Pi auszuführen. Obwohl der Raspberry Pi ein leistungsfähiger Einplatinencomputer ist, konnte er bei KI-Aufgaben nicht mit Desktop-Computern mit GPUs mithalten. Mit der Veröffentlichung des Raspberry Pi AI Kits durch die Raspberry Pi Foundation hat sich dies jedoch geändert. Dieses AI-Modul ist ein 13-TOPS-neuronaler-Netzwerk-Inferenzbeschleuniger, der auf dem Hailo-8L-Chip basiert und speziell für energieeffiziente KI-Anwendungen entwickelt wurde.
In diesem Tutorial zeige ich dir, wie du auf dem Raspberry Pi 5 Board mithilfe des Raspberry Pi AI Kits eine Objekterkennung durchführen kannst. Ich werde das benutzerdefinierte ONNX-Modell in ein Format konvertieren, das mit der Hailo-Hardware kompatibel ist.
Vorbereitung des Datensatzes
Der verwendete Datensatz enthält 5000 Bilder mit Bounding-Box-Anmerkungen im PASCAL VOC-Format für die folgenden drei Klassen: Helm, Person und Kopf. Du kannst den Datensatz unter zdataset.com herunterladen.
Der folgende Code kann verwendet werden, um die Bounding-Box-Koordinaten im Datensatz vom PASCAL VOC-Format in das für YOLOv8 erforderliche Format zu konvertieren:
from xml.dom import minidom
import os
classes={"helmet":0,"head":1,"person":2}
def convert_coordinates(size, box):
dw = 1.0/size[0]
dh = 1.0/size[1]
x = (box[0]+box[1])/2.0
y = (box[2]+box[3])/2.0
w = box[1]-box[0]
h = box[3]-box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)
def converter(classes):
old_labels_path = "./data/annotations_old/"
new_labels_path = "./data/labels/"
for file_name in os.listdir(old_labels_path):
old_file = minidom.parse(f"{old_labels_path}/{file_name}")
name_out = (file_name[:-4]+'.txt')
with open(f"{new_labels_path}/{name_out}", "w") as new_file:
itemlist = old_file.getElementsByTagName('object')
size = old_file.getElementsByTagName('size')[0]
width = int((size.getElementsByTagName('width')[0]).firstChild.data)
height = int((size.getElementsByTagName('height')[0]).firstChild.data)
for item in itemlist:
class_name = (item.getElementsByTagName('name')[0]).firstChild.data
if class_name in classes:
label_str = str(classes[class_name])
else:
label_str = "-1"
print (f"{class_name} not in function classes")
xmin = ((item.getElementsByTagName('bndbox')[0]).getElementsByTagName('xmin')[0]).firstChild.data
ymin = ((item.getElementsByTagName('ymin')[0]).firstChild.data)
xmax = ((item.getElementsByTagName('xmax')[0]).firstChild.data)
ymax = ((item.getElementsByTagName('ymax')[0]).firstChild.data)
b = (float(xmin), float(xmax), float(ymin), float(ymax))
bb = convert_coordinates((width,height), b)
new_file.write(f"{label_str} {' '.join([f'{a:.6f}' for a in bb])}\n")
print (f"wrote {name_out}")
def main():
converter(classes)
if __name__ == '__main__':
main()
Nach der Datenerhebung und -verarbeitung besteht der nächste Schritt darin, YOLOv8 mithilfe von Transfer Learning mit dem neuen Modell neu zu trainieren.
YOLOv8 auf einem benutzerdefinierten Datensatz trainieren
Die Erstellung von KI-Modellen von Grund auf kann kompliziert sein. Glücklicherweise gibt es viele vortrainierte Modelle, die du für verschiedene Zwecke verwenden kannst. Transfer Learning ist eine Technik, bei der ein vorhandenes oder vortrainiertes Modell als Grundlage für das neue Modell verwendet wird.
Ich werde das Ultralytics-Paket verwenden, um mit YOLOv8 zu arbeiten. Um YOLOv8 über pip zu installieren, verwende den folgenden Befehl:
pip install ultralytics
Stelle sicher, dass dein benutzerdefinierter Datensatz korrekt organisiert ist. Bilder und deren entsprechende Anmerkungen müssen in einem bestimmten Format gespeichert werden, das YOLOv8 versteht.
Verwende das Kommandozeilenprogramm yolo, das von YOLOv8 bereitgestellt wird, um das Training zu starten. Hier ist der Befehl zum Training von YOLOv8 mit deinem benutzerdefinierten Datensatz:
yolo task=detect \
mode=train \
model=yolov8n.pt \
data=./data.yaml \
epochs=100 \
imgsz=640 \
batch=32
YOLOv8 zeigt Trainingsfortschrittsmetriken wie Verlust und Mean Average Precision (mAP) an.
Wenn das Training abgeschlossen ist, muss das Modell ins ONNX-Format exportiert werden. Modelle im ONNX-Format können in vielen großen maschinellen Lernframeworks ausgeführt werden.
Exportiere das trainierte Modell ins ONNX-Format mit folgendem Befehl:
yolo export model=/home/admin2/Projects/training/runs/detect/train6/weights/best.pt imgsz=640 format=onnx opset=11
Sobald der Export abgeschlossen ist, können wir mit den nächsten Schritten fortfahren.
Datenfluss-Compiler herunterladen und installieren
Besuche die Hailo Developer Zone Software-Downloads, um den Hailo Dataflow Compiler herunterzuladen.
Öffne ein Terminalfenster und navigiere zum Verzeichnis, in dem du die Wheel-Datei heruntergeladen hast. Installiere den Compiler mit folgendem Befehl:
pip3 install ./hailo_dataflow_compiler-3.28.0-py3-none-linux_x86_64.whl
Klonen das Hailo Model Zoo Repository:
git clone https://github.com/hailo-ai/hailo_model_zoo.git
Navigiere zum Verzeichnis hailo_model_zoo:
pip install -e .
Konvertiere das ONNX-Modell in ein Hailo-kompatibles Format mit folgendem Befehl:
python hailo_model_zoo/main.py compile yolov8n --ckpt ../Safety-Helmet-Detection/output/best.onnx --hw-arch hailo8l --calib-path ../Safety-Helmet-Detection/data/images --classes 3 --performance
Der Output zeigt Informationen zur Ressourcennutzung während des Konvertierungsprozesses an:
[info] context_0 utilization:
[info] +-----------+---------------------+---------------------+--------------------+
[info] | Cluster | Control Utilization | Compute Utilization | Memory Utilization |
[info] +-----------+---------------------+---------------------+--------------------+
[info] | cluster_0 | 100% | 43,8% | 46,1% |
[info] | cluster_1 | 100% | 68,8% | 59,4% |
[info] | cluster_4 | 62,5% | 46,9% | 43% |
[info] | cluster_5 | 100% | 46,9% | 48,4% |
[info] +-----------+---------------------+---------------------+--------------------+
[info] | Total | 90,6% | 51,6% | 49,2% |
[info] +-----------+---------------------+---------------------+---------------------+
[info] context_1 utilization:
[info] +-----------+---------------------+---------------------+---------------------+
[info] | Cluster | Control Utilization | Compute Utilization | Memory Utilization |
[info] +-----------+---------------------+---------------------+---------------------+
[info] | cluster_0 | 87,5% | 60,9% | 48,4% |
[info] | cluster_1 | 75% | 100% | 53,9% |
[info] | cluster_4 | 93,8% | 81,3% | 57% |
[info] | cluster_5 | 100% | 75% | 58,6% |
[info] +-----------+---------------------+---------------------+--------------------+
[info] | Total | 89,1% | 79,3% | 54,5% |
[info] +-----------+---------------------+---------------------+--------------------+
[info] Successful Mapping (allocation time: 5m 16s)
[info] Compiling context_0...
[info] Compiling context_1...
[info] Bandwidth of model inputs: 9.375 Mbps, outputs: 4.29382 Mbps (for a single frame)
[info] Bandwidth of DDR buffers: 0.0 Mbps (for a single frame)
[info] Bandwidth of inter context tensors: 17.1875 Mbps (for a single frame)
[info] Compiling context_0...
[info] Compiling context_1...
[info] Bandwidth of model inputs: 9.375 Mbps, outputs: 4.29382 Mbps (for a single frame)
[info] Bandwidth of DDR buffers: 0.0 Mbps (for a single frame)
[info] Bandwidth of inter context tensors: 17.1875 Mbps (for a single frame)
[info] Building HEF...
[info] Successful Compilation (compilation time: 10s)
[info] Saved HAR to: /home/admin2/Projects/hailo_model_zoo/yolov8n.har
<Hailo Model Zoo INFO> HEF file written to yolov8n.hef
Die erfolgreiche Kompilierung resultiert in einer Hailo Executable Format (HEF) Datei, die normalerweise im aktuellen Verzeichnis mit einem Namen wie yolov8n.hef gespeichert wird. Das Modell ist nun einsatzbereit.
Hailo Raspberry Pi Projekt installieren
Klonen das Repository von GitHub:
git clone https://github.com/hailo-ai/hailo-rpi5-examples.git
Um die Inferenz-Ergebnisse direkt in eine Datei zu speichern, habe ich die Datei basic_pipelines/detection.py durch Ersetzen der folgenden Zeile modifiziert:
+ QUEUE("queue_hailo_display") + f"fpsdisplaysink video-sink={self.video_sink} name=hailo_display sync={self.sync} text-overlay={self.options_menu.show_fps} signal-fps-measurements=true "
mit der folgenden Zeile:
+ "x264enc bitrate=5000 speed-preset=medium ! mp4mux ! filesink location=detection_output.mp4 "
Diese Änderung ersetzt die Hailo-Anzeigewarteschlange durch einen x264-Encoder zur Video-Codierung und speichert die Ergebnisse in einer Datei namens detection_output.mp4.
Verwende dann den folgenden Befehl, um die Inferenz auf einer Videodatei mit dem kompilierten Modell auszuführen:
python basic_pipelines/safety_detection.py --labels-json ./safety-labels.json --hef ./yolov8n.hef -i ./test5.mp4
Hier ist ein praktisches Beispiel für die Sicherheitshelm-Erkennung mit dem Ultralytics YOLOv8n-Modell, das beeindruckende 30 FPS Inferenzgeschwindigkeit erreicht. Detektierte Objekte werden in Echtzeit mit Bounding-Boxen und Labels versehen. Bei der Objekterkennung besteht immer ein Kompromiss zwischen Genauigkeit und Geschwindigkeit. Es ist wichtig, die spezifischen Anforderungen deiner Anwendung zu berücksichtigen und das richtige Gleichgewicht zwischen Genauigkeit und Geschwindigkeit zu wählen
Schlusswort
Dieser Leitfaden zeigt dir, wie du das Raspberry Pi AI Kit mit Hailo-Hardware nutzen kannst, um eine effiziente KI-Inferenz zur Sicherheitshelm-Erkennung zu erreichen. Der beschriebene Ansatz kann an verschiedene Anwendungen angepasst werden, um leistungsstarke Objekterkennungsnetzwerke zu erstellen.
Nachdem ich das benutzerdefinierte Modell trainiert und in einem realen Szenario getestet habe, bist du nun in der Lage, mit den gewonnenen Kenntnissen eigene benutzerdefinierte Objekterkennungsmodelle auf dem Raspberry Pi 5 Board zu erstellen und zu trainieren.
Viel Spaß beim Entwickeln!
Danksagung
Die Videoaufnahmen, die in dieser Demonstration verwendet wurden, stammen mit freundlicher Genehmigung von Los Muertos Crew und Akin Victor.
Danke an die Teams von Raspberry Pi und Hailo für ihre großartige Arbeit am Raspberry Pi AI Kit, das diesen Leitfaden ermöglicht hat.
Shakhizat Nurgaliyev
Wir freuen uns, diesen spannenden Artikel von Shakhizat Nurgaliyev präsentieren zu dürfen. Shakhizat ist ein engagierter Entwicklungsingenieur für eingebettete Systeme und verfügt über umfassende Expertise in den Bereichen Robotik und Internet der Dinge (IoT). Seine Spezialisierung liegt in der Entwicklung autonomer und intelligenter Systeme, die maschinelles Lernen einsetzen, um auf ihre Umgebung zu reagieren. Mit seiner umfangreichen Erfahrung, die von der Konzeption bis hin zur Programmierung reicht, leistet er einen bedeutenden Beitrag zur Weiterentwicklung von Robotik und IoT.