Katzenerkennung

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
samaha
User
Beiträge: 6
Registriert: Sonntag 12. März 2017, 11:04

Hallo,
ich beschäftige mich als Python-Anfänger im Zug eines Projektes
mit einer Katzenerkennung. Nach erfolgreicher Erkennung soll
die eigene Katze Zugang zu Flüssigkeit / Futter bekommen.
Die Ablaufsteuerung hardwareseitig via GPIO funktioniert.

Software: Python 2.7.9 und OpenCV 3.x

Gedanken meinerseits dazu:

1. Autostart von cat_xx.py wenn Raspi3 startet
2. Katzen-Aktivität an "Futterkrippe" wird von PIR-Bewegungsmelder an GPIO
registriert
3. Videoaufzeichnung wird gestartet und per haarcascade (frontalcatface)
Katzengesicht erfasst
4. Erfasstes, eingerahmtes Katzengesicht soll "extrahiert" / als Bild gespeichert werden
5. Auto-Modus: Vergleich mit vorhandenem Bild des Gesichtes der Katze
oder
Manuell-Modus: Zusenden des extrahierten Bildes per Mail
an Smartphone
6. Aktivierung eines GPIO-Ports zur Fortsetzung der hartware-
seitigen Ablaufsteuerung bei eigener Katze bzw.
bei fremder (nichteigene) Katze Pause von x min und
ab Punkt 2 auf ein Neues

Bis zum Punkt 3 funktioniert die test_xx.py. Bei Erfassung wird bei
Punkt 4 das komplette Kamerabild gespeichert und nicht der gerahmte
Bereich. An der Stelle geht es nicht wie gewünscht weiter.

Wie kann das erfasste Gesicht (der gerahmte Bereich) als Bild gespeichert werden?

Darüber hinaus bin ich für Vorschläge dankbar.

Es handelt sich wie gesagt um die ersten Schritte mit
sicherlich einigen Verbesserungsmöglichkeiten.

Vielen Dank vorab.

anbei der Code der test_xx.py:

[codebox=python file=Unbenannt.txt]
# -*- coding: utf-8 -*-
# Import der benötigten Pakete
import sys
sys.path.append('/usr/local/lib/python2.7/site-packages')
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
import numpy as np

filenames = 'image-{timestamp:%S}.jpg'

# Kamerainitialisierung und Festlegung von Auflösung und Wiederholrate
camera = PiCamera()
camera.resolution = (320, 240 )
camera.framerate = 25

# Kamera(Bild)-Drehung (Kamera liegt während der Programmierung "kopfüber"
camera.rotation = 180

rawCapture = PiRGBArray(camera, size=(320, 240))

cat_cascade = cv2.CascadeClassifier('./haarcascade_frontalcatface.xml')

# Pause für Kamera-aktivierung
time.sleep(0.5)

# Kameraaufzeichnung
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
image = frame.array

# Bildumwandlung in Graustufen;
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = cat_cascade.detectMultiScale(gray,
scaleFactor=1.3,
minNeighbors=9,
minSize=(75, 75))

# Erstellung des Rahmens um die Gesichter
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
print "{0} Aktivitaet(en) vor der Kamera".format(len(faces))
if len(faces) > 0:
print "weiter"

cv2.imshow('frame',image)
#cv2.imshow('gray',gray)

key = cv2.waitKey(1) & 0xFF

rawCapture.truncate(0)

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

[/code]
Zuletzt geändert von Anonymous am Dienstag 14. März 2017, 16:50, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@samaha:
Als Anregung - ich würde noch die Katzenerkennung über eine AI mit tensorflow z.B. mit Katzenvideos von youtube trainieren. Für den Fall, dass Du einen Hund im Haushalt hast, ist die Sache dann gut gerüstet...
samaha
User
Beiträge: 6
Registriert: Sonntag 12. März 2017, 11:04

Vielen Dank für die Antwort.
Ein Hund ist nicht vorhanden und wird wegen Inkompatibilität
zu Katze nicht angeschafft werden.
Die Erkennung meiner "Musterkatze" funktioniert recht gut.
Ich bin leider noch nicht fündig geworden, wie ich den erfassten
Bereich als neues Bild speichern kann.
Gibt es da eine Möglichkeit über len o.ä.?
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Eigentlich sollte

Code: Alles auswählen

face = image[y:y+h, x:x+w ]
reichen. Das ist ja nur ein numpy array. Ggf. Indizes vertauschen, ich weiss nicht mehr genau, welche Ordnung er da hat.
samaha
User
Beiträge: 6
Registriert: Sonntag 12. März 2017, 11:04

Das funktioniert leider nicht :( .
Was funktioniert ist:
Bei Katzenerkennung:
-Bild mit erkannter Katze ohne Rechteck-Maske anzeigen oder speichern
und
-Bild mit erkannter Katze mit Rechteck-Maske anzeigen oder speichern
Ist es in Python 2.7 überhaupt möglich nur das erkannte Gesicht (Bild in dem Rechteck) zu extrahieren?

Danke euch vorab.
BlackJack

@samaha: Ja das ist möglich. Du hast ja alle Daten dafür, also das gesamte Array mit dem kompletten Bild und die Eckdaten für das Rechteck. Warum sollte das also nicht gehen?
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

samaha hat geschrieben:Das funktioniert leider nicht :( .
Was funktioniert dabei nicht? Wird das Gesicht irgendwo abgeschnitten? Bekommst du eine Fehlermeldung?

Das Schema image[y:y+h, x:x+w] ist durchaus üblich. Wenn du ein Rechteck um diesen Bereich zeichnen kannst, dann sollte unter Verwendung dieser Werte auch das Ausschneiden / Isolieren des Bereichs möglich sein.
samaha
User
Beiträge: 6
Registriert: Sonntag 12. März 2017, 11:04

Nein, Fehlermeldung gab es keine. Mit imshow wurde nur ein graues Fenster angezeigt;
mit imwrite ein leeres Bild gespeichert.
:K
Habe ich den Pi gerade heruntergefahren und neu gestartet....und...es funktioniert.
Das Gesicht der erkannten Musterkatze wird wie gewollt als Bild erstellt!!!! :D

Ich danke Euch!!!

Nun geht es ans "Eingemachte":

Vergleich des hinterlegten Katzengesichtes mit dem gerade erstellten.
samaha
User
Beiträge: 6
Registriert: Sonntag 12. März 2017, 11:04

Hallo,

nachdem nun beide Musterkatzen im Videostream erkannt,
das Kamerabild und der eingerahmte Gesichtsbereich jeweils
erfolgreich als Bild gespeichert werden habe ich den Vergleich der
beiden vorher erstellten Katzengesichter ( Musterkatze 1 und 2 )mit
dem ersten der beiden Recognition-Code's der Opencv-Seite versucht:

http://opencv-python-tutroals.readthedo ... ching.html

Ablauf:
1) Katzengesicht wird im Videostream erkannt und Kamera-Bild im Moment der
Erkennung in Auflösung 320x240Pixel gespeichert
2) pos. Katzengesicht( Katze1 die gefüttert werden soll ) wird als Template geladen
3) Vergleich der beiden Bilder nach o.g. Code

Positiv erkannt werden soll nur Katze 1, negativ oder nicht erkannt werden soll Katze 2.
( Wertzuweisung an eine Variable oder True / False )

Mit o.g. Code werden beide Musterkatzengesichter von Katze1 und Katze2 (Template) an verschiedenen Stellen
des geladenen Bildes (Bild mit Katze1 320x240Pixel) vermeindlich erkannt.

Wie kann eine positive und/oder negative Übereinstimmung erreicht werden?

Für Tipps /Vorschläge danke ich euch vorab.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das kannst du so vergessen.

Template matching ist eine recht simple Technik. Im Grunde wird nur fuer jede moegliche Position im Bild das Template verglichen, indem fuer jeden Pixel die Abweichung zwischen Eingabe und Template ermittelt, und nach einer bestimmten Formel (zB Summe der Fehlerquadrate) aufsummiert.

Dieses Verfahren ist somit weder skalierungs- noch rotationsinvariant. Und "irgendwie Katze" ist - je nach Hintergrund - wahrscheinlich fuer beide Bilder bei dir so ungefaehr passend, und damit zumindest das Maximum, das da bestimmt wird.

Wenn du wirklich genau *deine* Katze erkennen willst, musst du schwerere Geschuetze auffahren. ZB selbst HOG-classifier bauen. Such mal nach Tutorials fuer OpenCV, mit denen das bei menschlichen Gesichtern gemacht wird - so geht's dann auch fuer Katzen. Da wirst du viele nicht-deine-Katze-Bilder brauchen (danke, Youtube), und viele von deiner Katze, und dann maechtig trainieren.
samaha
User
Beiträge: 6
Registriert: Sonntag 12. März 2017, 11:04

Also würde auch das reine Einlesen des Positiv-Katzengesichtes und
Suchen nach selbigen im Videostream nach Aktivierung der Kamera
durch Bewegungsmelder nicht funktionieren?.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich verstehe die Frage nicht. Kann man Katzen (oder andere) Gesichter erkennen? Ja. Kann man es so machen, wie du es begonnen hast? Nein. Habe ich aber doch beides schon ausgefuehrt :K
Riebers
User
Beiträge: 9
Registriert: Sonntag 18. Juni 2017, 18:52

Was für eine Kamera hast du für die Gesichtserkennung verwendet?
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Riebers hat geschrieben:Was für eine Kamera hast du für die Gesichtserkennung verwendet?
Kann man doch im Code erkennen- PiCamera, die fuer den PI angeboten wird.
Antworten