Nistkästen mit der Pi-Cam ins Internet bringen

Bewegungserkennung

Um nun zu erkennen, ob sich aktuell eine Meise im Nistkasten befindet, greift das Projekt auf einen simplen Algorithmus zurück. Zunächst sichert es das letzte Bild (Bildalt) und nimmt ein neues (Bildneu) auf. Anschließend wandelt es beide Aufnahmen in Grauwerte um und reduziert die Pixelzahl beider Bilder auf 4 x 3 Pixel.

Es folgt das Ermitteln einer Kennzahl, für die das Programm über alle jeweils 12 Bildpunkte die Differenz der Helligkeitswerte (Bildpunktneu - Bildpunktalt) berechnet und die Beträge aufsummiert. Fällt die Kennzahl größer aus, als ein Schwellwert, liegt eine Bildveränderung vor. Dann übermittelt das Program einen Merker an einen Webservice.

Für komplexe Pixeloperationen in Python gilt die quelloffene Bilderkennungsbibliothek OpenCV [7] als Mittel der Wahl. Weil dabei aber die Lernkurve recht steil ausfällt, kommt stattdessen die Python Image Library oder kurz PIL [8] zum Einsatz, die Sie über die Paketverwaltung einrichten (Listing 7). Ausführliche Tipps zum Umgang mit PIL liefert beispielsweise das deutschsprachige Blog Rustimation [9].

Listing 7

 

§ sudo apt install python-imaging

Den Python-Quelltext für unsere Meisencam inklusive des Hochladens des Bilds mit einem Webservice finden Sie in Listing 8. Der Schwellwert von 35 wurde vor dem Bezug des Nistkastens durch ein Meisenpaar experimentell ermittelt. Dazu hielten wir verschieden große Gegenstände ins Einflugloch, die unterschiedlich hohe Kennzahlen erzeugten.

Die Wahl des Schwellwerts geschah dann nach Augenmaß, sodass die Software erst bei größeren Unterschieden im Bild reagiert. Beim Nachbauen müssen Sie wahrscheinlich selbst einen brauchbaren Wert ermitteln, da andere Rahmenbedingungen (etwa dunkleres Holz oder anderes Licht) neue Schwellwerte nötig machen.

Listing 8

 

#!/usr/bin/python
# meisencam.py
# Bildveraenderungserkennung mit PIL
import picamera
import time
from time import sleep
import requests
from PIL import Image
# Voreinstellungen
WIDTH=320
HEIGHT=240
FONTSIZE=20
SCHWELLWERT=35
# Kamera initialisieren
camera = picamera.PiCamera()
camera.vflip = False
camera.hflip = False
camera.brightness = 60
camera.resolution = (WIDTH,HEIGHT)
camera.iso = 400
camera.shutter_speed = 25000
camera.awb_mode = 'cloudy'
localpicname = '/mnt/ramdisk/meisencam.jpg'
zeitstempel = time.strftime("%Y%m%d-%H%M%S")
camera.annotate_text = zeitstempel
sleep (2)
camera.capture(localpicname)
print (zeitstempel)
camera.close()
# Kennzahl fuer die Bildveraenderung ermitteln
# Bilder in Objekte laden
localaltname='/mnt/ramdisk/meisencamalt.jpg'
bildneu=Image.open(localpicname)
# Falls Raspi neu gestartet, existiert das alte Bild nicht
# Hilfsweise fuer einen Durchlauf das neue nehmen
try:
  bildalt=Image.open(localaltname)
except IOError:
  bildalt=bildneu
# altes Bild durch aktuelles Bild ersetzen
bildneu.save(localaltname)
# Bilder in Grauwerte umrechnen
bildneu=bildneu.convert("L")
bildalt=bildalt.convert("L")
# Bilder stark verkleinern
breite=4
hoehe=3
size=[breite,hoehe]
bildneu=bildneu.resize(size)
bildalt=bildalt.resize(size)
# In einer Schleife Kennzahl ermitteln
x=0
y=0
kennzahl=0
while (x<breite):
  while (y<hoehe):
  hneu = bildneu.getpixel((x,y))
  halt = bildalt.getpixel((x,y))
  kennzahl=kennzahl+abs(hneu-halt)
  y=y+1
  x=x+1
kennzahl=kennzahl/hoehe/breite
print ("Kennzahl: " + str(kennzahl))
if (kennzahl>SCHWELLWERT):
  mode=1
else:
  mode=0
print ("Modus: " + str(mode))
# Auf den Webspace hochladen
# Webservice-Aufruf ohne Bildveraenderung:
url = 'http://meisencam.cbrell.de/meisencamWS.php'
# Webservice-Aufruf bei Bildveraenderung
if (mode==1):
  url = 'http://meisencam.cbrell.de/meisencamWS.php?mode=1'
files = {'file': open(localpicname, 'rb')}
r = requests.post(url, files=files)
print(r)
# Log schreiben
f = file('/mnt/ramdisk/meisencam.log','a')
ausgabe = zeitstempel + ';' + str(kennzahl) + ';' + str(mode) + ';' + r.text + $
f.write(ausgabe)
f.close()

Die Einstellungen für die Kamera – insbesondere der ISO-Wert, die Belichtungszeit in Mikrosekunden und der Farbabgleich – werden fest eingestellt. Lässt man die Kamera die Werte selbst automatisch ermitteln, kommen insbesondere mit dem Infrarot-Kameramodul sehr unterschiedliche Varianten heraus. Die Bildveränderungserkennung spricht dann an, obwohl sich im Meisenkasten eigentlich nichts tut.

Bilder hochladen

Bei dem Webservice, der das Bild entgegennimmt und auf dem Webserver speichert, handelt es sich um ein einfaches PHP-Skript mit dem Namen meisencamWS.php (Listing 9). Die Programmiersprache PHP stellt nahezu jeder Webspace-Anbieter zur Verfügung, in der Regel genügt ein kleines Webhosting-Paket für wenige Euro monatlich.

Das Skript geht davon aus, dass es im Stammverzeichnis den Ordner archiv gibt. Dorthin lädt das Programm das Bild, sobald die Bilderkennung eine Veränderung meldet.

Listing 9

 

<?php
// Vorbelegungen
$mode=0; //default, nur aktuelles Bild speichern
// mode = 1 Bild Kopieren
if(isset($_GET['mode'])) if ($_GET['mode']==1) $mode=1;
// Dateinamen auf dem Webserver
$target_file='meisencam.jpg'; // aktuelles Bild
$target_file_cont='archiv/meisencam'.date("ymd-His").'.jpg'; // Archivbild
// Bild hochladen
if(isset($_FILES['file']) && $_FILES['file']['size'] != 0){
        $target_dir = "";
        // Falls Bild so heißen soll wie das hochgeladene:
        // $target_file = $target_dir . basename($_FILES['file']['name']);
        // $target_file = $target_dir . $_FILES['file']['name']);
        if (move_uploaded_file($_FILES['file']['tmp_name'], $target_file)) {
        echo "Bild ". basename( $_FILES['file']['name']). " erfolgreich hochgeladen.";
        }
}
if ($mode==1) copy ($target_file,$target_file_cont);
// Loggen
$Logdatei='meisencam.log';
$IP=getenv("REMOTE_ADDR");
$Domain=gethostbyaddr($IP);
$var='nichts übertragen';
if (isset($_POST)) $var=implode("-",$_POST);
if (isset($_FILES['file'])) $var.='-'.$_FILES['file']['name'];
$Ausgabe=time().';'.$IP.';'.$Domain.';'.date("d.m.Y").';'.date("H:i:s").';'.$var."\r\n";
$fh=fopen($Logdatei,"a");
fwrite($fh,$Ausgabe);
fclose($fh);
?>

Sobald Sie das PHP-Skript auf den Webserver gespielt und den Aufruf im Python-Skript entsprechend angepasst haben, bietet es sich an, die Aufnahme- und Upload-Funktion mit dem Aufruf von ./meisencam.py zu testen. Das Ergebnis prüfen Sie mit einem FTP-Programm oder mit einem Aufruf im Browser, in dem Sie in die Adresszeile den Pfad zum Verzeichnis des Skripts eingeben, gefolgt von /meisencam.jpg.

Im nächsten Schritt kopieren Sie das Programm zur Anzeige des Bilds auf den Webserver. Die recht umfangreiche HTML-Datei dazu mit einigen Javascript-Befehlen finden Sie auf der Heft-DVD als anzeigeseite.html. In den ebenfalls auf der Heft-DVD befindlichen Dateien navigator.html und navigator.php liegen die Skripte, mit denen Sie die Archivbilder in einer Art Mini-Galerie ansehen können. Spielen Sie beide in das Unterverzeichnis Archiv/ADM/ auf dem Webserver ein.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 9 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Raspberry Pi Geek kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

Aktuelle Ausgabe

12/2018
Coole Projekte

Diese Ausgabe als PDF kaufen

Preis € 7,99
(inkl. 19% MwSt.)

Stellenmarkt

Neuigkeiten

  • Bytes und Beats

    In Sonic Pi können Sie mit wenigen Codezeilen Klänge manipulieren, Beats zusammenstellen und ganze Songs komponieren.

  • Klein, aber fein

  • Trick or treat

    Das traditionelle RPG-Gruselkabinett glänzt dieses Jahr mit einer innovativen Umsetzung mittels Pneumatik und Elektropneumatik sowie ST-Programmierung.

  • Unter Kontrolle

    Traditionell stellen wir alljährlich ein selbst gebautes Halloween-Gespenst vor. Die pneumatischen und elektronischen Grundlagen erklärt dieser Artikel.

  • Go Pi Go!

    Der Bausatz GoPiGo3 liefert Bauteile und Software für ein kleines Roboterauto. Zusammen mit einem RasPi als Gehirn programmieren Sie den Roboter per Mausklick.

  • Handlicher Helfer

    Während die Folien der Präsentation durchlaufen, liefert ein kleiner Dokumentenserver auf Basis des GL-AR300M-ext zusätzliche Informationen aus.

  • Wiederverwertet

    Mithilfe eines einfachen Python-Programms recyceln Sie ein ausgedientes Smartphone als drahtlos angebundenes RasPi-Display.

  • Herzenssache

    Steigt beim Krimi der Herzschlag bedrohlich an? Mit einem Pulsmesser in Eigenbau ermitteln Sie einfach und kostengünstig, ob der Herzschlag noch in verträglichen Bereichen liegt.

  • Fernbedient

    Mit der Fernbedienung den RasPi steuern. In der Theorie möglich, in der Praxis oft beschwerlich. Die Libcec liefert praktische Tools zur Fehlersuche.

  • Musikwürfel

    Mit Musikcube machen Sie Ihre eigene Sammlung fit fürs Streamen. Der terminalbasierte Audioplayer lässt sich Fernsteuern und bietet eine App für Android-Smartphones.