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

06/2019
Home Improvement

Diese Ausgabe als PDF kaufen

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

Stellenmarkt

Neuigkeiten

  • Verschlungene Pfade

    Mit Schleifen, Fallunterscheidungen und Funktionen programmieren Sie komplexe Skripte auf einfache und elegante Weise.

  • Extrem genau

    Mit einem A/D-Wandler messen Sie bei Bedarf Spannungen. Der MCP3424 macht dabei konstruktionsbedingt eine gute Figur.

  • Verbindungsaufnahme

  • Süßer Wecker

    Dem RasPi fehlen sowohl eine Echtzeituhr als auch ein BIOS, ein zeitgesteuertes Wecken erfordert also Zusatzkomponenten. Hier springt der Witty Pi Mini in die Bresche, ein µHAT von UUGear.

  • Windows to go

    Das Aufsetzen zuverlässiger und sicherer Remote-Desktop-Lösungen erfordert einiges Know-how. Die RasPi-basierte Pinbox von Pintexx reduziert den Konfigurationsaufwand auf ein Minimum.

  • Prima Klima

    In Museen ist es Pflicht, zu Hause nützlich: das permanente Prüfen und zentrale Erfassen der Feuchtigkeit und Temperatur in Räumen.

  • Auf einen Blick

    Ein maßgeschneiderter Infoscreen auf RasPi-Basis mit stromsparendem E-Ink-Display zeigt Termine, Bilder, Mitteilungen und Wetterinformationen an.

  • Sanft berührt

    Mit einem RasPi und dem Controllermodul PiXtend lassen sich mühelos Roboterarme ansteuern und deren Bewegung automatisieren.

  • Popcorn-Kino

    Mit Kodi 18.0 unterstützt LibreELEC 9.0 jetzt die von vielen Streaming-Diensten genutzte DRM-Verschlüsselung. Die Integration von Netflix, Amazon und Co. erfordert allerdings Handarbeit.

  • So nah und doch so fern

    Der RasPi kommt häufig als Server oder Steuerrechner für spezielle Zwecke zum Einsatz. Mit Anydesk erhalten Sie dazu eine Steuersoftware mit grafischer Oberfläche.