TigerJython xx
für Gymnasien

Raspberry PI Kamera


Der Pi2Go kann mit einer 5-Megapixel-Kamera erweitert werden. Mit dieser kleinen und preisgünstigen Kamera können Fotos mit einer maximalen Auflösung von 2592 x 1944 Pixeln, sowie Videoaufnahmen in den vier Modi 1080p30, 720p60, 640x480p90 und 640x480p60 erstellen werden.

Für die Befestigung der Kamera auf dem Pi2Go-Roboter eignet sich am besten der RPI Camera Kit, der unter Pi2Go-Zubehör zu finden ist. Dieser enthält zusätzlich zwei Servomotoren, mit welchen die vertikale und horizontale Position der Kamera geändert werden kann.


 
 


Pi2Go Camera Kit

Eine Anleitung zum Zusammenbauen findet man hier.

 


Pi2Go hat 4 Pin-Anschlüsse für Servomotoren. Sie befinden sich vorne rechts und sind mit s12, s13, s14 und s15 bezeichnet.
  Der horizontale Servomotor muss am s12 (der erste von Innen) angeschlossen sein, der braune Kabel rechts. Der vertikale Servomotor ist am s13 angeschlossen sein, braun rechts.  

Beispiel 1: Bilder aufnehmen und auf dem PC anzeigen (remote Modus)
Mit dem Befehl camera.captureAndTransfer(width, height) wird ein Bild gegebener Grösse im JPEG-Format aufgenommen und als String via WLAN auf den Computer transferiert. Auf dem Computer wird das JPEG-String in eine Bitmap umgewandelt und in einem Grafik-Fenster dargestellt.

# Cam1.py, remote Mode

from raspibrick import *
from gpanel import *

width = 800
height = 600

robot = Robot()
camera = Camera()
makeGPanel(Size(width, height))
window(0, width, 0, height)
while not isEscapeHit():
   jpeg = camera.captureAndTransfer(width, height)
   img = readImage(jpeg)
   image(img, 0, 0)
robot.exit()
Programmcode markieren (Ctrl+C kopieren)
 

 

 


Erklärungen zum Programmcode:

jpeg = camera.captureAndTransfer(width, height): nimmt ein Bild mit der geg. Pixelauflösung auf, transferiert es auf den remote Computer und gibt es als String im JPEG Format zurück
img = readImage(jpeg): wandelt ein Bild als JPEG String in eine in GPanel verwendbare Bitmap um
image(img, 0, 0): stellt das Bild im Grafikfenster an der Position 0, 0 dar


Beispiel 2: Kamera mit Servomotoren positionieren (remote und autonomer Modus)
Die Kamera wird mit dem horizontalen Servomotor fortlaufend zwischen -50° und 120° positioniert und nimmt in jeder Position ein Bild auf. Die Bilder werden auf dem Computer im Grafikfenster angezeigt.

# Cam2.py

from raspibrick import *
from gpanel import *

robot = Robot()
camera = Camera()
horzMotor = ServoMotor(2, 300, 1.6)

width = 640
height = 480
makeGPanel(Size(width, height))
window(0, width, 0, height)
for pos in range(-50, 120, 20):
    horzMotor.setPos(pos)
    jpeg = camera.captureAndTransfer(width, height)
    img = readImage(jpeg)
    image(img, 0, 0)
    Tools.delay(1500)
horzMotor.setPos(45)
Tools.delay(3000)
robot.exit()
Programmcode markieren (Ctrl+C kopieren)
   

Erklärungen zum Programmcode:

horzMotor.setPos(pos): positioniert Kamera mit dem horizontalen Servomotor (pos in Grad)


Beispiel 3: Roboter und Kamera werden remote gesteuert (remote Modus)
Ferngesteuert fährt der Roboter herum und nimmt mit einer ferngesteuerten Kamera Bilder auf. Die Bilder werden in einem Grafikfenster auf dem Computer dargestellt. Die Servermotoren der Kamera werden mit den Cursortasten gesteuert (LEFT: links, RIGHT: rechts, UP: nach oben , DOWN: nach unten). Mit der Taste q wird ein Bild aufgenommen und auf dem Computer angezeigt.

Für die Bewegung des Roboters werden folgende Tasten verwendet:
x: forward(), a: leftArc(), s: rightArt(), x: stop.

# Cam3.py

from raspibrick import *
from gpanel import *

def takeSnapshot():
    jpeg = camera.captureAndTransfer(width, height)
    img = readImage(jpeg)
    if img != None:
        image(img, 0, 0)

width = 640
height = 480

robot = Robot()
gear = Gear()
gear.setSpeed(30)
camera = Camera()
horzMotor = ServoMotor(2, 300, 1.6)
vertMotor = ServoMotor(3, 320, 2)
makeGPanel(Size(width, height))
window(0, width, 0, height)
takeSnapshot()
horzPos = 0
vertPos = 0
while robot.isConnected():
    doMove = False
    c = getKeyCode()
    if c == 65535:
        continue
    print c
    if c == 38 and vertPos < 50:     
        vertPos += 10
        doMove = True
    elif c == 40 and vertPos > - 50:
        vertPos -= 10
        doMove = True
    elif c == 37 and horzPos < 50:
        horzPos += 10
        doMove = True
    elif c == 39 and horzPos > - 50:
        horzPos -= 10
        doMove = True
    elif c == 65:  # a
        gear.leftArc(0.1)
    elif c == 87:  # w 
        gear.forward()
    elif c == 83:  # s 
        gear.rightArc(0.1)
    elif c == 88:  # x 
        gear.stop()
    elif c == 32:  # space    
       takeSnapshot()
    if doMove:
        horzMotor.setPos(horzPos)
        vertMotor.setPos(vertPos)
robot.exit()
Programmcode markieren (Ctrl+C kopieren)
   

Erklärungen zum Programmcode:

 c = getKeyCode(): liefert den Code der gedrückten Taste
if c == 32: takeSnapshot(): Falls die Leertaste gedrückt wurde, wird ein Bild aufgenommen, zum Computer transferiert und auf dem Computerbildschirm angezeigt.

 

Beispiel 4: Videoüberwachung
Mit der Camera werden in regelmässigen Abständen Bilder aufgenommen und jeweils zwei nacheinander folgende wie folgt verglichen: Man geht die beiden Bilder Pixel für Pixel durch und vergleicht in jedem Pixel die roten, grünen und blauen Farbanteile. Danach werden Pixel gezählt, bei welchen der rote, grüne oder blaue Anteil wesentlich unterschiedlichen Wert aufweisst. Falls mehr als 10% der Pixel eine Differenz aufweisst, hat siche das Bild geändert und ein Alarm wird ausgelöst.

# Cam4.py, remote mode

from raspibrick import *
from gpanel import *

def takeSnapshot():
    jpeg = camera.captureAndTransfer(width, height)
    img = readImage(jpeg)
    if img != None:
        image(img, -1, -1)
    return img

width = 120
height = 90

robot = Robot()
camera = Camera()
pair = [None, None]

makeGPanel(Size(width-2, height-2))
window(0, width, 0, height)
i = 0
while robot.isConnected():
    pair[i] = takeSnapshot()
    if i == 0:
        i = 1
    elif i == 1:
        i = 0
    if pair[0] == None or pair[1] == None:
        continue
    count = 0
    for x in range(width):
        for y in range(height):
            c0 = pair[0].getPixelColor(x,y)
            c1 = pair[1].getPixelColor(x,y)
            r = abs(c0.getRed() - c1.getRed())      
            g = abs(c0.getGreen() - c1.getGreen())      
            b = abs(c0.getBlue() - c1.getBlue())      
            if r > 10 or g > 10 or b > 10:
                count += 1
    print "count", count
    if count > (width * height) // 10:
        playTone(3000, 100)
robot.exit()
Programmcode markieren (Ctrl+C kopieren)
   

Erklärungen zum Programmcode:

pair[i] = takeSnapshot(): zwei nacheinander aufgenommene Bilder
c0 = pair[0].getPixelColor(x,y)
c1 = pair[1].getPixelColor(x,y)
r = abs(c0.getRed() - c1.getRed())
if count > (width * height) // 10

Bemerkung: Ein mit makeGPanel (Size(800, 600)) erzeugtes Grafikfenster ist 801 Pixel breit und 601 Pixel hoch, da beim Zeichnen im GPanel auch der erste und der letzte Pixel dargestellt wird. Eine Bitmap-Grafik 800x600 hat dagegen genau diese Pixelgrösse. Dadurch wird bei den dargestellten Bildern am Rand ein weisses 1 Pixel breites streifen sichtbar. Um das zu vermeiden, kann man mit makeGPanel(Size(width - 2, height - 2)) ein kleineres Grafikfenster erzeugen und das Bild mit image(img, -1, -1) so positionieren, dass kein leeres Pixel entsteht.


Beispiel 5: Kameraaufnahmen auf dem Raspi speichern (autonomer Modus)
Die Kamera wird gleich wie im Beispiel 2 mit dem horizontalen Servomotor an verschiedene Positionen versetzt. An jeder Position wird ein Bild aufgenommen und auf dem Raspi gespeichert. Die gespeicherten Bilder können später mit einem FTP-Tool, z.B. mit WinSCP auf den Computer heruntergeladen werden.

# Cam5.py, autonomous mode

from raspibrick import *
from gpanel import *

robot = Robot()
camera = Camera()

n = 1
for pos in range(-50, 55, 10):
    camera.setHorzPos(pos)
    filename = "home/pi/shot" + str(n) + ".jpg"
    jpeg = camera.captureAndSave(320, 240, filename)
    Tools.delay(2000)
    n += 1
camera.setHorzPos(0)
Tools.delay(3000)
robot.exit()
Programmcode markieren (Ctrl+C kopieren)
   

Erklärungen zum Programmcode:

 jpeg = camera.captureAndSave(320, 240, filename): Erstellt ein Bild und speichert es auf dem Raspi unter angegebenen Dateinamen