Raspberry Pi Camera time-lapse
In dit project zul je leren hoe je je eigen time-lapse camera kan maken met je Raspberry Pi 4 of Raspberry Pi 5. In dit project word alles uitgelegd zodat het makkelijk zelf te doen is en ook makkelijk zelf aan te passen is naar wat nodig is. We zullen het o.a hebben over hoe je de time-lapse volledig zelf kan configureren en ook is word er uitgelegd hoe de functies in de code werken. Laten we dan maar meteen beginnen!
Overzicht stappen van het project
- Terminal openen
- Projectmap aanmaken
- config.yaml maken en uitleg
- Installatiescript (dep.bash) maken en uitvoeren
- Python‑script (timelapse.py) aanmaken en code uitleg
- Directorystructuur controleren
- Timelapse draaien
- Video bekijken
- Veelvoorkomende problemen & tips
1. Terminal openen
- Grafisch: klik op het zwart‑wit icoon van de terminal (linksbovenin de menubalk).
- Sneltoets: druk op Ctrl+Alt+T.
- De terminal is je “commandoregel” waar je alle volgende commando’s invoert.
2. Projectmap aanmaken
In de terminal typ je:
mkdir ~/timelapse_projectmkdirmaakt een nieuwe map.~staat voor je home‑directory (bijv./home/pi).
Ga naar die map:
cd ~/timelapse_projectcd= change directory, je “gaat naar” de map.
Controleer dat je in de juiste map zit:
pwdpwdtoont je huidige locatie in het bestandssysteem.- Je zou iets als
/home/pi/timelapse_projectmoeten zien.
3. config.yaml maken en uitleg
Open de editor:
nano config.yamlnanois een eenvoudige teksteditor in de terminal.
Plak deze inhoud :
camera:
preview: true # Laat tijdens opnemen een klein voorvertoningsvenster zien
pixel_ratio:
- 1920 # Breedte van de foto’s
- 1080 # Hoogte van de foto’s
preview_pixel_ratio:
- 640 # Breedte van de preview
- 480 # Hoogte van de preview
logging: true # Zet op true om statusberichten in de terminal te zien
picture_folder: "pictures" # Map waar foto’s komen
time_lapse_folder: "time_lapse_videos" # Map waar de video komt
maxtime:
duration: 60 # Totale opname‑tijd in seconden
frame_interval: 0.5 # Tussen elke foto (in seconden)
frame_rate_video: 30 # Frames per seconde in de videoOpslaan: druk op Ctrl+O, Enter.
Afsluiten: Ctrl+X
Wat doet dit?
Config.yaml is ook wel het configuratie bestand van alle python code die je zult uitvoeren. Je vertelt het script hoe de camera moet werken, waar de bestanden komen te staan, hoe lang het loopt, en hoe snel de uiteindelijke video is.

4. Installatiescript (dep.bash) maken en uitvoeren
Maak het bestand:
nano dep.bashPlak dit erin:
#!/usr/bin/env bash
sudo apt-get update -y # Haalt de nieuwste pakketlijsten op
sudo apt-get upgrade -y # Installeert alle beschikbare updates
sudo apt-get autoremove -y # Verwijdert oude, overbodige pakketten
# Installeer Python-modules & camera-drivers
sudo apt-get install python3-picamera2 -y
sudo apt-get install python3-libcamera -y
sudo apt-get install python3-yaml -y
sudo apt-get install python3-shutil -y
sudo apt-get install python3-opencv -y # ‘cv2’
sudo apt-get install python3-numpy -y
sudo apt-get install python3-pathlib -yMaak uitvoerbaar:
chmod +x dep.bashVoer uit:
./dep.bash
Wat gebeurt er?
updateenupgradezorgen dat je systeem up‑to‑date is.autoremoveruimt op.installhaalt specifieke Python‑packages en camera‑libraries binnen.
5. Python‑script (timelapse.py) aanmaken en code uitleg
Open een nieuw bestand:
nano timelapse.py
Plak de volledige code (van from picamera2 import Picamera2 t/m cleanup()).
from picamera2 import Picamera2
from libcamera import Transform, controls
import libcamera
import yaml
import shutil
import cv2
import numpy as np
from pathlib import Path
import os
import time
# Open het configuratie bestand en lees hem
with open('config.yaml', 'r') as file:
config = yaml.safe_load(file)
# Maak een camera object
camera = Picamera2()
# Zet maximale stappen
iterations = int(config["maxtime"]["duration"] / config["frame_interval"]) # maximale tijd / interval
picdir = config["picture_folder"]
log = config["logging"]
def images_to_video(image_folder=f"{config['picture_folder']}", output_path=f"{config['time_lapse_folder']}/output.mp4", fps=30, pixel_radius=3):
if log:
print("Foto's naar video aan het converteren...")
folder_path = Path(image_folder)
# Get list of numbered images
image_files = sorted([f for f in folder_path.glob('*.jpg')
if f.stem.isdigit()],
key=lambda x: int(x.stem))
if not image_files:
raise ValueError("Geen fotos gevonden")
# Read first image to get dimensions
first_frame = cv2.imread(str(image_files[0]))
# Create VideoWriter object with H.264 codec
height, width = first_frame.shape[:2]
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # H.264 codec
out = cv2.VideoWriter(
str(output_path),
fourcc,
fps,
(width, height)
)
# Process each image
for img_path in image_files:
frame = cv2.imread(str(img_path))
# Apply Gaussian blur based on pixel radius
if pixel_radius > 0:
frame = cv2.GaussianBlur(frame,
(pixel_radius*2 + 1, pixel_radius*2 + 1),
0)
out.write(frame)
# Release VideoWriter
out.release()
cv2.destroyAllWindows()
def create_directorys(folders: list):
for folder in folders:
if not os.path.exists(f"{os.getcwd()}/{folder}"):
try:
os.mkdir(f"{os.getcwd()}/{folder}")
print(f"Map aangemaakt : {folder}")
except Exception as e:
if e.errno != errno.EEXIST:
print(f"Error bij het aanmaken van een map: {e}")
return
def cleanup():
shutil.rmtree(f"{os.getcwd()}/{config['picture_folder']}") # verwijdert alle foto bestanden
exit()
def maak_foto_en_sla_op(i):
try:
# Maak de foto
camera.capture_file(f"{os.getcwd()}/{picdir}/{i}.jpg")
if log:
print(f"foto {i} opgeslagen")
except Exception as e:
raise e
def error(e):
images_to_video()
cleanup()
print(f"Er is een error voorgekomen ({e}). De fotos die zijn gemaakt zijn opgeslagen en worden omgezet in een time-lapse")
exit(1)
# configureer de code
camera_config = camera.create_still_configuration(
main={"size": (config["camera"]["pixel_ratio"][0], config["camera"]["pixel_ratio"][1])},
lores={"size": (config["camera"]["preview_pixel_ratio"][0], config["camera"]["preview_pixel_ratio"][1])}
)
camera_config = camera.create_preview_configuration(
main={"size": (config["camera"]["pixel_ratio"][0], config["camera"]["pixel_ratio"][1])},
lores={"size": (config["camera"]["preview_pixel_ratio"][0], config["camera"]["preview_pixel_ratio"][1])}
)
camera.configure(camera_config)
camera.start(show_preview=config["camera"]["preview"])
camera.set_controls({"AfMode": controls.AfModeEnum.Continuous, "AfSpeed": controls.AfSpeedEnum.Fast})
create_directorys([config["picture_folder"], config["time_lapse_folder"]])
print("Let op : Het bestand output.mp4 word overgeschreven ook al staat hij er. Als je nog een oude video heb sla hem dan onder een andere naam op of op een andere plek om hem nog te behouden")
if log:
print("Programma begint met opnemen over 3 seconden")
time.sleep(3)
if log:
print("Programma maakt nu foto's")
try:
for i in range(1, iterations+1):
try:
maak_foto_en_sla_op(i)
time.sleep(config["frame_interval"])
except Exception as e:
error(e)
cleanup()
except Exception as e:
error(e)
cleanup()
images_to_video()
print("Klaar!")
cleanup()Opslaan en afsluiten: Ctrl+O, Enter & Ctrl+X.
Uitleg belangrijkste stukken code
Imports
from picamera2 import Picamera2
import yaml, shutil, cv2, numpy as np
from pathlib import Path
import os, timeHaalt alle modules binnen die we nodig hebben.
Config laden
with open('config.yaml','r') as f:
config = yaml.safe_load(f)Leest je instellingen uit config.yaml.
Iteraties berekenen
iterations = int(config["maxtime"]["duration"] / config["frame_interval"])
Berekent hoeveel foto’s er in totaal worden genomen.
Mappen aanmaken
def create_directorys(folders):
# Maakt folders als ze nog niet bestaanZorgt dat pictures/ en time_lapse_videos/ bestaan.
Foto’s maken
def maak_foto_en_sla_op(i):
camera.capture_file(f"{picdir}/{i}.jpg")Neemt een enkele foto en slaat ‘m op als 1.jpg, 2.jpg, etc.
Foto’s naar video
def images_to_video(...):
# Leest alle .jpg-bestanden, maakt er een mp4 vanCombineert de foto’s en voegt (optioneel) blur toe.
Error-afhandeling
def error(e):
images_to_video() # Zet op dat er een video wordt gemaakt
cleanup()Vangt fouten op, zorgt dat gemaakte foto’s niet verloren gaan.
Hoofdprogramma
camera.start(...)
for i in range(1, iterations+1):
maak_foto_en_sla_op(i)
time.sleep(config["frame_interval"])
images_to_video()
cleanup()- Start de camera
- Loopt door alle iteraties
- Pakt foto, wacht interval
- Maakt video, ruimt op
6. Directorystructuur controleren
In je timelapse_project‑map zou je nu moeten zien:
ls -R
.
├── config.yaml
├── dep.bash
├── timelapse.py
├── pictures/ # (leegt aanvankelijk)
└── time_lapse_videos/ # (leegt aanvankelijk)7. Timelapse draaien
- Zorg dat je in de projectmap bent (
cd ~/timelapse_project). - Typ:
python3 timelapse.py
Wat je ziet:
- In de terminal statusberichten (“foto 1 opgeslagen”, …).
- Na 3 seconden een countdown (als logging aanstaat).
- De camera maakt foto’s volgens jouw interval.
Wacht tot Klaar! in de terminal verschijnt.

8. Video bekijken
Na afloop staat de timelapse in:
~/timelapse_project/time_lapse_videos/output.mp4Op de Pi zelf:
omxplayer time_lapse_videos/output.mp4Op je computer: haal het bestand via SCP/USB over en open in VLC of een andere speler.
9. Veelvoorkomende problemen & tips
| Probleem | Oplossing |
|---|---|
| Camera niet beschikbaar | Check sudo raspi-config → Interface Options → Camera |
| Permissie‑fout | Draai script met python3 (niet als root), en check bestandsperms |
| Weinig schijfruimte | Pas maxtime of frame_interval aan, of breid SD‑kaart uit |
| Foto’s bewaren | Haal of comment cleanup() weg aan het einde van het script |
| Video‑codec problemen | Gebruik omxplayer of pas fourcc in images_to_video() aan |

