Gesichtserkennung in Echtzeit

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Salitek
User
Beiträge: 1
Registriert: Sonntag 19. November 2023, 19:47

Hallo liebe Community,

Ich beschäftige mich seit neuestem mit Python da ich es in meiner Technikerschule für mein Projekt benötige.
Dieses Projekt beinhaltet eine Echtzeit Gesichtserkennung, die ich mithilfe eines Tutorials programmiert habe und zuerst testen wollte, bevor Ich es auf meine Anforderungen anpasse.

Nun wird mein Gesicht erkannt, jedoch zeigt mir das Bildfenster "No match!" an und gibt mir folgenden Fehler aus:
Fehler bei der Gesichtserkennung: 'Unable to synchronously open object (bad symbol table node signature)'

Die verwendeten Bibliotheken sind aktuell und das Testbild kann ganz normal geöffnet werden und ist nicht beschädigt.

Hier noch mein Code:

import threading
import cv2
from deepface import DeepFace

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # Kamera initialisieren
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) # Video Breite
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # Video Höhe

counter = 0
face_match = False
known_img = cv2.imread("test_image.jpg")

def check_face(frame):
global face_match
try:
result = DeepFace.verify(frame, known_img.copy())
if result['verified']:
face_match = True
else:
face_match = False
except Exception as e:
print(f"Fehler bei der Gesichtserkennung: {e}")
face_match = False

while True:
ret, frame = cap.read()

if ret:
if counter % 100 == 0:
try:
threading.Thread(target=check_face, args=(frame.copy(),)).start()
except Exception as e:
print(f"Fehler beim Starten des Threads: {e}")

counter += 1

if face_match:
cv2.putText(frame, "Match!", (20, 450), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 3)
else:
cv2.putText(frame, "No match!", (20, 450), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)

cv2.imshow("video", frame)

key = cv2.waitKey(1)
if key == ord("q"):
break

cv2.destroyAllWindows()


Würde mich sehr freuen, wenn mir jemand weiter helfen könnte, da Ich noch nicht so viel Erfahrung mit Python gesammelt habe.

Mit freundlichen Grüßen,
Niklas
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Laut https://github.com/OlafenwaMoses/ImageAI/issues/131 deutet das auf korrupte Modeldaten hin. Mal neu installieren. Und threading würde ich erstmal rauslassen, auch das kann Probleme verursachen.
Benutzeravatar
__blackjack__
User
Beiträge: 13121
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Salitek: Anmerkungen zum Quelltext: Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

``global`` hat in einem sauberen Programm nichts zu suchen. An sich schon nicht, aber erst recht nicht wenn dann noch Threads verwendet werden. Funktionen und Methoden bekommen alles was sie ausser Konstanten benötigen, als Argument(e) übergeben.

Das heisst `check_face()` braucht (ohne Threads) einen Rückgabewert und `known_img` als Argument.

Warum wird `known_img` kopiert? Da wird doch nur lesend drauf zugegriffen‽

Das ``if``/``else`` bei ``result["verified"]`` ist überflüssig, weil *das* ja bereits das Ergebnis ist, beziehungsweise mit `bool()` in das Ergebnis umgewandelt werden kann.

Jegliche Ausnahme dort so zu behandeln ist nicht gut. Man behandelt damit auch Ausnahmen die man nicht erwartet und bekommt dann keinen Traceback der einem nähere Details verrät.

Beim starten des Threads würde ich gar keinen Fehler erwarten. Ausser dass da so schnell so viele Threads gestartet werden, das man das Limit erreicht. Dann hat man aber grössere Probleme als das man das im Grunde mit der Behandlung einfach ignorieren kann.

`destroyAllWindows()` wird so nie erreicht und auch die Kamera sollte man mit einem `release()`-Aufruf wieder freigeben. Das gehört in einen ``finally:``-Zweig.

Statt den `counter` manuell zu verwalten würde ich da eher `enumerate()` verwenden.

Farben als Tupel von drei Werten zwischen 0 und 255 literal in den Quelltext zu schreiben ist an sich in Ordnung, aber nicht bei OpenCV mit seiner BGR- statt RGB-Reihenfolge. Da würde ich immer mit Konstanten arbeiten um Verwirrung zu vermeiden.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import cv2
from deepface import DeepFace

BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (0, 0, 255)


def main():
    camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    try:
        camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

        known_image = cv2.imread("test_image.jpg")
        color, text = BLACK, ""
        frames = (frame for is_ok, frame in iter(camera.read, None) if is_ok)
        for frame_number, frame in enumerate(frames):
            if frame_number % 100 == 0:
                if DeepFace.verify(frame, known_image):
                    color, text = GREEN, "Match!"
                else:
                    color, text = RED, "No match!"

            cv2.putText(
                frame, text, (20, 450), cv2.FONT_HERSHEY_SIMPLEX, 2, color, 3
            )
            cv2.imshow("video", frame)
            if cv2.waitKey(1) == ord("q"):
                break

    finally:
        camera.release()
        cv2.destroyAllWindows()


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten