OpenCV Gesichtserkennung
Guten Morgen zusammen,
erst einmal zur Ausgangslage:
Zur Zeit schreibe ich meine Masterarbeit im Bereich Softwareentwicklung zur Gesichtserkennung. Da ich eigentlich Betriebswirtschaftslehre studiere bin ich was die Programmierung anbelangt Anfänger. Aber ich möchte mich mit dem Thema auseinander setzen, weil aufbauend auf diesem Programm eine "Business Intelligence" eingerichtet werden soll, die die Zeitstempel grafisch darstellt.
Wie gesagt, es soll ein einfaches Programm werden um das zu veranschaulichen, was ich innerhalb meiner Masterthesis schreibe.
So sollte es funktionieren:
1. Gesicht wird erkannt
2. Es werden Bilder gemacht und in einem Ordner abgelegt
3. Gesichtserkennung greift darauf zu und schaut ob die Person innerhalb der Ordner vorhanden ist. Wenn ja: Ausgabe Name, wenn nein: Ausgabe unbekannt
4. Später soll alles auf eine Datenbank gelegt werden (Vorname, Name, Zeitstempel)
5. Business Intelligence greift auf Datenbank zu und gibt grafisch die Zeitstempel aus
Mein Vorgehen ist im Moment:
1. Gesichtsdetektion schreiben: Habe ich realisiert
2. Gesichtsspeicherung via Webcam: Dort hänge ich momentan
Es soll der Name eingegeben werden und anhand dieses Namens ein neuer Ordner erstellt werden worin die 200 Trainingsbilder eingepflegt werden.
Dies funktioniert aber nicht. Er hat Probleme in dieser Zeile = cv2.imwrite(path + str(ID) + "." + str(count) + ".jpg")
Fehler ist:
Bitte Name eingeben: Dominik
Traceback (most recent call last):
File "C:/Users/Dominik/Desktop/PythonMasterarbeit/GesichtsspeicherungWebcam.py", line 27, in <module>
cv2.imwrite(path + str(ID) + "." + str(count) + ".jpg")
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
[ INFO:0] Initialize OpenCL runtime...
Quellcode:
import cv2
import os
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('Haar/haarcascade_eye.xml')
ID = input("Bitte Vorname eingeben: ")
count = 0
cam = cv2.VideoCapture(0)
path = os.makedirs("/" + ID)
while (cam.isOpened()):
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:
cv2.rectangle(gray, (x, y), (x + w, y + h), (255, 255, 255), 2)
count +=1
cv2.imwrite(path + str(ID) + "." + str(count) + ".jpg")
cv2.imshow("Gesichtsspeicherung",img_frame)
if cv2.waitkey(100) & 0xFF == ord("q"):
break
elif count>200:
break
cam.release()
cv2.destroyAllWindows()
Da ich das erste Mal in einem Forum unterwegs bin hoffe ich, das ich alle Informationen aufgeschrieben habe und ihr mir weiter helfen könnt.
Vielen Dank schon mal!
erst einmal zur Ausgangslage:
Zur Zeit schreibe ich meine Masterarbeit im Bereich Softwareentwicklung zur Gesichtserkennung. Da ich eigentlich Betriebswirtschaftslehre studiere bin ich was die Programmierung anbelangt Anfänger. Aber ich möchte mich mit dem Thema auseinander setzen, weil aufbauend auf diesem Programm eine "Business Intelligence" eingerichtet werden soll, die die Zeitstempel grafisch darstellt.
Wie gesagt, es soll ein einfaches Programm werden um das zu veranschaulichen, was ich innerhalb meiner Masterthesis schreibe.
So sollte es funktionieren:
1. Gesicht wird erkannt
2. Es werden Bilder gemacht und in einem Ordner abgelegt
3. Gesichtserkennung greift darauf zu und schaut ob die Person innerhalb der Ordner vorhanden ist. Wenn ja: Ausgabe Name, wenn nein: Ausgabe unbekannt
4. Später soll alles auf eine Datenbank gelegt werden (Vorname, Name, Zeitstempel)
5. Business Intelligence greift auf Datenbank zu und gibt grafisch die Zeitstempel aus
Mein Vorgehen ist im Moment:
1. Gesichtsdetektion schreiben: Habe ich realisiert
2. Gesichtsspeicherung via Webcam: Dort hänge ich momentan
Es soll der Name eingegeben werden und anhand dieses Namens ein neuer Ordner erstellt werden worin die 200 Trainingsbilder eingepflegt werden.
Dies funktioniert aber nicht. Er hat Probleme in dieser Zeile = cv2.imwrite(path + str(ID) + "." + str(count) + ".jpg")
Fehler ist:
Bitte Name eingeben: Dominik
Traceback (most recent call last):
File "C:/Users/Dominik/Desktop/PythonMasterarbeit/GesichtsspeicherungWebcam.py", line 27, in <module>
cv2.imwrite(path + str(ID) + "." + str(count) + ".jpg")
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
[ INFO:0] Initialize OpenCL runtime...
Quellcode:
import cv2
import os
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('Haar/haarcascade_eye.xml')
ID = input("Bitte Vorname eingeben: ")
count = 0
cam = cv2.VideoCapture(0)
path = os.makedirs("/" + ID)
while (cam.isOpened()):
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:
cv2.rectangle(gray, (x, y), (x + w, y + h), (255, 255, 255), 2)
count +=1
cv2.imwrite(path + str(ID) + "." + str(count) + ".jpg")
cv2.imshow("Gesichtsspeicherung",img_frame)
if cv2.waitkey(100) & 0xFF == ord("q"):
break
elif count>200:
break
cam.release()
cv2.destroyAllWindows()
Da ich das erste Mal in einem Forum unterwegs bin hoffe ich, das ich alle Informationen aufgeschrieben habe und ihr mir weiter helfen könnt.
Vielen Dank schon mal!
Moin,
in Foren wird es normalerweise gern gesehen, wenn man abschließend seine Lösung veröffentlicht. So können andere, die eventuell das gleiche Problem haben, auch von der Lösung profitieren.
Außerdem sollte Quelltext in Codebox-Tags („Code auswählen“ direkt über dem Editor-Textfeld) gesetzt werden, damit die Einrückung erhalten bleibt. Das macht es allen Beteiligten leichter, den Code zu lesen.
Zum Code: Du könntest dir mal Stringformatierung sowie die Module `os.path` und `pathlib` angucken. Damit kann man das Zusammenbauen des Dateinamens sehr viel eleganter ausdrücken.
Ansonsten noch viel Erfolg bei deiner Masterarbeit!
in Foren wird es normalerweise gern gesehen, wenn man abschließend seine Lösung veröffentlicht. So können andere, die eventuell das gleiche Problem haben, auch von der Lösung profitieren.
Außerdem sollte Quelltext in Codebox-Tags („Code auswählen“ direkt über dem Editor-Textfeld) gesetzt werden, damit die Einrückung erhalten bleibt. Das macht es allen Beteiligten leichter, den Code zu lesen.
Zum Code: Du könntest dir mal Stringformatierung sowie die Module `os.path` und `pathlib` angucken. Damit kann man das Zusammenbauen des Dateinamens sehr viel eleganter ausdrücken.
Ansonsten noch viel Erfolg bei deiner Masterarbeit!
Hallo noch einmal,
tut mir leid für die späte Antwort. Ich hatte viele Abstimmungen mit meinem Professor.
Ich werde am Ende mein Ergebnis hier ins Forum stellen, damit alle etwas davon haben.
Das Pfad-Problem habe ich genau wie Sie es gesagt haben gelöst.
Nun zu meinem nächsten Problem. Wie oben erwähnt hat sich ein wenig die Aufgabenstellung geändert.
Nun soll eine Datenbank angelegt werden, auf welche die Gesichtserkennung zugreift und den Namen heraus zieht, wenn das Gesicht erkannt wurde. Später sollen noch Emotionen erkannt werden innerhalb des erkannten Gesichts und diese in die gleiche Datenbank in eine andere Tabelle geschrieben werden.
Nun erstmal meine "Datenbank-Datei", in dem die Datenbank erstellt wird um die Spaltennamen erwähnt zu haben:
Danach werden die Daten via Input abgefragt und abgespeichert.
Es werden Bilder gemacht diese gespeichert und trainiert.
Bis dahin funktioniert auch alles.
Und nun zu meinem eigentlichen Problem:
Hier soll das Gesicht erkannt werden. Dies ist auch der Fall. Er geht in die if Bedingung rein, aber scheitert dann ohne Fehler beim Auslesen der Datenbank.
Ich hoffe mir kann irgendjemand helfen. Ich habe wirklich versucht den Fehler zu finden, gegoogelt etc., aber nichts gefunden.
Ich bin wirklich am verzweifeln. Bin schon kurz davor aufzugeben. Sitze da jetzt schon seit drei Wochen dran.
tut mir leid für die späte Antwort. Ich hatte viele Abstimmungen mit meinem Professor.
Ich werde am Ende mein Ergebnis hier ins Forum stellen, damit alle etwas davon haben.
Das Pfad-Problem habe ich genau wie Sie es gesagt haben gelöst.
Nun zu meinem nächsten Problem. Wie oben erwähnt hat sich ein wenig die Aufgabenstellung geändert.
Nun soll eine Datenbank angelegt werden, auf welche die Gesichtserkennung zugreift und den Namen heraus zieht, wenn das Gesicht erkannt wurde. Später sollen noch Emotionen erkannt werden innerhalb des erkannten Gesichts und diese in die gleiche Datenbank in eine andere Tabelle geschrieben werden.
Nun erstmal meine "Datenbank-Datei", in dem die Datenbank erstellt wird um die Spaltennamen erwähnt zu haben:
Code: Alles auswählen
Tabelle1 = """
DROP TABLE IF EXISTs Benutzer;
CREATE TABLE Benutzer(
ID integer primary key,
Vorname text,
Nachname text,
Geschlecht text,
Geburtsdatum text
);
"""
Es werden Bilder gemacht diese gespeichert und trainiert.
Bis dahin funktioniert auch alles.
Und nun zu meinem eigentlichen Problem:
Hier soll das Gesicht erkannt werden. Dies ist auch der Fall. Er geht in die if Bedingung rein, aber scheitert dann ohne Fehler beim Auslesen der Datenbank.
Code: Alles auswählen
while True:
ret, img_frame = cam.read()
gray = cv2.cvtColor(img_frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.2, 5)
for (x, y, w, h) in faces:
cv2.rectangle(img_frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
ID, conf = LBPH.predict(gray[y:y+h, x:x+w])
if conf < 50:
continue
FRecs = c.execute("SELECT * FROM Benutzer WHERE ID = (?);", (ID,))
Benutzer = FRecs.fetchall()
cv2.putText(img_frame, Benutzer[0] + " " + Benutzer[1], (x + 2, y + h - 5), font, 0, 4, (0, 255, 0), 1)
#if FRecs.rowcount == 0:
#print("Ein Gesicht wurde gefunden ist aber nicht in der Datenbank")
#continue
else:
cv2.putText(img_frame, 'Nicht bekannt', (x + 2, y + h - 5), font, 1, (0, 0, 255), 1)
Ich bin wirklich am verzweifeln. Bin schon kurz davor aufzugeben. Sitze da jetzt schon seit drei Wochen dran.
@DonJuan: das Geburtsdatum sollte vom Typ Datum sein, das ist kein Text. Du sagst ja explizit, dass Du nichts machen willst (`continue`)m wenn conf < 50 ist. `continue` sollte man so weit wie möglich vermeiden, weil es den Programmfluß undurchsichtig macht. Du willst wahrscheinlich `fetchone` benutzen, statt `fetchall`. `c` ist ein schlechter Name, weil man nicht weiß, ist das nun ein Cursor oder eine Connection. Sollte ein Cursor sein, auf dem Du dann auch fetchone aufrufst, der Rückgabewert von `execute` ist eine SQLite-Spezialität, die den Umstieg auf eine andere Datenbank nur unnötig verkompliziert. Gib bei SELECT die Felder immer explizit an, das ist robuster gegen Datenbankänderungen. Statt Strings mit + zusammenzustückeln, nimm format.
Vielen Dank erstmal für die schnelle Antwort.
Ich habe es soweit angepasst und vereinfacht. Sieht nun so aus:
Jetzt bekomme ich leider diesen Fehler:
cv2.putText(img_frame, Benutzer[1], (x + 2, y + h - 5), font, 0, 4, (0, 255, 0), 1)
TypeError: an integer is required (got type tuple)
Ich weiß zwar was es bedeutet, aber ich finde einfach nicht den Ursprung des Ganzen. Bzw habe ich eine Ahnung, aber weiß nicht wie ich es löse.
Ich vermute ich iteriere durch int Werte, aber will string ausgeben und das funktioniert nicht... Ist nur meine Vermutung.... wie gesagt bin absoluter Anfänger.
Ich habe es soweit angepasst und vereinfacht. Sieht nun so aus:
Code: Alles auswählen
if conf < 50:
FRecs = cur.execute("SELECT * FROM Benutzer WHERE ID = (?);", (ID,))
Benutzer = FRecs.fetchone()
#cv2.putText(img_frame, Benutzer[0] + Benutzer[1], (x + 2, y + h - 5), font, 0, 4, (0, 255, 0), 1)
cv2.putText(img_frame, Benutzer[1], (x + 2, y + h - 5), font, 0, 4, (0, 255, 0), 1)
cv2.putText(img_frame, Benutzer[1], (x + 2, y + h - 5), font, 0, 4, (0, 255, 0), 1)
TypeError: an integer is required (got type tuple)
Ich weiß zwar was es bedeutet, aber ich finde einfach nicht den Ursprung des Ganzen. Bzw habe ich eine Ahnung, aber weiß nicht wie ich es löse.
Ich vermute ich iteriere durch int Werte, aber will string ausgeben und das funktioniert nicht... Ist nur meine Vermutung.... wie gesagt bin absoluter Anfänger.
Code: Alles auswählen
if conf < 50:
FRecs = cur.execute("SELECT * FROM Benutzer WHERE ID = (?);", (ID,))
Benutzer = FRecs.fetchone()
print(Benutzer[1])
Also scheitert es an der Funktion, oder?
Code: Alles auswählen
cv2.putText(img_frame, Benutzer[1], (x + 2, y + h - 5), font, 0, 4, (0, 255, 0), 1)
Wow, super, vielen Dank!!!
Leider stehe ich nun vor dem nächsten Problem.
Die if Bedingung macht mir Probleme. Er soll aus der Datenbank den Zeitstempel auslesen und überprüfen, ob 5 Minuten vergangen sind. Leider finde ich in Google immer nur Möglichkeiten mit time.sleep(300). Das bringt mir aber nichts, da das Programm ja weiterlaufen soll.
Bei allen anderen Möglichkeiten die ich bisher ausprobiert habe (wie oben der dümmste Ausdruck mit result -300) gibt er mir natürlich zurück, das es unterschiedliche Typen sind.
Kann mir hier eventuell noch einmal jemand helfen. Sorry für die vielen Fragen. Vermutlich aus eurer Sicht auch richtig doofe
Leider stehe ich nun vor dem nächsten Problem.
Code: Alles auswählen
for (sx, sy, sw, sh) in smiles:
cv2.rectangle(roi_color, (sx, sy), (sx + sw, sy + sh), (0, 0, 255), 1)
unix = time.time()
date = datetime.datetime.fromtimestamp(unix).strftime('%Y-%m-%d %H:%M:%S')
SDec = cur.execute("SELECT Zeitstempel FROM Emotion WHERE ID = (?) ORDER BY Zeitstempel DESC;", (ID,))
result = SDec.fetchone()
print(result)
if result < result - 300:
cur.execute(
"INSERT INTO Emotion (ID, Vorname, Nachname, Geschlecht, Geburtsdatum, Emotion, Zeitstempel) VALUES (?,?,?,?,?,?,?)",
(Benutzer[0], Benutzer[1], Benutzer[2], Benutzer[3], Benutzer[4], 'Smile', date))
conn.commit()
Bei allen anderen Möglichkeiten die ich bisher ausprobiert habe (wie oben der dümmste Ausdruck mit result -300) gibt er mir natürlich zurück, das es unterschiedliche Typen sind.
Kann mir hier eventuell noch einmal jemand helfen. Sorry für die vielen Fragen. Vermutlich aus eurer Sicht auch richtig doofe
fetchone gibt dir immer ein Tupel zurueck. Auch wenn du nur einen Wert erwartest. Darum macht man dann
Und fuer die Zukunft: poste konkrete Fehlermeldungen, nicht paraphrasierungen. Last but not least: result < result - 300 ist natuerlich unter keinen Umstaenden wahr.
Code: Alles auswählen
result, = SDec.fetchone()
@DonJuan: ich verstehe nicht wo Du wie warten willst und was das mit sleep zu tun haben soll.
Die Datenbank kennt automatisch Zeitstempel und der Treiber wandelt das in Datetime-Objekte um. Da von Hand was rumzuformatieren ist falsch.
Solche bedingten INSERTS macht man üblicherweise auch direkt in SQL, bei SQLite also:
Jetzt hast Du noch die erste Normierung von Datenbanktabellen mißachtet. Da Vorname, Nachname, Geschlecht und Geburtsdatum sich nicht mit der Emotion ändern und Du diese Daten schon in der Benutzer-Tabelle hast, brauchst Du sie nicht nochmal zu speichern, und die Emotionstabelle verkleinert sich zu ID, Emotion, Zeitstempel:
Die Datenbank kennt automatisch Zeitstempel und der Treiber wandelt das in Datetime-Objekte um. Da von Hand was rumzuformatieren ist falsch.
Solche bedingten INSERTS macht man üblicherweise auch direkt in SQL, bei SQLite also:
Code: Alles auswählen
c.execute("INSERT INTO Emotion (ID, Vorname, Nachname, Geschlecht, Geburtsdatum, Emotion, Zeitstempel) "
"SELECT ?,?,?,?,?,?,datetime('NOW') WHERE NOT EXISTS ("
"SELECT * FROM Emotion WHERE ID=? AND Zeitstempel >= datetime('NOW', '-5 minutes'))",
[Benutzer[0], Benutzer[1], Benutzer[2], Benutzer[3], Benutzer[4], 'Smile', Benutzer[0]])
Code: Alles auswählen
c.execute("INSERT INTO Emotion (ID, Emotion, Zeitstempel) "
"SELECT ?,?,datetime('NOW') WHERE NOT EXISTS ("
"SELECT * FROM Emotion WHERE ID=? AND Zeitstempel >= datetime('NOW', '-5 minutes'))",
[Benutzer[0], 'Smile', Benutzer[0]])
Hallo zusammen,
verzeiht mir die verspätete Rückmeldung.
Ich habe mich zuerst mit dem theoretischen Teil meiner Thesis beschäftigen müssen und bin nun zum Programmieren zurück gekehrt.
Das Programm steht soweit. Ich werde es gerne mit Abgabe meiner Thesis hier posten, um anderen evtl. weiterhelfen zu können.
Aber wie gesagt, mein Programm steht nur fast.
Ich habe folgendes Problem:
Ich habe mein Problem im Text markiert. Letztendlich soll durch Input ein Ordner erstellt werden in welchen abgespeichert wird.
Habe wirklich schon viel ausprobiert, aber irgendwie scheitere ich immer am Pfad. Meine zweite und nicht sehr schlanke Lösung war, die Dateien anschließend einfach zu verschieben, aber auch damit habe ich Probleme.
Ich hoffe Ihr könnt mir weiterhelfen...
Achso Fehler 1:
Er speichert einfach keine Dateien
Fehler 2:
Er findet die Datei nicht um sie zu verschieben
Danke
verzeiht mir die verspätete Rückmeldung.
Ich habe mich zuerst mit dem theoretischen Teil meiner Thesis beschäftigen müssen und bin nun zum Programmieren zurück gekehrt.
Das Programm steht soweit. Ich werde es gerne mit Abgabe meiner Thesis hier posten, um anderen evtl. weiterhelfen zu können.
Aber wie gesagt, mein Programm steht nur fast.
Ich habe folgendes Problem:
Code: Alles auswählen
import cv2
import os
import time
import datetime
import shutil
if not os.path.exists('./Personen'):
os.makedirs('./Personen')
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)
counter = 0
Basispfad = os.path.dirname(os.path.abspath(__file__))
Personenpfad = os.path.join(Basispfad, "Personen")
Namenpfad = os.path.join(Personenpfad, name)
ts = time.time()
st = datetime.datetime.fromtimestamp(ts).strftime('%d-%m-%Y_%H-%M-%S')
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 = name + " " + str(st)
cv2.imwrite("Personen/" + str(file_name) + " -c " + str(counter)+ ".jpg", roi_gray)#Diese Zeile funktioniert, jedoch natürlich im falschen Ordner
cv2.imwrite(Namenpfad + str(file_name) + " -c " + str(counter)+ ".jpg", roi_gray) # Diese Zeile funktioniert nicht, es kann nur am Pfad liegen, da ich alles andere getestet habe. Ich hoffe jemand kann mir helfen
cv2.waitKey(300)
cv2.imshow('Gesichtsspeicherung',gray)
counter += 1
if cv2.waitKey(1) & 0xFF == ord('q'):
break
print ('Gesichtsspeicherung abgeschlossen')
Habe wirklich schon viel ausprobiert, aber irgendwie scheitere ich immer am Pfad. Meine zweite und nicht sehr schlanke Lösung war, die Dateien anschließend einfach zu verschieben, aber auch damit habe ich Probleme.
Code: Alles auswählen
for subdir, dirs, files in os.walk(Personenpfad):
for file in files:
if str(file).startswith(name):
print(file)
src = Personenpfad + file
os.rename(src, Namenpfad)
else:
print("Keine Dateien vorhanden")
Achso Fehler 1:
Er speichert einfach keine Dateien
Fehler 2:
Er findet die Datei nicht um sie zu verschieben
Danke
- __blackjack__
- User
- Beiträge: 13116
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Du hast da einen komischen Mix aus Pfaden relativ zum aktuellen Arbeitsverzeichnis und relativ zum Programm, die mal mit ``+`` und '/' und mal mit `os.path.join()` zusammengesetzt werden. Bei ersterem entscheide Dich für das eine oder das andere, und Pfade immer mit `os.path.join()` zusammensetzen.
Das `str()` und ``+`` wo keine Pfadteile verbunden werden, solltest Du durch die `format()`-Methode ersetzen.
Das `str()` und ``+`` wo keine Pfadteile verbunden werden, solltest Du durch die `format()`-Methode ersetzen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
@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)