USB-Webcam im Netzwerk bereitstellen und Fotos archivieren

0 Kommentare

Der ein oder andere kennt das vielleicht von privaten oder öffentlichen Wetterstationen: Eine Webcam, die in die Ferne zeigt und wo genug Himmel drauf zu sehen ist. Damit man das Wetter am jeweiligen Ort selbst begutachten kann und auch z.B. in der Natur sieht, dass Schnee liegt und ähnliches. Ich selbst finde sowas schön und wollte sowas mit meinem kleinen Server realisieren, zumal ich ein ähnliches Projekt 2009 bereits am laufen hatte, damals jedoch an einem anderen Standpunkt.
Das Ziel dieser Anleitung ist, eine Webcam unter Linux (Debian) zum laufen zu bringen, jede Minute automatisch ein Foto zu machen und dies zu archivieren. Außerdem soll es bereitgestellt werden, sodass man z.B. mit der eigenen Homepage darauf zugreifen kann oder sich andere Dienste das Webcambild holen können (bei Wetterstationen z.B. Weather Underground). Des Weiteren gibt es mit einem kleinen Script noch die Möglichkeit, aus den einzelnen Fotos ein Zeitraffer zu erstellen.

Also legen wir mal los.
Zuerst die Webcam via USB verbinden. Dank aktuellem Kernel wird die Webcam in den meisten Fällen problemlos Plug’n’Play erkannt und wir können sofort los legen. In meinem Falle ist dies eine etwas ältere Logitech QuickCam Communicate STX. Jedoch gibt es auch viele aktuelle Logitech Webcams, welche für wenig Geld zu haben sind und eine gute Qualität haben. Außerdem lassen sich bei denen auch Parameter anpassen, welche teilweise nützlich sind, dazu jedoch später mehr.
Alle Befehle werden übrigens als root ausgeführt.

Mittels lsusb überprüfen wir, ob die Webcam korrekt erkannt wurde. Daraufhin bekommen wir eine Liste aller angeschlossenen USB-Geräte, darunter bei mir:

[...]
Bus 001 Device 005: ID 046d:08ad Logitech, Inc. QuickCam Communicate STX
[...]

Somit ist unsere Webcam erreichbar und wir können uns darum kümmern, dass wir ein Bild bekommen.

Ein Foto mit der Webcam machen

Da unser Server keine grafische Oberfläche hat, erledigen wir alles von der Shell aus. Dort kann man mittels ffmpeg (Name des Pakets. Der Befehl heißt inzwischen avconv, also nicht verwirren lassen) ein Foto von einer Videoquelle aufnehmen.
Dazu erstmal ffmpeg installieren, falls dies noch nicht geschehen ist:

$ apt-get install ffmpeg

Jetzt können wir ein Foto aufnehmen:

$ avconv -f video4linux2 -s 640x480 -r 1 -i /dev/video0 -vframes 1 -f image2 webcam.jpg  

Dabei sollte /dev/video0 in dem Fall die Webcam sein. Sind weitere Video-Eingänge vorhanden, z.B. von einer TV-Karte, so muss man alles durch probieren. So habe ich bei mir z.B. video0 und video1 zur Auswahl.
Bei video0 kam bei mir ein Fehler, da das die TV-Karte ist. Daraufhin video1 probiert und siehe da, es geht.
Der Befehl nutzt den video4linux2 Codec um ein Webcam-Bild mit der Auflösung 640x480px (VGA) aufzunehmen. Das es nur ein Foto sein soll und kein Video wird auch noch einmal dadurch klar, dass wir nur 1 Frame aufnehmen. Gespeichert wird das Bild dann als webcam.jpg im aktuellen Ordner.
Hilfreich mag vielleicht auch der Webcam Artikel im Ubuntuusers.de Wiki sein.

Ergebnis: Das Bild ist komplett weiß. Wieso? Weil die Webcam aus dem Fenster schaut und es draußen für Webcam Verhältnisse viel zu hell ist.
Wie man es vom Webcam-chatten kennt, braucht die Webcam meist ein wenig Zeit um sich an die Helligkeit zu gewöhnen, nachdem diese angeschaltet wurde. Also bräuchten wir hier sozusagen einen Timer, der x Sekunden wartet, bevor ein Foto gemacht wird. Aber auch das hilft nicht immer. Außerdem sind Webcams nicht unbedingt dafür geeignet, um aus dem Fenster zu schauen. Zumindest nicht jene Modelle, die nicht wirklich auf Helligkeitsregelungen von Linux hören. Daher muss eine manuelle Hilfe her!

Der beste Weg um die Webcam abzudunkeln

Die Bilder der Webcam sind also deutlich zu hell. Nach längerem herumprobieren fand ich eine passende Lösung. Mit Hilfe einer dritten Hand aus dem Elektro-Zubehör habe ich zwei dunkle Sonnenbrillengläser vor die Webcam gehängt. Diese liegen aufeinander und sind recht dunkel, womit das Bild schon mal deutlich abgedunkelt wird. Das Ergebnis ist ein akzeptables Bild. Zwar immer noch nicht perfekt, aber bei direkter Sonneneinstrahlung versagen wohl die meisten günstigen Webcams.

Die Webcam im Web bereitstellen

Damit man von jedem PC aus auf die Webcam zugreifen kann, gibt es eine kleine Software namens motion. Diese streamt das aktuelle Webcam-Bild automatisch auf einem eingestellten Port. Aktuell nutze ich die Software nicht mehr, da ich mit Hilfe meiner Skripts automatisch jede Minute ein Bild aufnehme. Dazu komme ich jedoch später. Wer also keinen Pseudo-Livestream (ist ja nicht wirklich in Echtzeit) benötigt, kann diesen Teil überspringen.
Also installieren wir motion:

$ apt-get install motion

Damit motion beim Systemstart gestartet wird, müssen wir dies in der /etc/default/motion einstellen:

start_motion_daemon = yes

Somit wird motion automatisch gestartet.
Jetzt stellen wir noch die /etc/motion/motion.conf ein:
Dort einmal die Videoquelle einstellen: videodevice /dev/video1 (Zeile 29), wobei man video1 durch die jeweilige Videoquelle ändern muss, die bei einem selbst funktioniert hat.
Dann die Auflösung der Kamera:

width 640
height 480

(Zeile 70 + 72)
Und die Bildwiederholrate wenn wir uns das live-Bild im Browser anschauen: framerate 5 (Zeile 77), wodurch wir 5 Bilder die Sekunde erhalten, was vollkommen ausreichend ist.

Jetzt können wir motion starten:

$ motion

Also schauen wir einmal, was motion uns schreibt. Nach ein paar Sekunden kommt bei mir, dass der Stream auf Port 8081 gestartet ist und dass alles erfolgreich initalisiert wurde.
Somit greifen wir mal darauf zu: http://server:8081 .
Doch es kommt zu einem Fehler. Es ist kein Zugriff möglich. Warum? Weil nur der Localhost darauf zugreifen darf. Eine Lösung dazu fand ich im Raspberry Pi Forum.
Somit bearbeiten wir erneut die /etc/motion/motion.conf:

webcam_localhost off (Zeile 413)
control_localhost off (Zeile 429)

-> Jetzt ist der Zugriff von allen Rechnern möglich. Am saubersten lief es bei mir unter folgender Adresse: http://server:8081/?action=stream
Unten rechts wird Datum + Uhrzeit eingeblendet und da sehen wir, dass es dauerhaft aktualisiert wird.

Wer über eine moderne Webcam verfügt, die sich was von den Linux-Einstellungen sagen lässt, dann kann man versuchen, in der /etc/motion/motion.conf zwei Parameter anzupassen und mit den brightness Werten herumzuprobieren. Das hatte bei meiner leider keinen Erfolg…

auto_brightness on (Zeile 112)
brightness 10 (Zeile 118)

Eine komfortable FFMpeg Alternative

19_26
Ich möchte nun zwei Wege zeigen, um ein Webcambild zu machen und Datum + Uhrzeit einzufügen. Als erstes einmal der leichte. Dazu gibt es eine Software namens fswebcam.
Fswebcam erlaubt uns dazu auch noch ein paar Parameter, welche am besten in einer .conf-Datei abgelegt werden, die von fswebcam eingelesen wird.

$ apt-get install fswebcam
$ fswebcam -c /home/sofa/cam.conf -D 2 aktuell.jpg

Hier wird jetzt also fswebcam installiert und danach aufgerufen. Dabei wird die cam.conf eingelesen, es wird 2 Sekunden gewartet (Delay zwischen Start der Webcam + Foto, damit sich z.B. die Helligkeit regeln kann) und dann als aktuell.jpg gespeichert.
Der Inhalt der cam.conf sieht wie folgt aus:

device /dev/video1
jpeg 95
skip 20
resolution 640x480
title "Wetterstation"
set "White Balance Temperature, Auto"=True
set "Contrast"=30
set "Saturation"=40
frames 1

Dabei sollten die Parameter soweit eigentlich selbsterklärend sein. Fswebcam funktioniert gut und zuverlässig, schaut auch ganz gut aus (siehe Bild am Anfang des Abschnitts), jedoch wollte ich etwas flexibler sein. Somit bleibt noch die Möglichkeit, sich das selbst zu basteln.

Foto mit FFMpeg inklusive Text-Overlay

20_32
Am Anfang habe ich bereits gezeigt, wie wir mit Hilfe von ffmpeg bzw. avconv ein Foto mit der Webcam machen können. Jedoch möchte ich außerdem Datum + Uhrzeit eingeblendet bekommen.
Das ganze ist etwas umständlich, jedoch lernt man dabei auch ein wenig den Umgang mit ImageMagick. Jenes Tool ist verdammt mächtig und erlaubt einem Bildmanipulationen ohne Ende.
Ich möchte jetzt nicht genauer auf den Umfang des Tools eingehen. Dazu muss sich jeder selbst mal die Manual auf der Homepage von ImageMagick bzw. in Wikipedias geben, zumal man auch immer ein wenig herum experimentieren muss.
Das Prinzip ist, dass wir einmal das aktuelle Webcambild haben. Dann erstellen wir eine transparente PNG-Datei mit den gleichen Maßen wir das Webcambild. Die beiden Dateien werden dann übereinander gelegt und siehe da, wir haben Text auf unserem Bild.

$ convert -size 640x480 xc:transparent -font Courier-bold -pointsize 10 -fill GhostWhite -draw "text 10,15 '20. April 2014 | 19:45:00'" output.png

Erstellt ein transparentes Bild mit 640x480px wo in Courier Fett bei 10pt in der Farbe GhostWrite „20. April 2014 | 19:45:00“ oben links in die Ecke geschrieben wird. Diese Datei heißt output.png. Schriftart und Inhalt kann man natürlich jeder Zeit anpassen, ebenso die Position und alles weitere.

$ composite -dissolve 100% -quality 100 output.png image.jpg output.jpg

Dieser Befehl nimmt das Webcambild (image.jpg) und unser Text-Overlay (output.png) und bastelt die beiden Dateien zu output.jpg zusammen. Ergebnis ist das Webcambild mit Text.

Hilfreiche Links:

Automatisieren

Cronjob macht uns das Leben leicht. Jenes Programm soll jede Minute ein Skript von uns aufrufen. Das Ziel des Skripts ist, ein Foto zu machen, Text-Overlay hinzufügen und das ganze abspeichern und archivieren.
webcam_photo.sh:

#!/bin/sh

ORDNER="/var/www/cam"
ZEIT=$(date +"%d.%m.%Y | %H:%M:%S")

# Foto abspeichern unter ORDNER/tmp.jpg
avconv -f video4linux2 -s 640x480 -r 1 -i /dev/video-webcam -vframes 1 -f image2 $ORDNER/tmp.jpg
#fswebcam -c /home/sven/webcam/cam.conf -D 2 $ORDNER/aktuell.jpg

# Datum + Uhrzeit bereitstellen
convert -size 640x480 xc:transparent -font Courier-bold -pointsize 10 -fill GhostWhite -draw "text 10,15 '$ZEIT'" $ORDNER/tmp.png

# Beides zusammenfuegen als aktuell.jpg
composite -dissolve 100% -quality 100 $ORDNER/tmp.png $ORDNER/tmp.jpg $ORDNER/aktuell.jpg

# Datei archivieren unter ORDNER/YYYY/MM/DD/HH_II.jpg
ARCHIV=$(date +"/archiv/%Y/%m/%d/")
DATEI=$(date +"%H_%M.jpg")

# Ordner anlegen falls nicht vorhanden
mkdir -p $ORDNER$ARCHIV

cp $ORDNER/aktuell.jpg $ORDNER$ARCHIV$DATEI

Das beinhaltet auch die Möglichkeit, mit fswebcam zu arbeiten. Dazu einfach die jeweilige Zeile auskommentieren und dafür avconv und die ImageMagick Befehle convert und composite auskommentieren, da diese dann nicht mehr benötigt werden.
Ansonsten dürfte das Skript sich soweit selbst erklären. Das aktuelle Bild finden wir im Web-Ordner unter /cam/aktuell.jpg. Außerdem gibt es das Archiv unter /cam/archiv/JAHR/MONAT/TAG/. Alle Dateien werden automatisch verwaltet, es wird ein neuer Ordner angelegt für jedes Jahr, jeden Monat und jeden Tag, voll automatisch. Und der Grund-Ordner kann ganz oben als Variable angepasst werden.
Das Skript muss nun noch ausführbar gemacht werden mittels chmod +x webcam_photo.sh.
Führen wir nun das Skript aus, erhalten wir hoffentlich folgende Ausgabe (falls wir mittels ffmpeg arbeiten):

$ ./webcam_photo.sh
avconv version 0.8.10-6:0.8.10-1, Copyright (c) 2000-2013 the Libav developers
built on Feb  5 2014 17:15:30 with gcc 4.7.2
[video4linux2 @ 0x89459a0] max_analyze_duration reached
[video4linux2 @ 0x89459a0] Estimating duration from bitrate, this may be inaccurate
Input #0, video4linux2, from '/dev/video1':
  Duration: N/A, start: 716888.880822, bitrate: N/A
	Stream #0.0: Video: mjpeg, yuvj422p, 640x480, 0 kb/s, 1 fps, 1 tbr, 1000k tbn, 1 tbc
[buffer @ 0x8945800] w:640 h:480 pixfmt:yuvj422p
Output #0, image2, to '/var/www/webcam/tmp.jpg':
  Metadata:
	encoder         : Lavf53.21.1
	Stream #0.0: Video: mjpeg, yuvj422p, 640x480, q=2-31, 200 kb/s, 90k tbn, 1 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg -> mjpeg)
Press ctrl-c to stop encoding
frame=    1 fps=  0 q=4.0 Lsize=      -0kB time=1.00 bitrate=  -0.2kbits/s
video:26kB audio:0kB global headers:0kB muxing overhead -100.081967%

Das Skript läuft somit sauber durch. Super!

Cronjob einrichten

Wir bearbeiten die /etc/crontab und fügen ganz unten dann die nachfolgende Zeile ein.
$ vim /etc/crontab

*/1 6-21 * * * root /home/sven/webcam/webcam_photo.sh > /dev/null 2>&1

Die Zeile besagt, dass jede Minute, zwischen 6:00 Uhr und 21:59 Uhr das Skript ausgeführt wird. Die Ausgabe wird dabei verworfen. Schöne Beispiele zu Cronjobs bietet mal wieder das ubuntuusers.de Wiki.

Webcambild optimieren

Meinen Weg zur Bild-optimierung habe ich bereits geschrieben. Bei mir reichen zwei Sonnenbrillengläser aus und das Bild ist akzeptabel. Moderne Webcams wie unter dem Link, den ich am Anfang erwähnt habe, bieten die Möglichkeit, automatisch die Helligkeit zu regulieren. Das nimmt einem viel Arbeit ab und das Bild dürfte deutlich besser sein. Unter Umständen soll auch das Tool v4l-utils helfen, da man damit manuell Werte wie die Helligkeit setzen kann, insofern die Webcam das unterstützt.

Zeitraffer-Video erstellen

Wer ein wenig mit ffmpeg (avconv) herumspielt, der findet auch ziemlich schnell heraus, dass damit Zeitraffer-Videos möglich sind. Dazu reicht ein einzeiliger Befehl und alle Fotos im jeweiligen Ordner werden genommen und zu einem Zeitraffer zusammengefügt. Zumal nach meinem Archiv-Skript die Bilder nach Stunde_Minute.jpg gespeichert werden, reicht es, wenn sich die Software die Dateien alphabetisch holt.

avconv -f image2 -pattern_type glob -i "*.jpg" -r 20 tag.mov

Das bezieht sich auf die jpg Dateien im aktuellen Ordner. Dies könnte man in Skript-Form anpassen, dass z.B. jeden Tag um Mitternacht ein Video erstellt wird, wobei man dann den absoluten Pfad zu den Bildern nimmt und mit dem date Befehl den Tag herausfiltert, wie ich es in meinem obigen Skript getan habe. Gespeichert ist das Video dann als tag.mov.

Fazit

Mit ein wenig Aufwand ist es möglich, seine Webcam zu automatisieren und jede Minute ein Foto zu machen. Somit hat man sein eigenes Archiv, kann Zeitraffervideos erstellen und da das aktuelle Bild immer gleich heißt (cam/aktuell.jpg) können andere Dienste darauf zugreifen. Das funktioniert bei mir seit einiger Zeit wunderbar mit Weahter Underground. Und eine alte Webcam hat somit noch einen schönen Verwendungszweck. Wer allgemein gerne bastelt, kann diese auch gerne auseinander nehmen und vielleicht bei der Linse eine kleine Blende basteln oder sonst irgendwie versuchen, das Bild abzudunkeln / zu optmieren.
Ich hoffe, dass die Anleitung dem ein oder anderen helfen kann. Meine Webcam läuft zusammen mit dem Skript seit über einem Monat stabil und es ist immer ganz schön, auf der Wetterstations-Seite noch ein Webcambild zu haben. Oder sich den Zeitraffer vom letzten Tag anzuschauen.

Teile den Artikel mit Deinen Freunden!

Weitere Empfehlungen für Dich!

Hey, ich bin der Sven!

Ich programmiere und fotografiere. Bin im Web und auf der Linux-Konsole zuhause. Meine Homebase ist Frankfurt am Main. Ich reise gerne durch die ganze Welt und lese viel. Denke viel nach. Und auf diesem Blog zeige ich von allem etwas. Jede Woche neu. Das hier bin ich in Blog-Form. Ich bin der Sven, Hi!



Folge mir: facebook, twitter, instagram

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.