OpenCV Gesichtserkennung
@DonJuan: Dein Skript ist schwer zu lesen, weil Du verschiedene logische Teile vermischst, Pfad anlegen, Video-Capture, Counter. Der Counter wird erst direkt vor der while-Schleife gebraucht, sollte also erst dort definiert werden.
Es gibt in Python eine Namenskonvention, dass alle Variablen klein_mit_unterstrich geschrieben werden. Abkürzungen sollten vermieden werden. vname -> vorname. Was soll st oder ts bedeuten? Beim Lesen muß man da raten.
Zeiten formatiert man am besten in der Form "%Y-%m-%d_%H-%M-%S", dann lassen sie sich einfach lexikalisch sortieren.
Dass Cascades relativ zum Programmcode liegt (was Du nicht erzwingst) ist für mich noch logisch, die Daten, die Du schreibst, erwartet man aber relativ zum Arbeitsverzeichnis.
os.makedirs kennt ein exist_ok-Argument, das ist sicherer, als zu prüfen, ob das Verzeichnis existiert. Das erste makedirs ist überflüssig, weil es mit dem zweiten automatisch erzeugt wird.
Die meisten der str-Aufrufe sind überflüssig, weil es sowieso schon Strings sind. Besser ist es aber, die Dateinamen per format zu erzeugen:
Es gibt in Python eine Namenskonvention, dass alle Variablen klein_mit_unterstrich geschrieben werden. Abkürzungen sollten vermieden werden. vname -> vorname. Was soll st oder ts bedeuten? Beim Lesen muß man da raten.
Zeiten formatiert man am besten in der Form "%Y-%m-%d_%H-%M-%S", dann lassen sie sich einfach lexikalisch sortieren.
Dass Cascades relativ zum Programmcode liegt (was Du nicht erzwingst) ist für mich noch logisch, die Daten, die Du schreibst, erwartet man aber relativ zum Arbeitsverzeichnis.
os.makedirs kennt ein exist_ok-Argument, das ist sicherer, als zu prüfen, ob das Verzeichnis existiert. Das erste makedirs ist überflüssig, weil es mit dem zweiten automatisch erzeugt wird.
Die meisten der str-Aufrufe sind überflüssig, weil es sowieso schon Strings sind. Besser ist es aber, die Dateinamen per format zu erzeugen:
Code: Alles auswählen
current_time = datetime.datetime.now()
...
file_name = os.path.join(Namenpfad, "{} {:%Y-%m-%d_%H-%M-%S} - c {}.jpg".format(name, current_time, counter))
Vielen Dank erstmal für die Hilfe. Ich habe es versucht umzusetzen. Wie gesagt ich bin Neuling in diesem Gebiet.
Es funktioniert wieder alles bis auf das er die Datei nicht abspeichert. Ich habe mir mit print() ausgeben lassen:
...\Personen\Max Mustermann\Max Mustermann 2018-08-25_11-40-03 - c 4.jpg
Aber im Ordner ist keine Datei.
Es funktioniert wieder alles bis auf das er die Datei nicht abspeichert. Ich habe mir mit print() ausgeben lassen:
...\Personen\Max Mustermann\Max Mustermann 2018-08-25_11-40-03 - c 4.jpg
Aber im Ordner ist keine Datei.
Code: Alles auswählen
import cv2
import os
import time
import datetime
vname = input("Bitte Vorname eingeben: ")
nname = input("Bitte Nachname eingeben: ")
name = vname + " " + nname
if not os.path.exists('./Personen/' + name):
os.makedirs('./Personen/' + name)
face_cascade = cv2.CascadeClassifier('Cascades/haarcascade_frontalface_default.xml')
cam = cv2.VideoCapture(0)
Basispfad = os.path.dirname(os.path.abspath(__file__))
Personenpfad = os.path.join(Basispfad, "Personen")
Namenpfad = os.path.join(Personenpfad, name)
current_time = datetime.datetime.now()
counter = 0
while counter < 5:
ret, img_frame = cam.read()
gray = cv2.cvtColor(img_frame,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
roi_gray = gray[y:y + h, x:x + w]
roi_color = img_frame[y:y + h, x:x + w]
cv2.rectangle(gray, (x, y), (x + w, y + h), (255, 0, 0), 2)
file_name = os.path.join(Namenpfad, "{} {:%Y-%m-%d_%H-%M-%S} - c {}.jpg".format(name, current_time, counter))
print(file_name)
cv2.imwrite(file_name + ".jpg", roi_gray)
cv2.waitKey(300)
cv2.imshow('Gesichtsspeicherung',gray)
counter += 1
if cv2.waitKey(1) & 0xFF == ord('q'):
break
print ('Gesichtsspeicherung abgeschlossen')
cam.release()
cv2.destroyAllWindows()
Ich verstehe momentan nicht woran es liegen könnte...
ich erstelle den Pfad:
Ausgabe:
...\Personen\Max Mustermann
Dann speichere ich innerhalb dieses Pfads das Bild unter dem Namen: file_name ab, oder habe ich da einen Denkfehler?
Es tut mir leid das ich da so nach hake, aber ich sitze schon seit heute morgen um 05:00 Uhr an diesem Problem
ich erstelle den Pfad:
Code: Alles auswählen
Namenpfad = os.path.join(Personenpfad, name)
...\Personen\Max Mustermann
Dann speichere ich innerhalb dieses Pfads das Bild unter dem Namen: file_name ab, oder habe ich da einen Denkfehler?
Code: Alles auswählen
cv2.imwrite(file_name, roi_gray)
meine Gedanken/Fragen dazu:
- im Code oben wird dem Dateinamen zweimal .jpg zugewiesen
- wird das Unterverzeichnis mit dem Personennamen auch erstellt?
- wenn es ein Verzeichnis mit dem Namen der Person gibt, warum wird dem Dateinamen nochmals der Personenname zugewiesen?
- cv2.imwrite() liefert ein Boolean zurück, gib das mal aus, ich vermute False deutet auf einen Fehler beim schreiben
- gib imwrite mal manuell einen Pfadnamen ala imwrite('C:\cv2testdatei.jpg', roi_gray), wird diese Datei geschrieben?
- im Code oben wird dem Dateinamen zweimal .jpg zugewiesen
- wird das Unterverzeichnis mit dem Personennamen auch erstellt?
- wenn es ein Verzeichnis mit dem Namen der Person gibt, warum wird dem Dateinamen nochmals der Personenname zugewiesen?
- cv2.imwrite() liefert ein Boolean zurück, gib das mal aus, ich vermute False deutet auf einen Fehler beim schreiben
- gib imwrite mal manuell einen Pfadnamen ala imwrite('C:\cv2testdatei.jpg', roi_gray), wird diese Datei geschrieben?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Habe mal aus Spaß an der Freud opencv installiert und deinen Code in einem Jupyter Notebook ausprobiert.
Der Ordner "Personen" mit Unterordner "Vorname Nachname" wird erstellt.
Die Bilddateien werden problemlos geschrieben, haben aber .jpg.jpg am Ende. Naja, leicht zu ändern.
Das bei dir keine Dateien geschrieben werden, liegt also nicht am Code.
cv2.imwrite() liefert bei mir True zurück, Dateien werden ja auch erstellt. Was gibt es bei dir zurück?
Der Ordner "Personen" mit Unterordner "Vorname Nachname" wird erstellt.
Die Bilddateien werden problemlos geschrieben, haben aber .jpg.jpg am Ende. Naja, leicht zu ändern.
Das bei dir keine Dateien geschrieben werden, liegt also nicht am Code.
cv2.imwrite() liefert bei mir True zurück, Dateien werden ja auch erstellt. Was gibt es bei dir zurück?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
@DonJuan: Du erzeugst den Pfad './Personen/' + name willst aber in os.path.join(Basispfad, "Personen", name) schreiben. Solange Du den Pfad auf zwei verschiedene Arten zusammensetzt, kann es halt sein, dass zwei verschiedene Orte dabei rauskommen. Die Lösung ist, die Variable »Namenpfad« so zu definieren, wie Du es möchtest (also entweder relativ zum Skript oder zum Arbeitsverzeichnis) und sie überall zu benutzen.
@ThomasL: danke ThomasL, dass Du den OP weiter verwirrst, indem Du schreibst, sein Code wäre richtig, obwohl schon drei andere Leute geduldig versuchen, ihm den Fehler, den er macht zu erklären.
@ThomasL: danke ThomasL, dass Du den OP weiter verwirrst, indem Du schreibst, sein Code wäre richtig, obwohl schon drei andere Leute geduldig versuchen, ihm den Fehler, den er macht zu erklären.
Kann jetzt schlecht Bitte sagen, zu verwirren war ja nicht meine Absicht.
Ich stimme dir zu, mit der Aussage "liegt also nicht am Code" habe ich mich etwas zu weit aufs Glatteis gewagt.
Aus der Tatsache, dass der Code bei mir funktioniert auf Korrektheit in anderen Umgebungen zu schließen,
ist vermessen und da es bei ihm ja nicht läuft sogar falsch.
Da bin ich im Eifer übers Ziel hinaus geschossen.
Ich stimme dir zu, mit der Aussage "liegt also nicht am Code" habe ich mich etwas zu weit aufs Glatteis gewagt.
Aus der Tatsache, dass der Code bei mir funktioniert auf Korrektheit in anderen Umgebungen zu schließen,
ist vermessen und da es bei ihm ja nicht läuft sogar falsch.
Da bin ich im Eifer übers Ziel hinaus geschossen.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Hallo, ich bin ganz neu im Forum und glaube, dass meine Frage hier ganz gut reinpasst, auch wenn sie mit der Ursprungsfrage nichts zu tun hat.
Folgender Code greift die Koordinaten des erkannten Bildes ab und macht es unscharf, um es dann anzuzeigen.
roi_color = img_frame[y:y + h, x:x + w]
roi_color = cv2.GaussianBlur(roi_color, (21,21), 0)
cv2.imshow("unscharf", roi_color)
Was ich möchte, ist aber kein neues Fenster, sondern dass direkt im Originalbild das Gesicht unscharf gezeichnet wird. Wie mache ich das?
Vielen Dank im Voraus!
Folgender Code greift die Koordinaten des erkannten Bildes ab und macht es unscharf, um es dann anzuzeigen.
roi_color = img_frame[y:y + h, x:x + w]
roi_color = cv2.GaussianBlur(roi_color, (21,21), 0)
cv2.imshow("unscharf", roi_color)
Was ich möchte, ist aber kein neues Fenster, sondern dass direkt im Originalbild das Gesicht unscharf gezeichnet wird. Wie mache ich das?
Vielen Dank im Voraus!
- __blackjack__
- User
- Beiträge: 13099
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Vicky: Wie kann eine Frage hier ganz gut reinpassen die nichts mit der ursprünglichen Frage zu tun hat?
Wenn Du `img_frame` ändern möchtest, müsstest Du das Ergebnis von `GaussianBlur` wieder dem Bildausschnitt zuweisen.
Wenn Du `img_frame` ändern möchtest, müsstest Du das Ergebnis von `GaussianBlur` wieder dem Bildausschnitt zuweisen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Super, vielen Dank, hat geklappt! Nächste Challenge: ich möchte das Gesicht nicht verschwommen anzeigen, sondern ein anderes Gesicht vor das Originalgesicht einblenden. Dazu habe ich eine Datei erstellt (sarah_gesicht_klein.jpg), die nur das Gesicht enthält. Es kommt aber ein Value Error could not broadcast input array from shape (594,480,3) into shape (175,175,3). Die Bildgröße der einzufügenden Datei mittels cv2.resize zu verändern bringt nichts, weil die Bezugsgröße sich ständig ändert. Wer weiß eine Lösung? Vielen Dank!
import cv2
video = cv2.VideoCapture(0)
sarah = cv2.imread("sarah_gesicht_klein.jpg")
while True:
check, frame = video.read()
frame = cv2.flip(frame, 1)
result_image = frame.copy()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
classifier = cv2.CascadeClassifier("c:/Users/vw/Kursmaterialien/data/haarcascades/haarcascade_frontalface_alt2.xml")
faces = classifier.detectMultiScale(gray, 1.1, minNeighbors=8)
for x, y, w, h in faces:
roi_color = frame[y:y + h, x:x + w]
result_image[y:y + roi_color.shape[0], x:x + roi_color.shape[1]] = sarah
cv2.imshow("Test", result_image)
key = cv2.waitKey(1)
if key == ord("q"):
break
print(frame)
video.release()
cv2.destroyAllWindows()
import cv2
video = cv2.VideoCapture(0)
sarah = cv2.imread("sarah_gesicht_klein.jpg")
while True:
check, frame = video.read()
frame = cv2.flip(frame, 1)
result_image = frame.copy()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
classifier = cv2.CascadeClassifier("c:/Users/vw/Kursmaterialien/data/haarcascades/haarcascade_frontalface_alt2.xml")
faces = classifier.detectMultiScale(gray, 1.1, minNeighbors=8)
for x, y, w, h in faces:
roi_color = frame[y:y + h, x:x + w]
result_image[y:y + roi_color.shape[0], x:x + roi_color.shape[1]] = sarah
cv2.imshow("Test", result_image)
key = cv2.waitKey(1)
if key == ord("q"):
break
print(frame)
video.release()
cv2.destroyAllWindows()