MeType

Schlagwort: python

Der magische Spiegel – Gesichtserkennung & allgemeines Update

Nachdem ich hier eine ganze Weile nichts mehr von mir gegeben habe, mal wieder ein kleines Update. Das Dateisystem meiner SD-Karte hat sich vor längerer Zeit mal verabschiedet und ich hatte bis vorgestern keine wirkliche Motivation dazu das System neu aufzusetzen.
Jetzt bin ich allerdings endlich mal dazu gekommen – nun auch mit der neusten Version von Raspbian: „Jessie“ und einem mit dem Original-Code wieder abgeglichenen Spiegelinterface von Michael Teeuw. Kurz zu der neuen Linux Version, ich muss sagen, mir gefällt systemd bisher echt gut, kommt mir sehr viel einfacher vor damit die Prozesse zu verwalten aber darum soll es heute nicht gehen.

Ich habe damals mal den Code von der Raspberry Pi Face Recognition Treasure Box genommen und etwas angepasst, sodass er nicht nur ein Gesicht als berechtigt oder nicht berechtigt erkennt, sondern zwischen Gesichtern unterscheiden kann und kontinuierlich nach Gesichtern sucht, statt nur nach einem Knopfdruck. Diesen veränderten Code habe ich nun auch in den Spiegel eingebaut. Er kann nun also erkennen, wer vor ihm steht, dann eine Begrüßung und Informationen für diesen speziellen Nutzer anzeigen.

Da ich inzwischen relative viele Prozesse habe, die irgendwas machen, habe ich gestern Abend mal noch ein kleines Schema aufgezeichnet, um nicht den Überblick zu verlieren, wer mit wem redet.
Software:Hardware magischer Spiegel

Auf der Software Seite habe ich ganz unten, für die Steuerung von GPIO-Sachen, den mirrorcontroller. Er schaut nach Veränderungen des Bewegungsmelders und überwacht einen Knopf. In Zukunft wird er auch noch die Farben der RGB LED Beleuchtung steuern aber die, muss ich erst noch einbauen. Bewegt sich etwas, wird das Relais des Monitors geschaltet und ein Signal an den Gesichtserkennungsprozess gegeben, welcher dann anfängt Fotos aufzunehmen und sie nach Gesichtern abzusuchen. Erkennt der Prozess ein Gesicht, gibt er dieses an den SocketIOServer weiter, welcher es wiederum an das Webinterface leitet, um dort dann eine Willkommensnachricht und personalisierte Inhalte anzuzeigen. Neben dieser Funktion kann der SocketIOServer noch Online-Banking, um den aktuellen Kontostand des Nutzers anzuzeigen, er sammelt Statistiken zu meinen Vimeo-Videos, ermittelt den vorhandenen Festplattenspeicher auf meinem Server, überwacht die Fritz!Box, um über Anrufe zu informieren und zeigt von meinen Kunden noch zu bezahlende Rechnungen an. In nächster Zeit möchte ich noch Wunderlist einbauen, damit auch meine ToDo’s angezeigt werden können.

Das ist mein aktueller Stand soweit, nachdem ich die letzten Hardwarekomponenten jetzt dann soweit fertig habe, kann es endlich auch mal an das Gehäuse gehen.

Node.js – Python Bridge

Die Methode aus dem letzten Beitrag Daten von meinem Pythonskript mit zerorpc in mein Node.js-Skript zu bekommen hat zwar im Endeffekt irgendwie funktioniert, nur gab es das Problem, dass es wenn ich die Skripte eine Weile laufen lies irgendwann aufgehört hat die Daten weiterzuleiten. Da ich sowieso nicht wirklich zufrieden mit der Methode war, habe ich gar nicht mehr nach dem Problem sondern gleich nach einer anderen Lösung gesucht, die ich dank John Hobbs jetzt auch habe. Auf der Suche nach Beispielen für UNIX Sockets habe ich diesen Artikel gefunden, nach einem Kommentar, hat er ihn gleich noch um einen Node.js-Server ergänzt, was jetzt auch ohne Probleme funktioniert.

import RPi.GPIO as GPIO
import os, os.path
import socket

GPIO.setup(27, GPIO.IN)

def node_bridge(command):
    if os.path.exists( "/tmp/python_node_bridge" ):
        client = socket.socket( socket.AF_UNIX, socket.SOCK_STREAM )
        client.connect( "/tmp/python_node_bridge" )
        client.send( command )
        client.close()
    else:
        print "Couldn't Connect!"

def switchview(27):
    node_bridge("switchview")

try:
    GPIO.add_event_detect(27, GPIO.FALLING, callback=switchview, bouncetime=600)
    while 1:
        time.sleep(100)
var io = require('socket.io').listen(1234);
var net = require('net');

var server = net.createServer(function(python_bridge) {
  python_bridge.on('data', function(data) {
    if(data.toString() == "switchview") {
      io.sockets.emit('switchview');
    }
  });
});
server.listen("/tmp/python_node_bridge");
var socket = io.connect('http://localhost:1234');
view = "view1";

function switchview() {
  if (view == "view1") {
    $('#view1').fadeOut(700);
    $('#view2').fadeIn(700);
    view = "view2"
  } else if (view == "view2") {
    $('#view2').fadeOut(700);
    $('#view1').fadeIn(700);
   view = "view1"
  }
};

socket.on('switchview', function () {
  switchview();
});

Diese drei Code-Schnippsel schalten nun nach dem Drücken eines Tasters zwischen zwei verschiedenen Ansichten hin und her, zeigen also unterschiedliche Informationen auf dem Spiegel an.
Das Pythonskript überwacht den GPIO-Pin und wartet darauf, dass die 3.3V Spannung auf 0V abfällt. Passiert das schickt es eine Nachricht an mein Node.js-Skript, welches diese an die Benutzeroberfläche weiterleitet und dort eine Funktion auslöst, die zwischen den Ansicht wechselt.

Python Unklarheit

Vielleicht hat hier ja irgendjemand ein bisschen mehr Ahnung von Python als ich – vermutlich nicht sonderlich schwer – und kann mir daher erklären, wieso das erste Skript nicht funktioniert, das Zweite hingegen schon. Biteule und ich sind nur soweit gekommen, dass es wohl irgendwas mit dem Threading der GPIO-Callbacks zu tun haben muss aber was jetzt genau das Problem ist, verstehen wir beide nicht. Es ist nicht so, dass zerorpc im ersten Skript beim Aufruf nicht vorhanden ist, immerhin kann es einen Fehler ausgeben (LostRemote: Lost remote after 10s heartbeat), wieso also macht es trotzdem einen Unterschied, an welcher Stelle ich es importiere?

import RPi.GPIO as GPIO
import time
import zerorpc

nodebridge = zerorpc.Client()
nodebridge.connect("tcp://127.0.0.1:4242")

GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.IN)

def switchview(switchview_taster):
    nodebridge.switchview()

try:
    GPIO.add_event_detect(27, GPIO.FALLING, callback=switchview, bouncetime=600)
    while 1:
        time.sleep(100)
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.IN)

def switchview(switchview_taster):
    import zerorpc
    nodebridge = zerorpc.Client()
    nodebridge.connect("tcp://127.0.0.1:4242")
    nodebridge.switchview()

try:
   GPIO.add_event_detect(27, GPIO.FALLING, callback=switchview, bouncetime=600)
   while 1:
      time.sleep(100)
var io = require('socket.io').listen(1234);
var zerorpc = require("zerorpc");

var pythonbridge = new zerorpc.Server({
  switchview: function(reply) {
    io.sockets.emit('switchview');
    reply(null);
  }
});

pythonbridge.on("error", function(error) {
  console.error("RPC server error:", error);
});

pythonbridge.bind("tcp://0.0.0.0:4242");

UPDATE 12.02.15 – 14:51:

Copyright © 2018 MeType

Theme von Anders Norén↑ ↑