Auf dem Raspberry Pi lässt sich relativ einfach eine USB-Webcam einrichten. Damit kann man dann zum Beispiel in regelmäßigen Abständen Bilder schießen und diese auf einen Webserver hochladen. Und genau das werde ich in diesem Artikel beschreiben.
Als OS setzte ich hier Raspbian vorraus, da ich eben diese Distribution verwende. Die Software, die wir für unser Vorhaben benötigen ist fswebcam und ncftp. Also kümmern wir uns zunächst darum, dass unsere Quellen und die Pakete aktuell sind:
sudo apt-get update && sudp apt-get upgrade
Dann können wir fswebcam installieren:
sudo apt-get install fswebcam
Und anschließend ncftp:
sudo apt-get install ncftp
Falls noch nicht geschehen sollte jetzt die Webcam mit einem USB-Port verbunden werden!
Wenn nur eine Webcam am Raspberry Pi hängt, dann sollte diese als /dev/video0 eingebunden sein. Dies ist allerdings nur von Interesse, wenn man mehrere Cams betreiben möchte oder für eine eventuelle Fehlersuche, denn fswebcam benutzt die erste Kamera, die es findet.
Ob fswebcam funktioniert überprüfen wir mit dem Aufruf fswebcam image.jpg
pi@raspcam ~ $ fswebcam image.jpg --- Opening /dev/video0... Trying source module v4l2... /dev/video0 opened. No input was specified, using the first. Adjusting resolution from 384x288 to 352x288. --- Capturing frame... Captured frame in 0.00 seconds. --- Processing captured image... Writing JPEG image to 'image.jpg'. pi@raspcam ~ $
Wie man sieht, wurde ein Bild als image.jpg gespeichert. Allerdings ist das nur in einer sehr bescheidenen Auflösung passiert (384 mal 288 Pixel). Das Programm verwendet für alle Einstellugen (sogenannte ‚controls‘) seine Default-Werte und das gilt auch für solche Einstellungen wie z.B. Helligkeit und Kontrast.
Nicht alle Kameras bieten die gleichen Einstellungsmöglichkeiten und für jede Kamera und Aufnahmesituation müssen diese Parameter erst gesetzt werden.
Einen Überblick, über die unterstützen controls findet man für seine Kamera mit dem Befehl fswebcam –list-controls heraus. Hier die Ausgabe für meine Kamera, eine Logitech HD Webcam C525:
pi@raspcam ~ $ fswebcam --list-controls --- Opening /dev/video0... Trying source module v4l2... /dev/video0 opened. No input was specified, using the first. Available Controls Current Value Range ------------------ ------------- ----- Brightness 140 (54%) 0 - 255 Contrast 33 (12%) 0 - 255 Saturation 32 (12%) 0 - 255 White Balance Temperature, Auto True True | False Gain 16 (6%) 0 - 255 Power Line Frequency 60 Hz Disabled | 50 Hz | 60 Hz White Balance Temperature 6396 (97%) 2800 - 6500 Sharpness 25 (9%) 0 - 255 Backlight Compensation 1 0 - 1 Adjusting resolution from 384x288 to 352x288. --- Capturing frame... Captured frame in 0.00 seconds. --- Processing captured image... There are unsaved changes to the image. pi@raspcam ~ $
Damit man nicht jedes mal eine riesige Latte von Parametern beim Aufruf von fswebcam mitgeben muss, kann man sich eine Konfigurationsdatei erstellen und diese beim Programmaufruf einbinden. Nachfolgend seht Ihr meine erste Konfigurationsdatei:
pi@raspcam ~/conf $ cat .fswebcam device /dev/video0 input 0 skip 50 resolution 1280x720 set brightness=55% set contrast=13% set sharpness=10% jpeg 95
Interessant ist hier die Zeile ’skip 50′. Dies gibt an, dass die ersten 50 Bilder verworfen werden sollen und gibt der Kamera somit Zeit zum Fokussieren. Der Rest kann den man-pages zu fswebcam entnommen werden.
Damit kann nun aber fswebcam wie folgt aufgerufen werden:
fswebcam -c /home/pi/conf/.fswebcam image.jpg
Wobei ‚-c‚ den Pfad zur Konfigurationsdatei beschreibt.
Jetzt kommen wir zum automatisierten Knipsen und Hochladen:
Für das Erstellen der Bilder habe ich mir ein kleines Bash-Skript capture.sh geschrieben:
Dafür gebt Ihr in der Konsole folgendes ein:
nano capture.sh
Kopiert dann folgendes in die Datei:
#!/bin/bash #set up the paths and file names filename="image" filepath="/home/pi/webcam" #process the arguments while getopts f:h? opt; do case "$opt" in f) filename=$OPTARG;; h|?) echo "usage is [-f <filename>]" >&2 exit 1 ;; *) echo "Invalid option: -$OPTARG" >&2 exit 1 ;; esac done now=`date +"%Y%m%d_%H%M%S"` filename+="_${now}.jpg" partname="${filename}.part" partpath="${filepath}/${partname}" filepath+="/${filename}" fswebcam -q -c /home/pi/conf/.fswebcam $partpath mv $partpath $filepath echo "[$(date +"%d.%m.%Y %H:%M:%S")] picture ${filename} taken"
Zum Speichern: Strg+X, Shift+Y und Enter
Kurz gesagt erstellt das Skript ein Bild mit dem Dateinamen im Format image_<Datum>_<Uhrzeit>.jpg.part und benennt es anschließen in <Dateiname>_<Datum>_<Uhrzeit>.jpg (ohne .part) um. Optinal kann man dem Skript noch mit dem Schalter -f <Dateiname> einen Namen mitgeben, der das ‚image‚ im Dateinamen ersetzt.
Den Wert der Variablen filepath (bei mir /home/pi/webcam) müsst Ihr auf Euren Speicherort für die Bilder abändern. Und ggf. müsst Ihr noch den Pfad zu Eurer Konfig-Datei für fswebcam anpassen.
Wenn Ihr Euch fragt, was das denn bitte mit dem ‚.part‘ soll… dazu kommen wir gleich noch.
Denn jetzt kommt das zweite Skript, welches uns per FTP ein Bild auf einen Webserver kopieren soll:
Wir bemühen wieder den nano-Editor und geben folgendes ein die Konsole ein:
nano upload.sh
#!/bin/bash ### # This script takes the latest jpg-file from the source-path and # creates a temporary copy in the same directory (uploadname). # Once this is done the temp-file will be copied to a webserver # using ncftpput. # Temp-file will be cleaned at the begining and at the end of the script # (see 'rm' commands). # The full path to 'rm' and 'cp' is used to prefent using aliases of the commands. ### #set up the paths and file names sourcepath="/home/pi/webcam" sourcefile=$(ls -1t "$sourcepath"/*.jpg | head -n1) uploadname="$sourcepath"/"webcam.jpg" ftppath="/webcam" echo "[$(date +"%d.%m.%Y %H:%M:%S")] uploading picture ${sourcefile}..." /bin/rm -f "$uploadname" /bin/cp -f "$sourcefile" "$uploadname" ncftpput -V -S .tmp -u <user> -p <password> meinserver.de "$ftppath" "$uploadname" /bin/rm -f "$uploadname" echo "[$(date +"%d.%m.%Y %H:%M:%S")] picture uploaded as ${uploadname}"
Zum Speichern: Strg+X, Shift+Y und Enter
In dem Skript müssen sourcepath (zeigt bei mir auf /home/pi/webcam), der Name mit der die Datei auf dem Webserver landen soll (bei mir webcam.jpg) und der Pfad auf dem Server ftppath (bei mir /webcam) nach Euren Bedürfnissen angepasst werden. Außerdem müsst Ihr natürlich Eueren User, das Passwort und den Hostnamen Eures Webservers ergänzen.
ACHTUNG! Der sourcepath aus diesem Skript muss gleich dem filepath aus dem ersten Skript sein!
Die Funktionsweise diese Upload-Skripts ist folgende:
Es wird die neuste Datei mit der Endung ‚jpg‚ aus dem Verzeichnis geholt, in dem Ihr Eure Bilder ablegt (also sourcepath bzw. filepath) und anschließend auf den Webserver mit einem bestimmten Dateinamen hochgeladen. Weil ich immer die neueste Datei vom Typ jpg hole, gehe ich im ersten Skript auf Nummer Sicher und erzeuge erst die .part-Datei, die anschließend umbenannt wird. Denn ich möchte verhindern, dass fswebcam eine Datei eventuell noch nicht fertig geschrieben hat und das zweite Skript aber schon versucht diese Datei hochzuladen bzw. zu kopieren.
Das Ganze hört sich vielleicht etwas umständlich an, denn man könnte auch ein viel einfacheres Skript schreiben wie zum Beispiel das hier:
nano capture_upload.sh
#!/bin/bash #set up the paths and file names filename="image" filepath="/home/pi/webcam" uploadname="webcam.jpg" uploadpath="/webcam" #process the arguments while getopts f:h? opt; do case "$opt" in f) filename=$OPTARG;; h|?) echo "usage is [-f <filename>]" >&2 exit 1 ;; *) echo "Invalid option: -$OPTARG" >&2 exit 1 ;; esac done now=`date +"%Y%m%d_%H%M%S"` tmpfile="${filepath}/${uploadname}" filename+="_${now}.jpg" filepath+="/${filename}" fswebcam -q -c /home/pi/conf/.fswebcam $filepath cp $filepath $tmpfile echo "picture ${filename} taken" ncftpput -V -u <user> -p <password> meinserver.de $uploadpath $tmpfile echo "picture uploaded as ${uploadname}"
Zum Speichern: Strg+X, Shift+Y und Enter
Und dran denken, dass auch hier wieder filepath, uploadname und uploadpath, sowie User, Passwort und Host des Servers angepasst werden müssen!
Das Skript capture_upload.sh hat den Nachteil, dass immer ein Foto gemacht und dieses dann auch hochgeladen wird. Für meinen Anwendungsfall wollte ich allerdings alle 2 Minuten ein Bild machen, und nur alle 10 Minuten ein Bild an den Webserver schicken.
Wie das geht zeige ich Euch jetzt noch. Hierfür machen wir entsprechende Eintrage in die Crontab.
Diese editieren wir mit dem Aufruf:
crontab -e
Für die Variante mit den beiden separaten Skripte und meinem Anwendungsfall könnte die Crontab so aussehen:
#Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any'). # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command */2 7-20 * * 1-6 /home/pi/script/capture.sh >> /home/pi/webcam/capture.log */10 7-20 * * 1-6 /home/pi/script/upload.sh >> /home/pi/webcam/capture.log
Hier wird alle 2 Minuten zwischen 7 und 20 Uhr von Montag bis Samstag das Skript capture.sh aufgerufen.
Das Skript upload.sh wird im gleichen Zeitraum aufgerufen, allerdings nur alle 10 Minuten.
Mit ‚>> /home/pi/webcam/capture.log‘ leite ich die Log-Ausgaben (die echo-Befehle) eine Log-Datei um.
Und hier ist noch ein Beispiel für einen Crontab-Eintrag der Ein-Skript-Variante. Es wird im gleichen Zeitraum wie oben (und in 10 Minuten Abständen) ein Bild aufgenommen und auf den Webserver geladen:
# Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any'). # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command */10 7-20 * * 1-6 /home/pi/script/capture_upload.sh >> /home/pi/webcam/capture.log
Zum Schluß noch der Link zu meiner Webcam: http://oldzitterhand.de/webcam/
Viel Spaß!
Schreibe einen Kommentar