face_landmarks_single_face.py
# Dieses Werk ist unter der MIT-Lizenz lizenziert.
# Copyright (c) 2013-2025 OpenMV LLC. Alle Rechte vorbehalten.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Dieses Beispiel demonstriert Googles MediaPipe-Gesichtslandmarken-Erkennungsmodell für ein einzelnes Gesicht.
#
# HINWEIS: Für dieses Beispiel wird eine OpenMV Cam mit NPU wie die AE3 oder N6 benötigt, um in Echtzeit zu laufen.
import csi
import time
import ml
from ml.preprocessing import Normalization
from ml.postprocessing.mediapipe import BlazeFace
from ml.postprocessing.mediapipe import FaceLandmarks
# Sensor initialisieren.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
# BlazeFace benötigt für die besten Ergebnisse ein quadratisches Bild.
# FaceLandmarks funktioniert mit nicht-quadratischen Bildern aus BlazeFace-Zuschnitten.
csi0.window((400, 400))
# Eingebautes Gesichtserkennungsmodell laden
face_detection = ml.Model("/rom/blazeface_front_128.tflite", postprocess=BlazeFace(threshold=0.4))
print(face_detection)
# Eingebautes Gesichtslandmarken-Modell laden
face_landmarks = ml.Model("/rom/face_landmarks_192.tflite", postprocess=FaceLandmarks(threshold=0.4))
print(face_landmarks)
# Tracking-Variablen.
n = None
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
if n is None:
# faces ist eine Liste von ((x, y, w, h), score, keypoints)-Tupeln
for r, score, keypoints in face_detection.predict([img]):
# rect ist (x, y, w, h) - für das Gesichtslandmarken-Modell um das 2-Fache vergrößern
wider_rect = (r[0] - r[2] // 2, r[1] - r[3] // 2, r[2] * 2, r[3] * 2)
# Nur auf der ROI des erkannten Gesichts arbeiten
n = Normalization(roi=wider_rect)
else:
# marks ist eine Liste von ((x, y, w, h), score, keypoints)-Tupeln
marks = face_landmarks.predict([n(img)])
# Keine Gesichter erkannt, den Tracker zurücksetzen.
if not marks:
n = None
continue
# Begrenzungsrahmen um die erkannten Gesichter und Keypoints zeichnen.
for r, score, keypoints in marks:
ml.utils.draw_predictions(img, [r], ("face",), ((0, 0, 255),), format=None)
# keypoints ist ein ndarray der Form (468, 3), wobei jeder Keypoint (x, y, z) ist
ml.utils.draw_keypoints(img, keypoints, radius=0, color=(255, 0, 0))
# new_wider_rect zum Tracking auf dem Gesicht zentrieren
new_wider_rect = (r[0] + (r[2] // 2) - (wider_rect[2] // 2),
r[1] + (r[3] // 2) - (wider_rect[3] // 2),
wider_rect[2],
wider_rect[3])
# Nur auf der ROI des erkannten Gesichts arbeiten
n = Normalization(roi=new_wider_rect)
print(clock.fps(), "fps")