Raspberry Pi: Kamera einrichten und verwenden

Prof. Jürgen Plate

Raspberry Pi: Kamera einrichten und verwenden

Seit Mai 2013 ist für den Raspberry Pi ein winziges, aber leistungsfähiges Kamera-Modul erhältlich. Anfang 2014 kan ein zweites Modell hinzu, das Nachtaufnahmen mit Infrarot-Beleuchtung erlaubt. Die technischen Daten sind in der folgenden Tabelle zusammengefasst:

Abmessungen25 mm x 20 mm x 9 mm
Sensor5 Megapixel mit Fixfokusobjektiv
Fotoauflösungbis 2592 x 1944 Pixel
Videoauflösung1920 x 1080 / 30 Frames
1280 x 720 / 60 Frames
640 x 480 / 60 oder 90 Frames
Kabellängeca. 150 mm
VersionenRaspberry Pi Kamera
Raspberry Pi Kamera Infrarot

Das Kamera-Modul wird in einem Antistatikbeutel mit vormontiertem Flachbandkabel geliefert. Der Anschluss der Kamera erfolgt über die 15-polige serielle MIPI-Schnittstelle (CSI - Camera Serial Interface) auf dem Raspberry Pi. Der Vorteil dieser Schnittstelle gegenüber USB besteht in der direkten Verbindung von Kamera-Modul und dem Broadcom BCM2835 (SoC). Die Infrarot-Version (NoIR) kann "im Dunklen sehen", zeigt aber bei Tageslicht eine leichte Farbverfälschung. Hier wird besser die "Normalversion" verwendet - oder man spendiert einen Infrarotfilter.

Da hier nur die wichtigsten Optionen und Möglichkeiten von Kamera und Software besprochen werden, sei jetzt schon auf die Dokumentation im Web verwiesen:

Das natürlich auf den Webseiten des Raspberry Pi selbst auch etwas über die Kamera steht, brauche ich wohl nicht mehr zu erwähnen.

Kamera anschliessen

Die CSI-Schnittstelle befindet sich zwischen der HDMI- und der Ethernet-Buchse. Um das 15-polige Flachbandkabel vom Kamera-Modul mit dem Board zu verbinden zieht man den oberen Teil des CSI-Steckverbinders etwas nach oben, steckt dann das Flachbandkabel mit der blauen Markierung zum Ethernet-Anschluss hin ein und drückt den Verschluss wieder nach unten. Nun ist der Kontakt hergestellt und das Kabel sitzt fest.

Nun muss noch der Kamera-Support in Raspbian aktiviert werden, was am Einfachsten über das Konfigurationstools raspi-config erledigt wird. Dort einfach die Kamera auf "Enable" setzen. Zum Abschluss muss der Raspberry Pi noch rebootet werden, damit die Kamera genutzt werden kann.

Wenn Sie die rote Aufnahme-LED stört, können Sie diese deaktivieren. Dazu ist ein neuer Eintrag in der Datei /boot/config.txt mit anschließendem Neustart notwendig:

disable_camera_led=1
Einmal mit der obigen Methode deaktiviert, lässt sich die LED über den GPIO 5 steuern (näheres über das Ansprechen des GPIO finden Sie z. B. im Kapitel Raspberry Pi: GPIO per Shell-Kommando ansteuern). Der GPIO wird aktiviert mit:
sudo echo "5" > /sys/class/gpio/export
sudo echo "out" > /sys/class/gpio/gpio5/direction
sudo chmod 666 /sys/class/gpio/gpio5/value
Danach können Sie die LED einschalten mit dem Kommando
echo "1" > /sys/class/gpio/gpio5/value
und wieder ausschalten mit
echo "0" > /sys/class/gpio/gpio5/value

Einzelbilder oder Bildsequenzen aufnehmen

Das Kamera-Modul wird über die beiden Programme raspistill (für Bilder) und raspivid (für Videos) angesprochen, die über zahlreiche Optionen verfügen. Auch eine Python-Bibliothek ist verfügbar. raspivid speichert Videos ausschließlich im H264-Format ab. Die Datei muss daher für die meisten Zwecke zuerst in ein gebräuchliches Format konvertieren werden (etwa mit gpac). Das Aufnehmen von Bildern ist recht einfach, wie die folgenden Beispiele zeigen:

# Aufnahme im JPG-Format (default)
raspistill -o image.jpg

# Aufnahme in anderen Formaten mit -e <Format>
# möglich sind: jpg, bmp, gif und png, z. B.
raspistill –e png -o image.png 

# Aufnahme ohne Preview mit -n oder --nopreview
raspistill -n -o image.jpg

# Zeitverzögerte Aufnahme mit -t <Millisekunden>
# ACHTUNG: Default ist -t 5000, wenn es schnell gehen
# soll, dann -t 0 verwenden
raspistill  -t 2000 -o image.jpg

# Aufnahme in einer niedrigeren Auflösung mit -w und -h
# z. B. 640 x 480 pixel
raspistill  -w 640 -h 480 -o image.jpg

# Aufnahme in einer niedrigeren Qualität (Angabe in %-Werten)
raspistill -q 50 -o image.jpg
Die Vorschaubilder lassen sich ebenfalls an- und abschalten: -f liefert eine Vorschau im Vollbildmodus, -n unterdrückt die Vorschau. Die Größe der Vorschau kann mittels -p eingestellt werden. Natürlich können Sie auch Werte wie Helligkeit, Kontrast, Bildschärfe oder Farbsettigung steuern. Aufschluss über die Möglichkeiten bietet der Parameter --help. Geben Sie -v (verbose) an, erzählt Ihnen das Programm, was es gerade macht.

raspistill kann auch für Zeitraffer-Aufnahmen genutzt werden. Dazu muss beim Dateinamen ein Zähler festgelegt werden. Das geschieht durch einen Platzhalter, wie er bei der C-Funktion printf oder auch beim time-Kommando verwendet wird. Er hat die Form "%xxd", wobei für xx die Zahl der Dezimalstellen eingesetzt wird. Damit später beim Sortieren kein Mist entsteht, müssen alle Zahlenwerte gleich lang sein, denn sonst kommt "10" nach "1" und nicht die "2". Das wird durch eine führende "0" erreicht. Für beispielsweise vier Stellen schreibt man "%04d". Das ergibt dann insgesamt z. B. einen Dateiangabe wie "bild_%04d.jpg", die zu den Namen "bild_0001.jpg", "bild_0002.jpg" usw. führt.

Im Fall von Zeitrafferaufnahmen wird mit -t die gesamt-Aufnahmedauer angegeben und mit -tl die Wartezeit zwischen zwei Aufnahmen (alle erfolgen wieder in Millisekunden). Mit dem folgendem Befehl wird eine Stunde lang (-t 3600000) alle 10 Sekunden (-tl 10000) ein Bild aufgenommen:

raspistill -tl 10000 -t 3600000 -o camera/bild_%04d.jpg
Um ein schickes Zeitraffer-Video zu bekommen, müssen Sie aus den vielen Einzelbilder nun mit ffmpeg noch ein Video erzeugen:
ffmpeg -qscale 5 -r 4 -b 9600 -i camera/bild_%04d.jpg camera/filmchen.mp4

Videos aufnehmen

Für die Aufnahme von Videos wird raspivid verwendet. Das Programm kennt viele der Bildbarameter von raspistill, darunter -v, -w, -h, -o oder die Einstellungen von Kontrast, Helligkeit etc. Die Framerate kann mit -fpr (frames per second) eingestellt werden. Mit dem Parameter -t gibt man die Aufnahmezeit in Millisekunden an. Für eine beliebig lange Aufnahme (z. B. für einen Stream) wird der Wert auf 0 gesetzt (Default: 5 Sekunden). Das voreingestellte Videoformat ist 1080p (1920 x 1080 Pixel). Abgespeichert wird, wie erwähnt, im H264-Format. Die folgenden Beispiele erklären die wichtigsten Parameter:

# 10-Sekunden-Video in 1080p (1920 x 1080)
raspivid  -t 10000 -o video.h264

# 10-Sekunden-Video in 720p (1280 x 720)
raspivid -t 10000 -w 1280 -h 720 -o video.h264

# 10-Sekunden-Video mit individueller Bitrate (3 MBits/s)
raspivid -t 10000 -b 3000000 -o video.h264

# 10-Sekunden-Video mit individueller Framerate (10 Frames/Sekunde)
raspivid -t 10000 -f 10 -o video.h264

# 10-Sekunden-Videostream an stdout schicken (Dateiname ist "-")
raspivid -t 10000 -o -

Um das erzeugte H264-Video in das gebräuchlichere MPEG4-Format umzuwandeln, greifen wir auf das Zusatzpaket gpac zurück, das sich unter Raspbian mittels apt-get installieren lässt. Die Konvertierung erfolgt dann z. B. mit:

MP4Box -fps 30 -add video.h264 video.mp4
Die Homepage von gpac ist gpac.wp.mines-telecom.fr/. Das Paket besteht aus einem Multimedia-Player, der "Osmo4" bzw. "MP4Client" heisst, einem Multimedia-Packager, "MP4Box", der oben zur Anwendung kommt und einigen Servertools.

Streaming auf ein anderes System

Sie können, falls der RasPi ohne Grafik läuft, die Videos auch gleich auf einen anderen Linux-Rechner streamen. Dafür kommt das "Schweizer Taschenmesser des Internets", Netcat zum Einsatz. Netcat kann auch wieder mit apt-get installiert werden. Auf dem Raspberry wird der Video-Stream in Netcat (nc) geleitet, das für die Übertagung zum fernen Client mit der IP-Adresse 10.1.1.1 sorgt. Als Portnummer wird hier 4711 verwendet:

raspivid  -w 1280 -h 720 -t 0 -o - | nc 10.1.1.1 4711

Auf dem Linux-Client wird zusätzlich zu Netcat der Videoplayer MPlayer (oder VLC oder was auch immer) installiert, um den Stream direkt auf der grafischen Oberfläche anzuzeigen. Netcat läuft hier im Servermodus und wartet auf dem Port 4711 auf die Anfrage des RasPi (beim mplayer wird die Standardeingabe durch den Dateinamen "-" repräsentiert):

nc -l -p 4711 | mplayer -fps 31 -cache 1024 -
Übrigens würde die Darstellung auch auf einer Windows-Kiste funktionieren, weil Netcat und Mplayer/VLC auch für Windows verfügbar sind.

Programmierung

Im Prinzip reichen die beiden Kommandozeilentools vollkommen aus. Will man die Kamera jedoch in eigene Programme einbinden ist es manchmal lästig und nicht zuletzt fehleranfälliger, mit Systemaufrufen zu hantieren. So ist es erfreulich, dass im Python-Modul "Picamera" alle Optionen der Kamera vollständig implementiert. Die Links im ersten Abschnitt führen zur Software und zur Dokumentation.

Die Library bietet nicht nur viele Konfiguraqtionsmöglichkeiten (brightness, contrast, saturation, image effects, exposure modes etc.) sondern erlaubt auch das Kamerabild live anzuzeigen. Natürlich sind, wie auf der Kommandozeile auch Captures und Videos möglich. Ich gestehe auch, dass die Beispiele von der Dokumentation des Moduls inspiriert wurden.

Beim ersten Python-Programm handelt es sich um ein Pendant des Kommandozeilenaufrufs oben. Nach dem Importieren der benötigten Module wird ein Kamera-Objekt erzeugt, die Auflösung eingestellt und ein Bild geschossen:

import picamera
from time import sleep

cam = picamera.PiCamera()
cam.resolution = (640, 480)
cam.start_preview()
time.sleep(5)
cam.stop_preview()
cam.capture('bild.jpg')
cam.close()

Falls bei der Aufnahme auftretende Fehler abgefangen werden sollen (wenn beispielsweise die Kamera deaktiviert ist, kann man einen try-Block verwenden:

import picamera
from time import sleep

cam = picamera.PiCamera()
try:
   cam.resolution = (800, 600)
   cam.start_preview()
   time.sleep(2)
   cam.stop_preview()
   cam.capture('bild.jpg')
finally:
   cam.close()
Oder Sie verwenden das context manager protocol und müssen so keine KameraInstanz anlegen. In folgenden Beispiel wird angenommen, dass die Kamera kopfunter an der Decke hängt - kein Problem, wir vertauschen einfach oben und unten sowie rechts und links:
import picamera
from time import sleep

with picamera.PiCamera() as cam:
try:
   cam.vflip = True
   cam.hflip = True
   cam.resolution = (800, 600)
   cam.start_preview()
   time.sleep(2)
   cam.stop_preview()
   cam.capture('bild.jpg')
finally:
   cam.close()

Sie können auch einmal mit Kameraparametern experimentieren und sich ansehen, was geschieht, wenn Sie die Helligkeit von 0 auf 100 Prozent hochregeln:

import picamera
from time import sleep

with picamera.PiCamera() as cam:
   cam.resolution = (800, 600)
   cam.start_preview()
   for i in range(100):
      cam.brightness = i
      time.sleep(0.2)
   cam.stop_preview()
   cam.close()

Mit Python können Sie aber noch wesentlich mehr anfangen. Das folgende Beispiel skizziert, wie sich das Kamerabild weiter nutzen lässt. Mit Hilfe des Moduls pygame haben Sie ruck-zuck ein Bildschirmfenster, in dem dann das gerade geschossene Bild angezeigt und mit dem Aktuellen Datum nebst Uhrzeit beschriftet wird. Erweiterungen seien Ihrer Phantasie überlassen:

import picamera
import time
import pygame

# Voreinstellungen
WIDTH=1280
HEIGHT=1024
FONTSIZE=50

# Kamera initialisieren
camera = picamera.PiCamera()
camera.vflip = False
camera.hflip = False
camera.brightness = 60

# Bildschirmfenster aufbauen, Hintergrund schwarz, Schrift weiss
pygame.init()
screen = pygame.display.set_mode((WIDTH,HEIGHT))
black = pygame.Color(0, 0, 0)
textcol = pygame.Color(255, 255, 0)
screen.fill(black)

while True:
    # Bild machen, als GIF speichern, gleiche Größe wie Fenster
    camera.start_preview()
    sleep(1)
    camera.capture('image.gif', format='gif', resize=(WIDTH,HEIGHT))
    camera.stop_preview()

    # altes Bild löschen
    screen.fill(black)
    pygame.display.update()    

    # Bild einlesen und anzeigen
    img = pygame.image.load('image.gif')
    screen.blit(img, (0, 0))

    # Datum und Uhrzeit darüber legen
    font = pygame.font.Font('freesansbold.ttf', FONTSIZE)
    text = time.strftime("%d.%m.%Y um %H:%M:%S Uhr")
    font_surf = font.render(text, True, textcol)
    font_rect = font_surf.get_rect()
    font_rect.left = 100
    font_rect.top = 100
    screen.blit(font_surf, font_rect)
    pygame.display.update()

    # etwas warten
    sleep(5)

# aus die Maus
camera.close()
pygame.quit()

Die Aufzeichnung von Videos erfolgt nach einem ähnlichen Schema. Hierzu bauen wir den Kommandozeilenaufruf für die Videoaufzeichnung nach. Die Methoden start_recording() und stop_recording() steuern die Aufzeichnung. Auch hier müssen Sie, sofern gewünscht, ein Vorschaufenster explizit anfordern und wieder schließen. Die Aufnahmedauer wird über wait_recording() eingestellt. Die Methode prüft auch kontinuierlich, ob der Speicherplatz auf der SD-Karte für die Aufzeichnung noch ausreicht, und bricht die Aufnahme notfalls ab. Das folgende Beispiel zewichnet 30 Sekunden auf:

import picamera
from time import sleep

with picamera.PiCamera() as cam:
   cam.start_preview()
   cam.start_recording('filmchen.h264')
   cam.wait_recording(30)
   cam.stop_recording()
   cam.stop_preview()
   cam.close()

Mit den bisher vorgestellten Programmen entstehen unter Umständen Unmengen total uninteressanter Bilder oder sinnlose Videos. Man könnte als Kriterium für Bewegungen vor der Kamera deutliche Änderungen in der beobachteten Szene heranziehen, also wenn zwei aufeinanderfolgende Bilder sich deutlich unterscheiden. Leichtes "flattern" von Blättern eines Baums oder die Nachbarkatze sollen aber unbeachtet bleiben.

Bei vielen Webcams kann man mit der Software Motion arbeiten, die auf dem Standard-Linux-Videostack Video4linux basiert. Scheinbar unterstützte die Picam das aber nicht. Jedoch gibt es ein Python-Programm ( http://www.raspberrypi.org/phpBB3/viewtopic.php?t=45235), das zwar sehr viel einfacher gehalten ist, aber in der Regel ausreicht. Das Programm nimmt Bilder auf und speichert sie mit einemZeitstempel im Dateinamen. Dann vergleicht es in einem niedrig auflösenden Stream immer zwei aufeinanderfolgende Bilder. Überschreiten die Veränderungen einen Schwellenwert, speichert der Pi das entsprechende hochauflösendes Bild.

Wie Sie sehen ist auch die Programmierung des Kamera-Interfaces mit Python nicht allzu schwierig. Viel Spass beim Experimentieren.

Die NoIR-Kamera

Für den RasPi gibt es ja zwei Kamera-Module, die normale Kamera und die NoIR-Kamera mit schwarzer Platine. "NoIR" steht für "No Infra Red (Filter)". Normalerweise haben Kameras einen eingebauten Infrarot-Filter, der die infraroten Anteile des Bildes unterdrückt und die deshalb Fotos liefern, die natürliche Farben wiedergeben. Die NoIR-Kamera ermöglicht Fotoeffekte, die auf dem Infrarot-Anteil des Lichts setzen. Der fehlende Infrarotfilter und ist vor allem für die Fotografie bei schlechten Lichtverhältnissen oder für Infrarotaufnahmen in der Dunkelheit geeignet. Man kann sie aber auch für atmosphärische Bilder bei Tageslicht einsetzen.

Für Infrarot-Effekte bei Tageslicht braucht man aber wieder einen entsprechenden Filter vor dem Objektiv, der einerseits möglichst viel Normallicht aussperrt und auf der anderen Seite einen möglichst hohen IR-Anteil durchlässt. Die NoIR-Kamera lässt einen genügend großen Anteil von Infrarotlicht zu ihrem Bildsensor passieren. Somit gelangt alles Infrarotlicht auf den Sensor, und die Belichtungszeiten werden nicht so hoch wie bei anderen Kameras mit IR-Filter. So kann man auch draussen fotografieren, wenn es nicht ganz windstill ist. Als Filter kommt u. a. der Polaroid Filter IR720 in Frage. Er filtert das meiste Licht unterhalb und oberhalb der Wellenlänge von 720 Nanometern (Nah-Infrarot), also das meiste sichtbare Licht. So lassen sich sogar Falschfarben-Aufnahmen machen. Gegebenenfalls muss der Weissabgleich nachträglich mit einer Bildverarbeitungssoftware gemacht werden.

Neue Raspberry-Pi-Kamera

Die Raspberry Pi Foundation hat im Mai 2016 eine neue Version der Kamera für den RasPi vorgestellt. Der Grund dafür liegt darin, dass die bislang in der Kamera eingebauten OmniVision-OV5647-Sensoren mit fünf Megapixeln seit Ende 2014 nicht mehr hergestellt werden. Im neuen Kameramodul V2.1 kommt der Sensor IMX219 von Sony zum Einsatz, der acht Megapixel Auflösung hat und zudem bessere Farben und eine höhere Bildqualität liefert.


(Bild: Raspberry Pi Foundation)

Die Kamera sitzt wie schon das erste Modell auf einer winzigen Platine und wird durch ein Flachbandkabel mit dem CSI-Port des Raspberry Pi verbunden. Das Modul soll mit denModellen 2 und 3 sowie den älteren Modellen A+ und B+ kompatibel sein. Neben der normalen Kamera ist auch wieder eine NoIR-Version erhältlich. Die neue Kamera beherrscht auch einen automatischen Weißabgleich. Er wird durchgeführt, während die rohen Sensordaten die Image Sensor Pipeline (ISP) durchlaufen dabei in Digitalbilder umgewandelt werden. Es sollen dabei auch Objektivverzerrungen, Rauschen oder fehlerhaften Pixel korrigiert werden. Einzelbilder sind mit einer Auflösung von maximal 3280 x 2464 Pixeln möglich. Videos mit 1080p kann die Kamera mit 30 Frames pro Sekunde (fps) aufnehmen, bei 720p liegt die maximale Bildrate bei 60 fps.
Quelle: www.raspberrypi.org/blog/new-8-megapixel-camera-board-sale-25

Infrarot-Scheinwerfer

Nachdem das zweite Kameramodell für Infrarotlicht geeignet ist, soll sie auch nachts etwas "sehen"? Dabei hilft ein kleiner Infrarot-Scheinwerfer. Der hier vorgestellte Eigenbau-Infrarot-Scheinwerfer besteht aus 40 preiswerten Infrarot-LEDs und acht Widerständen. Er lässt sich auch vom Lötanfänger ganz einfach auf einer Lochrasterplatte aufbauen. Profis machen sich natürlich eine Platine, insbesondere wenn mehr als ein Scheinwerfer gebraucht wird. Bei 12 V Versorgungsspannung nimmt der Scheinwerfer ca. 200 mA auf, er sollte also ggf. vom Computer aus ein- und ausgeschaltet werden können (per Relais oder MOSFET-Schalttransistor). Die Schaltung des Scheinwerfers ist so einfach, das im folgenden Bild nur die Verdrahtung gezeigt werden muss. Es werden jeweils 5 LEDs und ein 100-Ohm-Widerstand in Reihe geschaltet.

Für den Außeneinsatz muss dann noch ein passendes Gehäuse mit Klarsichtdeckel spendiert werden.

Allgemeine und weiterführende Informationen zum Betrieb von Webcams unter Linux finden Sie unter


Copyright © Hochschule München, FK 04, Prof. Jürgen Plate
Letzte Aktualisierung: