
Der Rockchip RK3588 ist dank seiner 6-TOPS-NPU, 48-MP-ISP und Unterstützung für Mehrkanal-Videoverarbeitung ideal für intelligente Überwachung und Sicherheitsanwendungen. Für das Szenario Intelligente Überwachung und Sicherheit wird häufig eine Kombination aus Videoeingang (z. B. MIPI-CSI-Kamera), KI-Inferenz (z. B. YOLOv5 für Objekterkennung) und Echtzeitverarbeitung benötigt. Nachfolgend sehen Sie einen ausgereiften Beispielcode, der auf einer typischen Anwendung basiert: Echtzeit-Objekterkennung mit YOLOv5 auf einer MIPI-CSI-Kamera, unter Verwendung des RKNN-Toolkits (Rockchip Neural Network) und Python. Dieser Code ist für RK3588-Entwicklungsboards (z. B. Forlinx FET3588-C, Geniatech DB3588V2) optimiert und nutzt die NPU für beschleunigte Inferenz.
Annahmen und Voraussetzungen
- Hardware: RK3588-Entwicklungsboard mit MIPI-CSI-Kamera (z. B. OV5647, IMX415 für 4K).
- Software: Ubuntu 20.04/22.04 oder Debian 11/12 mit vorinstalliertem RKNN-Toolkit (Version 1.7.0 oder höher), OpenCV und Python 3.8+.
- Modell: YOLOv5s (vorab in RKNN-Format konvertiert, z. B. yolov5s.rknn).
- Ziel: Echtzeit-Objekterkennung (z. B. Personen, Fahrzeuge) in einem Videostream mit Ausgabe auf HDMI oder Speicherung der Ergebnisse.
- Schnittstellen: MIPI-CSI für Kameraeingang, HDMI für Anzeige, optional NVMe/SATA für Speicherung.
Codebeschreibung
Der folgende Python-Code:
- Initialisiert die MIPI-CSI-Kamera mit OpenCV (GStreamer-Pipeline für RK3588).
- Lädt ein YOLOv5-Modell auf der NPU mit dem RKNN-Toolkit.
- Führt Echtzeit-Objekterkennung durch und zeichnet Bounding Boxes.
- Gibt den annotierten Videostream auf einem HDMI-Display aus.
- Speichert optional erkannte Objekte mit Zeitstempeln.
Beispielcode
import cv2
import numpy as np
from rknnlite.api import RKNNLite
import time
from datetime import datetime
# Konfiguration
MODEL_PATH = ‘./yolov5s.rknn’ # Pfad zum konvertierten RKNN-Modell
CAMERA_SRC = ‘v4l2src device=/dev/video0 ! video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! videoconvert ! appsink’
OUTPUT_CLASSES = [‘person’, ‘car’, ‘truck’, ‘bicycle’] # Klassen für YOLOv5
CONF_THRESHOLD = 0.5 # Konfidenzschwelle
NMS_THRESHOLD = 0.4 # Non-Maximum-Suppression-Schwelle
IMG_SIZE = (640, 640) # Eingabegröße für YOLOv5
# Hilfsfunktion für Preprocessing
def preprocess_image(img):
img_resized = cv2.resize(img, IMG_SIZE)
img_rgb = cv2.cvtColor(img_resized, cv2.COLOR_BGR2RGB)
img_norm = img_rgb.astype(np.float32) / 255.0
return img_norm
# Hilfsfunktion für Postprocessing (NMS)
def nms(boxes, scores, iou_threshold):
indices = cv2.dnn.NMSBoxes(boxes, scores, CONF_THRESHOLD, iou_threshold)
return indices
# Hauptprogramm
def main():
# RKNN-Initialisierung
rknn = RKNNLite()
print(“Lade RKNN-Modell…”)
ret = rknn.load_rknn(MODEL_PATH)
if ret != 0:
print(“Fehler beim Laden des Modells!”)
exit(ret)
ret = rknn.init_runtime()
if ret != 0:
print(“Fehler bei der Initialisierung der Runtime!”)
exit(ret)
# Kamera initialisieren
cap = cv2.VideoCapture(CAMERA_SRC, cv2.CAP_GSTREAMER)
if not cap.isOpened():
print(“Fehler beim Öffnen der Kamera!”)
exit(-1)
# Videoausgabe (optional)
fourcc = cv2.VideoWriter_fourcc(*’XVID’)
out = cv2.VideoWriter(‘output.avi’, fourcc, 30.0, (1920, 1080))
print(“Starte Echtzeit-Objekterkennung…”)
while True:
ret, frame = cap.read()
if not ret:
print(“Fehler beim Lesen des Frames!”)
break
# Preprocessing
img_input = preprocess_image(frame)
img_input = np.expand_dims(img_input, axis=0)
# Inferenz auf NPU
start_time = time.time()
outputs = rknn.inference(inputs=[img_input])
inference_time = time.time() – start_time
# Postprocessing
boxes, scores, classes = [], [], []
for output in outputs:
for pred in output[0]:
score = pred[4]
if score > CONF_THRESHOLD:
x_center, y_center, w, h = pred[:4]
x_min = int((x_center – w / 2) * frame.shape[1] / IMG_SIZE[0])
y_min = int((y_center – h / 2) * frame.shape[0] / IMG_SIZE[1])
x_max = int((x_center + w / 2) * frame.shape[1] / IMG_SIZE[0])
y_max = int((y_center + h / 2) * frame.shape[0] / IMG_SIZE[1])
boxes.append([x_min, y_min, x_max – x_min, y_max – y_min])
scores.append(score)
classes.append(int(pred[5]))
# NMS anwenden
indices = nms(boxes, scores, NMS_THRESHOLD)
# Bounding Boxes zeichnen
for i in indices:
box = boxes[i]
score = scores[i]
cls = classes[i]
x, y, w, h = box
label = f”{OUTPUT_CLASSES[cls]}: {score:.2f}”
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame, label, (x, y – 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
# Zeitstempel und Inferenzzeit anzeigen
timestamp = datetime.now().strftime(“%Y-%m-%d %H:%M:%S”)
cv2.putText(frame, f”Time: {timestamp}”, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
cv2.putText(frame, f”Inference: {inference_time:.3f}s”, (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
# Ausgabe auf HDMI
cv2.imshow(“Surveillance”, frame)
out.write(frame)
# Beenden mit ‘q’
if cv2.waitKey(1) & 0xFF == ord(‘q’):
break
# Aufräumen
cap.release()
out.release()
cv2.destroyAllWindows()
rknn.release()
if __name__ == “__main__”:
main()
Code-Erklärung
- Kameraeingang:
- Verwendet eine GStreamer-Pipeline (v4l2src) für MIPI-CSI-Kameraeingang, optimiert für RK3588.
- Standardauflösung: 1920×1080@30fps, anpassbar an Kameramodul (z. B. 4K für IMX415).
- RKNN-Inferenz:
- Lädt ein YOLOv5s-Modell (yolov5s.rknn), das zuvor mit dem RKNN-Toolkit von PyTorch nach RKNN konvertiert wurde.
- Nutzt die NPU für beschleunigte Inferenz, typische Latenz: ~30-50 ms pro Frame bei 1080p.
- Preprocessing:
- Skaliert das Bild auf 640×640 (YOLOv5-Standard), konvertiert in RGB und normalisiert die Pixelwerte.
- Postprocessing:
- Wendet Non-Maximum-Suppression (NMS) an, um überlappende Bounding Boxes zu eliminieren.
- Skaliert die Bounding Boxes auf die Originalauflösung (1920×1080).
- Ausgabe:
- Zeichnet Bounding Boxes und Labels (z. B. „person: 0.92“) auf den Frame.
- Zeigt den annotierten Stream auf einem HDMI-Display an und speichert ihn als Video (output.avi).
- Fügt Zeitstempel und Inferenzzeit zur Überwachung hinzu.
Voraussetzungen und Einrichtung
- RKNN-Toolkit Installation:
- Installieren Sie das RKNN-Toolkit auf dem RK3588-Board:bash
pip3 install rknn-toolkit-lite
- Stellen Sie sicher, dass die NPU-Treiber korrekt konfiguriert sind (siehe Rockchip-Dokumentation).
- Installieren Sie das RKNN-Toolkit auf dem RK3588-Board:
- YOLOv5-Modell Konvertierung:
- Laden Sie ein vortrainiertes YOLOv5s-Modell (PyTorch-Format) herunter.
- Konvertieren Sie es mit dem RKNN-Toolkit in das .rknn-Format:bash
python3 convert_yolov5.py --model yolov5s.pt --output yolov5s.rknn
(Hinweis: Der Konvertierungsschritt erfordert ein separates Setup, idealerweise auf einem x86-PC mit RKNN-Toolkit.)
- Abhängigkeiten:
- Installieren Sie OpenCV und NumPy:bash
pip3 install opencv-python numpy
- Stellen Sie sicher, dass GStreamer und V4L2-Treiber auf dem System verfügbar sind.
- Installieren Sie OpenCV und NumPy:
- Kamera-Konfiguration:
- Überprüfen Sie das Kameragerät mit:bash
ls /dev/video*
- Passen Sie CAMERA_SRC im Code an das richtige Gerät an (z. B. /dev/video0).
- Überprüfen Sie das Kameragerät mit:
Ausführung
- Speichern Sie den Code als yolov5_rknn_surveillance.py.
- Platzieren Sie das yolov5s.rknn-Modell im gleichen Verzeichnis.
- Führen Sie den Code aus:bash
python3 yolov5_rknn_surveillance.py
- Der Videostream wird auf dem HDMI-Display angezeigt. Drücken Sie q, um zu beenden.
Optimierungen und Erweiterungen
- Mehrkanal-Unterstützung: Fügen Sie mehrere cv2.VideoCapture-Instanzen für mehrere Kameras hinzu (z. B. 4x MIPI-CSI).
- Speicherung von Ereignissen: Speichern Sie Frames mit erkannten Objekten in ein Verzeichnis mit:python
if len(indices) > 0:
cv2.imwrite(f"detections/{timestamp}.jpg", frame) - Alarmierung: Implementieren Sie Benachrichtigungen (z. B. via MQTT) bei Erkennung bestimmter Klassen (z. B. „person“).
- Performance-Tuning: Reduzieren Sie die Eingabeauflösung (z. B. 1280×720) für höhere FPS auf Kosten der Genauigkeit.
- Integration mit NVR: Streamen Sie den annotierten Videofeed über RTSP mit GStreamer:bash
! appsrc ! videoconvert ! x264enc ! rtspclientsink location=rtsp://<server>:8554/stream
Hinweise
- Modellgenauigkeit: YOLOv5s ist ein leichtgewichtiges Modell. Für höhere Genauigkeit können YOLOv5m oder YOLOv8 verwendet werden (erfordert mehr NPU-Ressourcen).
- NPU-Last: Die NPU unterstützt bis zu 6 TOPS, aber Mehrkanal-Inferenz kann die CPU belasten. Verwenden Sie Multithreading für parallele Streams.
- Stromverbrauch: Bei hoher Last (z. B. 4K-Video + NPU) ist ein Kühlkörper erforderlich, um Überhitzung zu vermeiden.
- Lizenzierung: Stellen Sie sicher, dass das YOLOv5-Modell und das RKNN-Toolkit den Lizenzanforderungen Ihres Projekts entsprechen.