Pi Camera

Voor het ogenblik wordt nog volop gewerkt aan een nieuwe python bibliotheek voor de Pi Camera. Meer info kan je vinden op: https://www.raspberrypi.com/documentation/accessories/camera.html.

Eén van de leukste accessoires van de Raspberry Pi is het kleine Pi Cameraboard, een kleine printplaat met camerasensor die via een lintkabel verbinding maakt met de Raspberry Pi.

De Pi Camera kan op verschillende manieren gebruikt worden, bijvoorbeeld als time-lapse fotocamera of als webcam. Hij kan echter ook als optische sensor dienen voor een robot die door de Pi wordt aangestuurd. Omdat de camera geen usb-aansluiting heeft en erg weinig energie verbruikt, is hij veelzijdiger in te zetten dan een standaard webcam.

De Pi Camera zelf is overigens geen simpel dingetje - de Pi Camera Module 2 met een 8-megapixel-sensor kan 1080p-videoopnames maken, de Pi Camera Module 3 (12 MP) kan zelfs 4K foto's nemen. De Pi Camera is ook beschikbaar zonder Infrarood filter, waardoor deze ook gevoelig is voor infrarood licht. Handig voor warmtemetingen, nachtopnames, gezichtsherkenning, bewaking, enz.

Camera aansluiten

Camera aansluiten

De Pi Camera module is gevoelig voor statische elektriciteit, deze kan de elektronica beschadigen en de camera onbruikbaar maken. Zorg dus voor aarding als je de Pi Camera aansluit.

Om de camera op de Raspberry Pi aan te sluiten, moet je het slot tussen de audio-uitgang en de HDMI-poort opsporen en de sluiting openen. Steek de lintkabel van het cameraboard hierin met de blauwe strook aan de kant van de audio-uitgang. Zorg ervoor dat de aansluitingen van het lint goed in die van de Pi zitten.

Raspberry Pi OS bijwerken

Voordat we de Raspberry Pi Camera gebruiken, moeten we zeker weten dat de firm- en software helemaal up-to-date zijn. Dat doen we met een snelle software-upgrade. Open hiervoor een terminal en typ het volgende:

pi@raspberrypi:~ $ sudo apt update && sudo apt upgrade -y
Geraakt:1 http://deb.debian.org/debian bookworm InRelease
Ophalen:2 http://deb.debian.org/debian-security bookworm-security InRelease [48,0 kB]
Ophalen:3 http://deb.debian.org/debian bookworm-updates InRelease [52,1 kB]       
Geraakt:4 http://archive.raspberrypi.com/debian bookworm InRelease                
Pakketlijsten worden ingelezen... Klaar                                           
Boom van vereisten wordt opgebouwd... Klaar
De statusinformatie wordt gelezen... Klaar 
Alle pakketten zijn up-to-date.
Pakketlijsten worden ingelezen... Klaar
Boom van vereisten wordt opgebouwd... Klaar
De statusinformatie wordt gelezen... Klaar 
Opwaardering wordt doorgerekend... Klaar
0 opgewaardeerd, 0 nieuw geïnstalleerd, 0 te verwijderen en 0 niet opgewaardeerd.

Nu kunnen we de camera opdrachten installeren:

pi@raspberrypi:~ $ sudo apt install rpicam-apps
Pakketlijsten worden ingelezen... Klaar
Boom van vereisten wordt opgebouwd... Klaar
De statusinformatie wordt gelezen... Klaar 
De volgende extra pakketten zullen geïnstalleerd worden:
  libboost-program-options1.74.0 libcamera-ipa libcamera-tools libcamera0.1 libpisp-common libpisp1 python3-libcamera
De volgende pakketten zullen VERWIJDERD worden:
  libpisp1.0.0
De volgende NIEUWE pakketten zullen geïnstalleerd worden:
  libboost-program-options1.74.0 libpisp1 rpicam-apps
De volgende pakketten zullen opgewaardeerd worden:
  libcamera-ipa libcamera-tools libcamera0.1 libpisp-common python3-libcamera
5 opgewaardeerd, 3 nieuw geïnstalleerd, 1 te verwijderen en 0 niet opgewaardeerd.
Er moeten 2.203 kB aan archieven opgehaald worden.
Na deze bewerking zal er 4.475 kB extra schijfruimte gebruikt worden.
Wilt u doorgaan? [J/n] 
Ophalen:1 http://deb.debian.org/debian bookworm/main arm64 libboost-program-options1.74.0 arm64 1.74.0+ds1-21 [317 kB]
Ophalen:2 http://archive.raspberrypi.com/debian bookworm/main arm64 libcamera-ipa arm64 0.1.0+rpt20231122-1 [388 kB]
Ophalen:3 http://archive.raspberrypi.com/debian bookworm/main arm64 libcamera0.1 arm64 0.1.0+rpt20231122-1 [506 kB]
Ophalen:4 http://archive.raspberrypi.com/debian bookworm/main arm64 libpisp-common all 1.0.2-1 [4.292 B]
Ophalen:5 http://archive.raspberrypi.com/debian bookworm/main arm64 libpisp1 arm64 1.0.2-1 [179 kB]
Ophalen:6 http://archive.raspberrypi.com/debian bookworm/main arm64 libcamera-tools arm64 0.1.0+rpt20231122-1 [277 kB]
Ophalen:7 http://archive.raspberrypi.com/debian bookworm/main arm64 python3-libcamera arm64 0.1.0+rpt20231122-1 [215 kB]
Ophalen:8 http://archive.raspberrypi.com/debian bookworm/main arm64 rpicam-apps arm64 1.4.1-1 [317 kB]
2.203 kB opgehaald in 1s (1.543 kB/s)
De changelogs worden ingelezen... Klaar
(Database wordt ingelezen ... 145104 bestanden en mappen momenteel geïnstalleerd.)
Uitpakken van .../libcamera-ipa_0.1.0+rpt20231122-1_arm64.deb wordt voorbereid...
Bezig met uitpakken van libcamera-ipa:arm64 (0.1.0+rpt20231122-1) over (0.1.0+rpt20231020-1) ...
Uitpakken van .../libcamera0.1_0.1.0+rpt20231122-1_arm64.deb wordt voorbereid...
Bezig met uitpakken van libcamera0.1:arm64 (0.1.0+rpt20231122-1) over (0.1.0+rpt20231020-1) ...
(Database wordt ingelezen ... 145104 bestanden en mappen momenteel geïnstalleerd.)
libpisp1.0.0:arm64 (1.0.0-1) wordt verwijderd ...
(Database wordt ingelezen ... 145100 bestanden en mappen momenteel geïnstalleerd.)
Uitpakken van .../0-libpisp-common_1.0.2-1_all.deb wordt voorbereid...
Bezig met uitpakken van libpisp-common (1.0.2-1) over (1.0.0-1) ...
Voorheen niet geselecteerd pakket libpisp1:arm64 wordt geselecteerd.
Uitpakken van .../1-libpisp1_1.0.2-1_arm64.deb wordt voorbereid...
Bezig met uitpakken van libpisp1:arm64 (1.0.2-1) ...
Voorheen niet geselecteerd pakket libboost-program-options1.74.0:arm64 wordt geselecteerd.
Uitpakken van .../2-libboost-program-options1.74.0_1.74.0+ds1-21_arm64.deb wordt voorbereid...
Bezig met uitpakken van libboost-program-options1.74.0:arm64 (1.74.0+ds1-21) ...
Uitpakken van .../3-libcamera-tools_0.1.0+rpt20231122-1_arm64.deb wordt voorbereid...
Bezig met uitpakken van libcamera-tools (0.1.0+rpt20231122-1) over (0.1.0+rpt20231020-1) ...
Uitpakken van .../4-python3-libcamera_0.1.0+rpt20231122-1_arm64.deb wordt voorbereid...
Bezig met uitpakken van python3-libcamera (0.1.0+rpt20231122-1) over (0.1.0+rpt20231020-1) ...
Voorheen niet geselecteerd pakket rpicam-apps wordt geselecteerd.
Uitpakken van .../5-rpicam-apps_1.4.1-1_arm64.deb wordt voorbereid...
Bezig met uitpakken van rpicam-apps (1.4.1-1) ...
Instellen van libboost-program-options1.74.0:arm64 (1.74.0+ds1-21) ...
Instellen van libpisp-common (1.0.2-1) ...
Instellen van libpisp1:arm64 (1.0.2-1) ...
Instellen van libcamera-ipa:arm64 (0.1.0+rpt20231122-1) ...
Instellen van libcamera0.1:arm64 (0.1.0+rpt20231122-1) ...
Instellen van rpicam-apps (1.4.1-1) ...
Instellen van python3-libcamera (0.1.0+rpt20231122-1) ...
Instellen van libcamera-tools (0.1.0+rpt20231122-1) ...
Bezig met afhandelen van triggers voor libc-bin (2.36-9+rpt2+deb12u3) ...

Foto's nemen

Om foto's met de Raspberry Pi te nemen, hoef je alleen maar het volgende in te voeren:

pi@raspberrypi:~ $ rpicam-still -o Foto.jpg
Made X/EGL preview window
[0:07:29.885573256] [2557]  INFO Camera camera_manager.cpp:284 libcamera v0.1.0+99-4a23664b
[0:07:29.953846593] [2562]  WARN RPiSdn sdn.cpp:39 Using legacy SDN tuning - please consider moving SDN inside rpi.denoise
[0:07:29.956968405] [2562]  INFO RPI vc4.cpp:444 Registered camera /base/soc/i2c0mux/i2c@1/ov5647@36 to Unicam device /dev/media3 and ISP device /dev/media0
[0:07:29.957052274] [2562]  INFO RPI pipeline_base.cpp:1142 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
Mode selection for 1296:972:12:P
    SGBRG10_CSI2P,640x480/0 - Score: 3296
    SGBRG10_CSI2P,1296x972/0 - Score: 1000
    SGBRG10_CSI2P,1920x1080/0 - Score: 1349.67
    SGBRG10_CSI2P,2592x1944/0 - Score: 1567
Stream configuration adjusted
[0:07:29.958590004] [2557]  INFO Camera camera.cpp:1181 configuring streams: (0) 1296x972-YUV420 (1) 1296x972-SGBRG10_CSI2P
[0:07:29.959096390] [2562]  INFO RPI vc4.cpp:608 Sensor: /base/soc/i2c0mux/i2c@1/ov5647@36 - Selected sensor format: 1296x972-SGBRG10_1X10 - Selected unicam format: 1296x972-pGAA
Mode selection for 2592:1944:12:P
    SGBRG10_CSI2P,640x480/0 - Score: 7832
    SGBRG10_CSI2P,1296x972/0 - Score: 5536
    SGBRG10_CSI2P,1920x1080/0 - Score: 4238.67
    SGBRG10_CSI2P,2592x1944/0 - Score: 1000
Stream configuration adjusted
[0:07:35.128471199] [2557]  INFO Camera camera.cpp:1181 configuring streams: (0) 2592x1944-YUV420 (1) 2592x1944-SGBRG10_CSI2P
[0:07:35.130976959] [2562]  INFO RPI vc4.cpp:608 Sensor: /base/soc/i2c0mux/i2c@1/ov5647@36 - Selected sensor format: 2592x1944-SGBRG10_1X10 - Selected unicam format: 2592x1944-pGAA
Still capture image received

Je ziet dan gedurende vijf seconden een preview van het beeld van de camera, daarna wordt het laatste frame van het filmpje vastgelegd. Om de handleiding van een opdracht weer te geven, gebruik je de optie --help:

pi@raspberrypi:~ $ rpicam-still --help
Valid options are:
  -h [ --help ] [=arg(=1)] (=0)         Print this help message
  --version [=arg(=1)] (=0)             Displays the build version number
  --list-cameras [=arg(=1)] (=0)        Lists the available cameras attached to the system.
  --camera arg (=0)                     Chooses the camera to use. To list the available indexes, use the 
                                        --list-cameras option.
  -v [ --verbose ] [=arg(=2)] (=1)      Set verbosity level. Level 0 is no output, 1 is default, 2 is verbose.
  -c [ --config ] [=arg(=config.txt)]   Read the options from a file. If no filename is specified, default to 
                                        config.txt. In case of duplicate options, the ones provided on the command line
                                        will be used. Note that the config file must only contain the long form 
                                        options.
  --info-text arg (=#%frame (%fps fps) exp %exp ag %ag dg %dg)
                                        Sets the information string on the titlebar. Available values:
                                        %frame (frame number)
                                        %fps (framerate)
                                        %exp (shutter speed)
                                        %ag (analogue gain)
                                        %dg (digital gain)
                                        %rg (red colour gain)
                                        %bg (blue colour gain)
                                        %focus (focus FoM value)
                                        %aelock (AE locked status)
                                        %lp (lens position, if known)
                                        %afstate (AF state, if supported)
  --width arg (=0)                      Set the output image width (0 = use default value)
  --height arg (=0)                     Set the output image height (0 = use default value)
  -t [ --timeout ] arg (=5sec)          Time for which program runs. If no units are provided default to ms.
  -o [ --output ] arg                   Set the output file name
  --post-process-file arg               Set the file name for configuring the post-processing
  -n [ --nopreview ] [=arg(=1)] (=0)    Do not show a preview window
  -p [ --preview ] arg (=0,0,0,0)       Set the preview window dimensions, given as x,y,width,height e.g. 0,0,640,480
  -f [ --fullscreen ] [=arg(=1)] (=0)   Use a fullscreen preview window
  --qt-preview [=arg(=1)] (=0)          Use Qt-based preview window (WARNING: causes heavy CPU load, fullscreen not 
                                        supported)
  --hflip [=arg(=1)] (=0)               Request a horizontal flip transform
  --vflip [=arg(=1)] (=0)               Request a vertical flip transform
  --rotation arg (=0)                   Request an image rotation, 0 or 180
  --roi arg (=0,0,0,0)                  Set region of interest (digital zoom) e.g. 0.25,0.25,0.5,0.5
  --shutter arg (=0)                    Set a fixed shutter speed. If no units are provided default to us
  --analoggain arg (=0)                 Set a fixed gain value (synonym for 'gain' option)
  --gain arg                            Set a fixed gain value
  --metering arg (=centre)              Set the metering mode (centre, spot, average, custom)
  --exposure arg (=normal)              Set the exposure mode (normal, sport)
  --ev arg (=0)                         Set the EV exposure compensation, where 0 = no change
  --awb arg (=auto)                     Set the AWB mode (auto, incandescent, tungsten, fluorescent, indoor, daylight, 
                                        cloudy, custom)
  --awbgains arg (=0,0)                 Set explict red and blue gains (disable the automatic AWB algorithm)
  --flush [=arg(=1)] (=0)               Flush output data as soon as possible
  --wrap arg (=0)                       When writing multiple output files, reset the counter when it reaches this 
                                        number
  --brightness arg (=0)                 Adjust the brightness of the output images, in the range -1.0 to 1.0
  --contrast arg (=1)                   Adjust the contrast of the output image, where 1.0 = normal contrast
  --saturation arg (=1)                 Adjust the colour saturation of the output, where 1.0 = normal and 0.0 = 
                                        greyscale
  --sharpness arg (=1)                  Adjust the sharpness of the output image, where 1.0 = normal sharpening
  --framerate arg (=-1)                 Set the fixed framerate for preview and video modes
  --denoise arg (=auto)                 Sets the Denoise operating mode: auto, off, cdn_off, cdn_fast, cdn_hq
  --viewfinder-width arg (=0)           Width of viewfinder frames from the camera (distinct from the preview window 
                                        size
  --viewfinder-height arg (=0)          Height of viewfinder frames from the camera (distinct from the preview window 
                                        size)
  --tuning-file arg (=-)                Name of camera tuning file to use, omit this option for libcamera default 
                                        behaviour
  --lores-width arg (=0)                Width of low resolution frames (use 0 to omit low resolution stream
  --lores-height arg (=0)               Height of low resolution frames (use 0 to omit low resolution stream
  --mode arg                            Camera mode as W:H:bit-depth:packing, where packing is P (packed) or U 
                                        (unpacked)
  --viewfinder-mode arg                 Camera mode for preview as W:H:bit-depth:packing, where packing is P (packed) 
                                        or U (unpacked)
  --buffer-count arg (=0)               Number of in-flight requests (and buffers) configured for video, raw, and 
                                        still.
  --viewfinder-buffer-count arg (=0)    Number of in-flight requests (and buffers) configured for preview window.
  --no-raw [=arg(=1)] (=0)              Disable requesting of a RAW stream. Will override any manual mode reqest the 
                                        mode choice when setting framerate.
  --autofocus-mode arg (=default)       Control to set the mode of the AF (autofocus) algorithm.(manual, auto, 
                                        continuous)
  --autofocus-range arg (=normal)       Set the range of focus distances that is scanned.(normal, macro, full)
  --autofocus-speed arg (=normal)       Control that determines whether the AF algorithm is to move the lens as quickly
                                        as possible or more steadily.(normal, fast)
  --autofocus-window arg (=0,0,0,0)     Sets AfMetering to  AfMeteringWindows an set region used, e.g. 
                                        0.25,0.25,0.5,0.5
  --lens-position arg                   Set the lens to a particular focus position, expressed as a reciprocal distance
                                        (0 moves the lens to infinity), or "default" for the hyperfocal distance
  --hdr [=arg(=auto)] (=off)            Enable High Dynamic Range, where supported. Available values are "off", "auto",
                                        "sensor" for sensor HDR (e.g. for Camera Module 3), "single-exp" for PiSP based
                                        single exposure multiframe HDR
  --metadata arg                        Save captured image metadata to a file or "-" for stdout
  --metadata-format arg (=json)         Format to save the metadata in, either txt or json (requires --metadata)
  --flicker-period arg (=0s)            Manual flicker correction period
                                        Set to 10000us to cancel 50Hz flicker.
                                        Set to 8333us to cancel 60Hz flicker.
                                        
  -q [ --quality ] arg (=93)            Set the JPEG quality parameter
  -x [ --exif ] arg                     Add these extra EXIF tags to the output file
  --timelapse arg (=0ms)                Time interval between timelapse captures. If no units are provided default to 
                                        ms.
  --framestart arg (=0)                 Initial frame counter value for timelapse captures
  --datetime [=arg(=1)] (=0)            Use date format for output file names
  --timestamp [=arg(=1)] (=0)           Use system timestamps for output file names
  --restart arg (=0)                    Set JPEG restart interval
  -k [ --keypress ] [=arg(=1)] (=0)     Perform capture when ENTER pressed
  -s [ --signal ] [=arg(=1)] (=0)       Perform capture when signal received
  --thumb arg (=320:240:70)             Set thumbnail parameters as width:height:quality, or none
  -e [ --encoding ] arg (=jpg)          Set the desired output encoding, either jpg, png, rgb, bmp or yuv420
  -r [ --raw ] [=arg(=1)] (=0)          Also save raw file in DNG format
  --latest arg                          Create a symbolic link with this name to most recent saved file
  --immediate [=arg(=1)] (=0)           Perform first capture immediately, with no preview phase
  --autofocus-on-capture [=arg(=1)] (=0)
                                        Switch to AfModeAuto and trigger a scan just before capturing a still
  --zsl [=arg(=1)] (=0)                 Switch to AfModeAuto and trigger a scan just before capturing a still

Zo kom je bijvoorbeeld te weten dat je met de optie -v 0 minder meldingen krijgt, die eigenlijk bestemd zijn voor de ontwikkelaar of bij problemen:

pi@raspberrypi:~ $ rpicam-still -o Foto.jpg -v 0

Video opnemen

Om een filmpje op te nemen, gebruiken we een gelijkaardige opdracht, rpicam-vid, op de volgende manier:

pi@raspberrypi:~ $ rpicam-vid -o Video.h264 -v 0

Standaard wordt daarmee ook vijf seconden aan video opgenomen. De video speel je af met:

pi@raspberrypi:~ $ ffplay -autoexit Video.h264
ffplay version 5.1.4-0+rpt1+deb12u1 Copyright (c) 2003-2023 the FFmpeg developers
  built with gcc 12 (Debian 12.2.0-14)
  configuration: --prefix=/usr --extra-version=0+rpt1+deb12u1 --toolchain=hardened --incdir=/usr/include/aarch64-linux-gnu --enable-gpl --disable-stripping --disable-mmal --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sand --enable-sdl2 --disable-sndio --enable-libjxl --enable-neon --enable-v4l2-request --enable-libudev --enable-epoxy --libdir=/usr/lib/aarch64-linux-gnu --arch=arm64 --enable-pocketsphinx --enable-librsvg --enable-libdc1394 --enable-libdrm --enable-vout-drm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-libplacebo --enable-librav1e --enable-shared
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
Input #0, h264, from 'Video.h264': 0KB vq=    0KB sq=    0B f=0/0   
  Duration: N/A, bitrate: N/A
  Stream #0:0: Video: h264 (High), yuv420p(progressive), 640x480, 30 fps, 30 tbr, 1200k tbn
    nan M-V:    nan fd=   1 aq=    0KB vq=    0KB sq=    0B f=0/0

Bestandsbeheerder De foto's en video's worden standaard in de thuismap van de Pi gebruiker opgeslagen. Start in de grafische omgeving van de Pi de Bestandsbeheerder en dubbelklik op de foto om deze weer te geven. De standaard mediaspeler (VLC), speelt de video Video.h264 zonder problemen af. Voor sommige mediaspelers, moet je deze eerst converteren naar een MP4 bestand (mp4 bepaalt hoe de video in het bestand is opgenomen, h264 is de manier waarop is gecodeerd).

Video streamen

Je kunt de videobeelden ook streamen over een netwerk naar een programma op een ander apparaat. Start daarvoor de volgende opdracht:

pi@raspberrypi:~ $ rpicam-vid -t 0 --codec mjpeg --inline --listen -o tcp://0.0.0.0:8080 -v 0

Start VLC Media Player op en start in het menu Media de opdracht Netwerkstream openen... Geef als netwerk-url tcp/mjpeg://raspberrypi.local:8080 op en klik op de knop Afspelen. Vervang daarbij raspberrypy.local door de hostname of het IP adres van jouw eigen Raspberry Pi.

Stop je het afspelen, dan wordt automatisch het streamen gestopt.

Je kunt dit ook testen in een tweede terminal met de opdracht:

pi@raspberrypi:~ $ ffplay tcp://raspberrypi.local:8080 -vf "setpts=N/30" -fflags nobuffer -flags low_delay -framedrop -hide_banner -loglevel error

Programmeren

Als je wat meer met de Pi Camera wilt doen, kan je gebruik maken van Bash scripts.

Voorvertoning

Zorg dat je grafisch op de Raspberry Pi kunt werken (VNC, RDP of fysiek aangesloten op toetsenbord, muis en scherm). Start via het Menu in de groep Programmeren de applicatie Geany.

Geany start steeds met de programmabestanden waaraan je werkte. Bij de eerste start, krijg je automatisch een nieuw bestand. Elk nieuw programma dat je schrijft, sla je eerst op via het menu Bestand en de opdracht Opslaan als.... Geef jouw programma de naam camera.sh.

Om een voorvertoning 10 seconden op het scherm te bekijken, typ de volgende programmacode:

#!/bin/bash

timeout=10
preview="0,50,640,360"
rpicam-hello -t $((timeout*1000)) -p $preview

De eerste regel is steeds een Shebang en deze bevat het programma die het script moet uitvoeren, in ons geval /bin/bash.

De variabele timeout zorgt dat de voorvertoning 10 seconden actief blijft. De variable preview bepaalt waar het venster met de voorvertoning op het scherm zal verschijnen, tegen de linkerkant (0), 50 beeldpunten van boven, 640 beeldpunten breed en 360 beeldpunten hoog. Variabelen zorgen ervoor dat de programmacode duidelijker is en eenvoudig kan aangepast worden. Zo heeft de opdracht rpicam-hello de activiteitsduur in milliseconden nodig, we berekenen deze met $((timeout*1000)) waarbij alles wat tussen dubbele haken staat wordt berekend (* staat voor vermenigvuldigen). Het $-teken zorgt dat de variabelen timeout en preview gebruikt worden en deze woorden niet als opdracht worden uitgevoerd.

Sla de programmacode op met de sneltoets Ctrl+s

Om een script in Raspberry Pi OS (Linux) te kunnen starten, moet je het één keer uitvoerrechten geven. Je geeft het script uitvoerrechten door in de terminal de volgende opdracht uit te voeren:

pi@raspberrypi:~ $ chmod +x camera.sh

En start in Geany het programma met F5.

Ondertussen heb je waarschijnlijk gemerkt dat het venster niet correct gepositioneerd is, dit is te wijten aan de nieuwe grafische omgeving van de Raspberry Pi. De grafische omgeving bepaald nu waar vensters terecht komen, niet de programma's of scripts.

Praktijk opdracht

Opgelet, de programmacode in de opgaven is niet volledig. Enkel de relevante code wordt getoond. M.a.w. indien jouw script niet werkt, controleer het dan grondig en pas het aan tot het werkt.

  1. Als het beeld ondersteboven staat, kan je het beeld draaien door een variabele toe te voegen en de opdracht aan te passen:

    rotation=180
    rpicam-hello -p $preview --rotation $rotation

    Test dit. Je kunt het beeld 180 graden roteren, of terug standaard zetten met 0.
  2. Afhankelijk van de snelheid waarmee de lichtsensoren van Pi Camera klaar zijn om een foto te nemen, kan je de wachttijd sterk inkorten:

    output="Desktop/Foto.jpg"
    rpicam-still --nopreview -o $output

    De output variabele, samen met de -o optie bij de rpicam-still opdracht zorgen dat de foto wordt opgeslagen op het bureaublad (Desktop map). De --nopreview toont geen voorvertoning waardoor de foto wordt aangemaakt vanaf het moment dat de sensor klaar is. De foto kan je openen door er dubbel op te klikken.
  3. Om een foto met een bepaalde resolutie te nemen, gebruiken we de opties --width en --height en bijpassende variabelen. Voor een foto met een resolutie van 1280x720 pas je het script aan:

    width=1280
    height=720
    rpicam-still -p $preview -o $output --width $width --height $height

  4. Zonder de opties --width en --height maakt rpicam-still foto's met de maximale resolutie van de Pi Camera. Pas het script aan:

    output="Desktop/Max.jpg"
    rpicam-still -p $preview -o $output

    Open de pas aangemaakte foto en noteer de resolutie van jouw camera: .........x......... (zie titelbalk).
  5. Pas het script nu zelf aan om een miniatuur afbeelding te maken met een resolutie van 64x64 en sla deze op het bureaublad op met de naam Min.jpg
  6. Wil je de foto in een niet verlieslatend formaat opslaan om deze later zonder kwaliteitsverlies te bewerken, sla je de foto op in het PNG formaat. Pas daarvoor het script als volgt aan:

    output="Desktop/Foto.png"
    encoding="png"
    rpicam-still -p $preview -o $output -e $encoding

  7. Met een lus kan je vijf foto's na elkaar nemen:

    for in {1..5}
    do
      output=$(printf "Desktop/Foto%0*d.jpg" 2 $i)
      rpicam-still -p $preview -o $output
    done

    De variabele i bevat het huidige lusnummer, van 1 tot en met 5, de foto's worden dus opgeslagen als Foto01.jpg, Foto02.jpg en zo verder. De output variabele wordt telkens aangemaakt op basis van het huidige lusnummer $i en moet steeds uit 2 cijfers bestaan. Daar zorgt %0*d voor. Probeer dit uit.
  8. Nu je foto's kunt nemen, is het tijd om te kijken hoe je video's maakt. Terug willen we de resolutie beperken tot 1280x720, een compromis tussen kwaliteit en opslagruimte (eveneens de Youtube standaard resolutie):

    width=1280
    height=720
    timeout=10
    output="Desktop/Video.h264"
    rpicam-vid -t $((timeout*1000)) -o $output --width $width --height $height

    Test het programmma waarbij 10 seconden video wordt opgenomen. Test of je de opgenomen video kunt afspelen.
  9. Om tekst aan een foto toe te voegen, gaan we de hulp inroepen van de beeldbewerker ImageMagick. Installeer ImageMagick met de opdracht:
    pi@raspberrypi:~ $ sudo apt install imagemagick
    Pakketlijsten worden ingelezen... Klaar
    Boom van vereisten wordt opgebouwd... Klaar
    De statusinformatie wordt gelezen... Klaar 
    De volgende extra pakketten zullen geïnstalleerd worden:
      imagemagick-6.q16 libnetpbm11 netpbm
    Voorgestelde pakketten:
      imagemagick-doc autotrace cups-bsd | lpr | lprng enscript gimp gnuplot grads graphviz hp2xx html2ps libwmf-bin mplayer povray
      radiance texlive-base-bin transfig ufraw-batch
    De volgende NIEUWE pakketten zullen geïnstalleerd worden:
      imagemagick imagemagick-6.q16 libnetpbm11 netpbm
    0 opgewaardeerd, 4 nieuw geïnstalleerd, 0 te verwijderen en 0 niet opgewaardeerd.
    Er moeten 2.614 kB aan archieven opgehaald worden.
    Na deze bewerking zal er 26,7 MB extra schijfruimte gebruikt worden.
    Wilt u doorgaan? [J/n] 
    Ophalen:1 http://deb.debian.org/debian bookworm/main arm64 imagemagick-6.q16 arm64 8:6.9.11.60+dfsg-1.6 [339 kB]
    Ophalen:2 http://deb.debian.org/debian bookworm/main arm64 imagemagick arm64 8:6.9.11.60+dfsg-1.6 [122 kB]
    Ophalen:3 http://deb.debian.org/debian bookworm/main arm64 libnetpbm11 arm64 2:11.01.00-2 [167 kB]
    Ophalen:4 http://deb.debian.org/debian bookworm/main arm64 netpbm arm64 2:11.01.00-2 [1.986 kB]
    2.614 kB opgehaald in 0s (9.180 kB/s)
    Voorheen niet geselecteerd pakket imagemagick-6.q16 wordt geselecteerd.
    (Database wordt ingelezen ... 145164 bestanden en mappen momenteel geïnstalleerd.)
    Uitpakken van .../imagemagick-6.q16_8%3a6.9.11.60+dfsg-1.6_arm64.deb wordt voorbereid...
    Bezig met uitpakken van imagemagick-6.q16 (8:6.9.11.60+dfsg-1.6) ...
    ...
    Instellen van libnetpbm11:arm64 (2:11.01.00-2) ...
    Instellen van netpbm (2:11.01.00-2) ...
    Instellen van imagemagick-6.q16 (8:6.9.11.60+dfsg-1.6) ...
    update-alternatives: /usr/bin/compare-im6.q16 wordt gebruikt om in de automatische modus in /usr/bin/compare (compare) te voorzien
    update-alternatives: /usr/bin/compare-im6.q16 wordt gebruikt om in de automatische modus in /usr/bin/compare-im6 (compare-im6) te voorzien
    ...
    update-alternatives: /usr/bin/mogrify-im6.q16 wordt gebruikt om in de automatische modus in /usr/bin/mogrify (mogrify) te voorzien
    update-alternatives: /usr/bin/mogrify-im6.q16 wordt gebruikt om in de automatische modus in /usr/bin/mogrify-im6 (mogrify-im6) te voorzien
    Instellen van imagemagick (8:6.9.11.60+dfsg-1.6) ...
    Bezig met afhandelen van triggers voor desktop-file-utils (0.26-1) ...
    Bezig met afhandelen van triggers voor hicolor-icon-theme (0.17-2) ...
    Bezig met afhandelen van triggers voor gnome-menus (3.36.0-1.1) ...
    Bezig met afhandelen van triggers voor libc-bin (2.36-9+rpt2+deb12u3) ...
    Bezig met afhandelen van triggers voor man-db (2.11.2-2) ...
    Bezig met afhandelen van triggers voor mailcap (3.70+nmu1) ...
  10. We kunnen een foto nu voorzien van een tekst door deze na te bewerken met convert, een opdracht van het pakket ImageMagick. Probeer het volgende:

    output="Desktop/Tekst.jpg"
    rpicam-still -p $preview -o $output
    convert $output -gravity North -pointsize 90 -undercolor "rgba(0,0,0,0.5)" -fill yellow -annotate +0+' Pi Camera ' $output

    De tekst wordt in het midden bovenaan de foto geplaatst (-gravity North). De lettergrootte bedraagt 90 (-pointsize 90). Met een halfdoorzichtie zwarte achtergrond (-undercolor "rgba(0,0,0,0.5)"). En een opvallende gele tekstkleur (-fill yellow). De tekst op de foto wordt "Pi Camera" (-annotate +0+0 ' Pi Camera '. Je kunt zelf de mogelijkheden ontdekken in de handleiding op het internet.
  11. Je kunt de helderheid instellen van -1.0 (minimale helderheid) tot 1.0 (maximale helderheid). Standaard wordt 0 gebruikt. Neem een foto met de volgende helderheid:

    output="Desktop/Overbelicht.jpg"
    brightness=0.5
    rpicam-still -p $preview -o $output --brightness $brightness

  12. Om een overzicht te krijgen van de helderheidsinstelling nemen we die op in een lus. We maken dus een foto's met verschillende helderheidsinstellingen (telkens met 0.2 hogere helderheid) en plaatsen deze in de map PiCamera op het Bureaublad. Daarna maken we van de foto's een film met ffmpeg waarbij de foto's in elkaar overvloeien om deze uiteindelijk af te spelen:

    directory="Desktop/PiCamera"
    mkdir -p $directory
    filenr=0
    for in $(LC_ALL="en_US.UTF-8" seq -1 0.2 1)
    do
      output=$(printf "$directory/Foto%0*d.jpg" 3 $filenr)
      filenr=$((filenr 1))
      rpicam-still --brightness $i -t 1000 -o $output --nopreview
    done
    duration=#duration in seconds
    crossfadeDuration=#crossfade duration in seconds
    width=640
    height=360
    videooutput="$directory/PiCamera.mp4"
    ffmpeg --$directory/Foto%3d.jpg -vf zoompan=d=$(((duration+crossfadeDuration)/crossfadeDuration)):s=${width}x$height:fps=$((1/crossfadeDuration)),framerate=25:interp_start=0:interp_end=255:scene=100 -c:v mpeg4 -maxrate 5-q:$videooutput
    ffplay -autoexit $videooutput

  13. Probeer iets gelijkaardigs voor het contrast (regelbaar vanaf 0 = weinig contrast over 1 = standaard contrast en meer):
    1. Pas daarvoor de lus aan zodat deze telt van 0 tot 2 in stapjes van 0.2.
    2. Vervang in de rpicam-still opdracht de brightness optie door de contrast optie.
  14. Je kunt ook nabewerken met rpicam zelf. Daarvoor gebruik je een configuratiebestand met de bewerkingen (en de volgorde waarin) die uitgevoerd moeten worden. M.a.w. je kunt combineren. De configuratie voor de nabewerking (postProcess) definiëren we eerst in een variabele die bestaat uit meerdere regels (Heredoc). Zo'n variabele begint en eindigt steeds met hetzelfde stopwoord (in ons geval EOF). Deze variabele schrijven we dan weg naar een tijdelijk bestand (postProcess.json) waardoor het beschikbaar wordt voor de opdracht rpicam-hello. Onderstaand voorbeeld zorgt voor een negatief beeld:

    negate=$(cat << EOF
    {
        "negate":
        {
        }
    }
    EOF
    )
    echo $negate postProcess.json
    rpicam-hello --post-process-file postProcess.json

  15. Een complexere nabewerking, is DRC (Dynamic Range Compression).. Om het verschil beter te kunnen beoordelen, maken we een twee foto's: één met HDR nabewerking en één zonder. Daarna laten we beide foto's op het scherm weergeven om ze te vergelijken:

    drc=$(cat << EOF
    {
        "hdr" :
        {
        "num_frames" : 1,
        "lp_filter_strength" : 0.2,
        "lp_filter_threshold" : [ 0, 10.0 , 2048, 205.0, 4095, 205.0 ],
        "global_tonemap_points" :
        [
            { "q": 0.1, "width": 0.05, "target": 0.15, "max_up": 1.5, "max_down": 0.7 },
            { "q": 0.5, "width": 0.05, "target": 0.5, "max_up": 1.5, "max_down": 0.7 },
            { "q": 0.8, "width": 0.05, "target": 0.8, "max_up": 1.5, "max_down": 0.7 }
        ],
        "global_tonemap_strength" : 1.0,
        "local_pos_strength" : [ 0, 6.0, 1024, 2.0, 4095, 2.0 ],
        "local_neg_strength" : [ 0, 4.0, 1024, 1.5, 4095, 1.5 ],
        "local_tonemap_strength" : 1.0,
        "local_colour_scale" : 0.9
        }
    }
    EOF
    )
    echo $drc postProcess.json
    output="Desktop/DRC.jpg"
    rpicam-still -o $output --post-process-file postProcess.json  --nopreview
    (eom $output) &
    output="Desktop/Foto.jpg"
    rpicam-still -o $output --nopreview
    (eom $output) &

    De opdrachten om de foto's weer te geven, staan tussen haken en eindigen op & zodat het script verder kan werken zonder dat Eye Of Mate voltooid (afgesloten) is. M.a.w. multitasking.
  16. HDR en DRC worden dikwijls verward en de termen worden regelmatig door elkaar gebruikt. Maar wat is nu het verschil, we bepalen dit door de vorige nabewerking te vervangen door:

    hdr=$(cat << EOF
    {
        "hdr" :
        {
        "num_frames" : 8,
        "lp_filter_strength" : 0.2,
        "lp_filter_threshold" : [ 0, 10.0 , 2048, 205.0, 4095, 205.0 ],
        "global_tonemap_points" :
        [
            { "q": 0.1, "width": 0.05, "target": 0.15, "max_up": 5.0, "max_down": 0.5 },
            { "q": 0.5, "width": 0.05, "target": 0.45, "max_up": 5.0, "max_down": 0.5 },
            { "q": 0.8, "width": 0.05, "target": 0.7, "max_up": 5.0, "max_down": 0.5 }
        ],
        "global_tonemap_strength" : 1.0,
        "local_pos_strength" : [ 0, 6.0, 1024, 2.0, 4095, 2.0 ],
        "local_neg_strength" : [ 0, 4.0, 1024, 1.5, 4095, 1.5 ],
        "local_tonemap_strength" : 1.0,
        "local_colour_scale" : 0.8
        }
    }
    EOF
    )
    echo $hdr postProcess.json
    output="Desktop/HDR.jpg"

    Pas het script aan waar nodig en zorg ervoor dat ook de reeds aangemaakte DRC foto wordt weergeven.
  17. Nog een leuke toepassing is bewegingsdetectie:

    timeout=15
    motion=$(cat << EOF
    {
        "motion_detect" :
        {
        "roi_x" : 0.1,
        "roi_y" : 0.1,
        "roi_width" : 0.8,
        "roi_height" : 0.8,
        "difference_m" : 0.1,
        "difference_c" : 10,
        "region_threshold" : 0.005,
        "frame_period" : 5,
        "hskip" : 2,
        "vskip" : 2,
        "verbose" : 1
        }
    }
    EOF
    )
    echo $motion postProcess.json
    rpicam-hello -t $((timeout*1000)) --lores-width 128 --lores-height 96 --post-process-file postProcess.json

    De instelling "verbose" : 1 zorgt ervoor dat er in de terminal meldingen verschijnen. Daar bewegingsdetectie zeer intensief gebruik maakt van de rekenkracht van de processor gebruiken we lage resolutiebeelden (128x96). Lage resolutiebeelden volstaan om beweging te detecteren (vergelijk met dieren met een op beweging gespecialiseerd zicht).
  18. Sommige foto-toepassingen vergen een aangepaste sluitertijd (exposure). Zo kan je enkel snelle bewegingen, zoals in de sport, enkel goed fotograferen met een korte sluitertijd. Nachtbeelden van statische scenes hebben een lange sluitertijd nodig. De witbalans (hoeveelheid opgevangen licht) wordt daarbij automatisch gecorrigeerd. Er zijn 3 vooringestelde sluitertijden: normal, sport en long. Om deze sluitertijden te beoordelen, gebruiken we terug een lus, maar deze keer met termen:

    exposures=("normal" "sport" "long")
    for exposure in ${exposures[@]};
    do
      output="Desktop/$exposure.jpg"
      rpicam-still -o $output --exposure $exposure --nopreview
      (eom $output) &
    done

  19. Programmeer zelf een lus om de verschillende voorgeprogrammeerde witbalansen te beoordelen. De beschikbare --awb rpicam opties zijn: auto, incandescent, tungsten, fluorescent, indoor, daylight, cloudy.
  20. Alle mogelijkheden van de rpicam (binnenkort rpicam) vind je terug in de documentatie op internet.
  21. Schakel de Raspberry Pi uit.
  22. Gebruik het experimenteerbord en draadverbindingen om een drukknop op de Pi aan te sluiten:
    Drukknop aansluiten op de Pi
  23. Start de Raspberry Pi terug.
  24. Gpio (General Purpose In/Out) is de dubbele rij aansluitingen op de Raspberry Pi waarop je verschillende in- en uitvoerapparaten kunt aansluiten. In ons geval een drukknop (invoerapparaat). Een GPIO pin kan twee toestanden hebben: 0 indien deze dezelfde spanning heeft als massa (ground) of 1 als er een spanning van +3,3 volt t.o.v de massa op staat. Aangezien we de drukknop gebruiken om de pin kort te sluiten naar massa, geven we GPIO pin standaard een spanning van 3,3 volt (Pull Up). We configureren GPIO 17 als ingang met een spanning van 3,3 volt met de opdracht raspi-gpio set 17 pu. De toestand van de GPIO pin 17 lees je in met de opdracht raspi-gpio get 17. Het script bevat commentaarregels (beginnen met #) met uitleg:

    output="Desktop/Afdrukken.jpg"
    # Drukknop is aangesloten op GPIO pin 17 en massa
    buttonPin=17
    # Gebruikte GPIO pin wordt als ingang gebruikt en krijgt standaard 3,3 volt toegewezen (Pull Up)
    raspi-gpio set $buttonPin pu
    # Start de voorvertoning
    (rpicam-hello -t 0) &
    # Start van de oneindige lus
    while truedo
      # Lees de toestand van de gebruikte GPIO pin in
      button=$(raspi-gpio get $buttonPin)
      if [[ $button == *"level=0"* ]]; then # Drukknop ingedrukt dan
        # Stop de voorvertoning
        killall rpicam-hello
        # Neem de foto
        rpicam-still -o $output --nopreview
        # Verlaat de oneindige lus
        break
      fi
    done

  25. Wil je zelf op de foto staan, dan moet er na het afdrukken 3 seconden wachttijd ingesteld worden. Dit kan door voor het nemen van de foto de opdracht sleep 3 te plaatsen. Zorg er wel voor dat de voorvertoning tijdens de 3 seconden blijft staan, anders sta je misschien niet op de foto!
  26. Door afzonderlijke foto's van licht aangepaste situaties in een video op te nemen, maak je een stop motion animatie. Pas de programmacode aan zodat bij elke druk op de drukknop een nieuwe foto wordt gemaakt:

    # Bash instellen om te reageren op een toetsaanslag
    # Let op: dit werkt alleen als het terminalvenster waarin het script gestart is actief is, m.a.w op de voorgrond staat.
    if -t ]; then
      SAVED_STTY="`stty --save`"
      stty -echo -icanon -icrnl time min 0
    fi
    keypress=''

    # Alle foto's komen terecht in deze reeds aangemaakte map 
    directory="Desktop/PiCamera"
    # Maak de doelmap leeg
    rm $directory/*
    # Drukknop is aangesloten op GPIO pin 17 en massa
    buttonPin=17
    # Gebruikte GPIO pin wordt als ingang gebruikt en krijgt standaard 3,3 volt toegewezen (Pull Up)
    raspi-gpio set $buttonPin pu
    # Zet de foto teller op 0
    count=0
    # Start de voorvertoning
    (rpicam-hello -t 0) &
    # Bij het indrukken van een toets wordt de lus onderbroken
    while "x$keypress" "x" ]; do
      # Lees de toestand van de gebruikte GPIO pin in
      button=$(raspi-gpio get $buttonPin)
      if [[ $button == *"level=0"* ]]; then # Drukknop ingedrukt
        # Stel de bestandnaam van de foto samen
        output=$(printf "$directory/Foto%0*d.jpg" 3 $count)
        # Stop de voorvertoning
        killall rpicam-hello
        # Neem de foto
        rpicam-still -o $output --nopreview
        # Herstel de voorvertoning
        (rpicam-hello -t 0) &
        # Verhoog de foto teller
        count=$((count 1))
      fi
      # Controleer of er een toets werd ingedrukt
      keypress=$(cat -v)
    done
    # Stop de voorvertoning
    killall rpicam-hello

    # Bash terug herstellen om tekst in te kunnen typen
    if -t ]; then stty "$SAVED_STTY"fi

    # De bestandnaam van de aan te maken video
    videooutput="$directory/PiCamera.mp4"
    # Maak de Stop motion video aan
    ffmpeg -r 10 -$directory/Foto%03d.jpg $videooutput
    # Speel de Stop motion video af
    ffplay -autoexit $videooutput

    De while lus stopt enkel bij het drukken op een toets. Dit werkt echter alleen als het script toetsenbordinformatie kan ontvangen (focus). Dus het Terminal-venster moet actief zijn (focus geven) om het script met een toets te stoppen. Foto%0*d.jpg" 3 $count zal elke foto opslaan met de naam Foto gevolgd door 3 cijfers met voorloopnullen: 001, 002, 003, enz. Daardoor kunnen ze eenvoudig in de juiste volgorde in de video opgenomen worden. Maak ten minste 25 foto's voor een korte stop motion video met allerhande materiaal (gebruik je fantasie). Wie thuis nog LEGO of ander oud speelgoed heeft, kan ook daarmee artistiek aan de slag. Je kunt de beeldfrequentie aanpassen via -r 10 (hier 10 beelden per seconde).
  27. Misschien heb je tijdens deze les inspiratie gekregen om zelf een eigen toepassing te schrijven. Niemand houdt je tegen.
  28. Wie een kant en klare toepassing wil, kan eens kijken naar RaspiCam.

Openbare reacties op deze pagina (kunnen door alle bezoekers gelezen worden)

, vrijdag 2 juni 2023 19:28