RK3588

cropped-2.8.1.png
51miz-P1371254-FUV9P8GX-3840x1711

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:

  1. Initialisiert die MIPI-CSI-Kamera mit OpenCV (GStreamer-Pipeline für RK3588).
  2. Lädt ein YOLOv5-Modell auf der NPU mit dem RKNN-Toolkit.
  3. Führt Echtzeit-Objekterkennung durch und zeichnet Bounding Boxes.
  4. Gibt den annotierten Videostream auf einem HDMI-Display aus.
  5. 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

  1. 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).
  2. 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.
  3. Preprocessing:
    • Skaliert das Bild auf 640×640 (YOLOv5-Standard), konvertiert in RGB und normalisiert die Pixelwerte.
  4. Postprocessing:
    • Wendet Non-Maximum-Suppression (NMS) an, um überlappende Bounding Boxes zu eliminieren.
    • Skaliert die Bounding Boxes auf die Originalauflösung (1920×1080).
  5. 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

  1. 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).
  2. 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.)

  3. 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.
  4. 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).

Ausführung

  1. Speichern Sie den Code als yolov5_rknn_surveillance.py.
  2. Platzieren Sie das yolov5s.rknn-Modell im gleichen Verzeichnis.
  3. Führen Sie den Code aus:
    bash
     
    python3 yolov5_rknn_surveillance.py
     
  4. 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.

Verwandte Beiträge

滚动至顶部