Free demoJob-oriented courses at Debugshala, Old Palasia, Indore. Freshers, non-IT and year-gap welcome.Book a free demo +91-8982385539

Raspberry Pi Camera Projects: Picamera2 Timelapse and Motion

Lesson 6 of 7 · 11 min · Updated 12 Nov 2026

Raspberry Pi camera projects with Picamera2: set up Camera Module 3, build a timelapse, a motion-detecting camera and a robot dashcam, with numpy demos.

Think about the watchman at the gate of a housing society in Vijay Nagar. He does not write down everything he sees. He sits quietly, and only when something changes, a car arriving or a stranger walking in, does he note the time and look closely.

A camera on a robot needs the same habit. A Camera Module produces millions of numbers every second. A useful camera project decides which of those numbers matter, keeps those, and ignores the rest.

What is a Raspberry Pi camera project?

Map the watchman onto the hardware. His eyes are the camera sensor. His habit of glancing every few seconds is a capture loop. His "something changed" is a comparison between two frames. His notebook is the SD card where you save photos or video.

A Raspberry Pi camera project is a program that uses a camera connected to a Raspberry Pi single-board computer to capture images or video and process them, for tasks such as timelapse, security monitoring, robot vision or inspection.

The Raspberry Pi suits this job because it runs full Linux and Python, unlike the microcontrollers in the earlier projects. The comparison is in Arduino vs ESP32 vs Raspberry Pi. On a robot, the usual split is a Pi for the camera and decisions, and an Arduino for the motors, like the arm in the robotic arm project.

What you need

Part Notes
Raspberry Pi 5 or Pi 4 A Pi 5 is noticeably faster for image processing
Raspberry Pi Camera Module 3 12 MP with autofocus; the wide and NoIR versions also work
The right ribbon cable The Pi 5 has smaller camera connectors and needs a Pi 5 camera cable
microSD card with Raspberry Pi OS Bookworm or later; the desktop image has Picamera2 preinstalled
Official power supply 5 V, 5 A for a Pi 5; a weak supply causes random crashes

How does the Pi camera software stack work?

Raspberry Pi OS uses libcamera, an open-source camera framework. The sensor sends raw data to the Pi's image signal processor (ISP), which handles exposure, white balance, denoising and colour. On top of libcamera sit two tools you will use.

  • rpicam-apps: command-line programs such as rpicam-hello, rpicam-still and rpicam-vid. Older guides call them libcamera-hello and so on.
  • Picamera2: the official Python library. It hands you each frame as a numpy array, which is what makes it so easy to combine with OpenCV and your own code.
Raspberry Pi camera pipeline diagram: Camera Module sensor to the Pi's image signal processor through libcamera, producing a main RGB888 stream and a low-resolution YUV420 stream that Picamera2 returns as numpy arrays for saving, motion detection and computer vision

One camera can give you two streams at once: a large one to save and a small one to analyse quickly.

That two-stream idea is the key to fast projects. A 320 × 240 "lores" frame has about 77,000 pixels, while a 1280 × 720 frame has over 900,000. Analyse the small one and save the large one only when something interesting happens.

Set up and test the camera

  1. Power off the Pi. Never connect a camera ribbon to a running board.
  2. Connect the cable. Lift the connector's latch, insert the ribbon fully with the contacts facing the right way for your board, and press the latch down.
  3. Boot and update. Run sudo apt update && sudo apt full-upgrade.
  4. List cameras. Run the first command below. It should name your sensor (the Camera Module 3 reports imx708).
  5. Take a test photo. Run the second command and open test.jpg.
Terminal
rpicam-hello --list-cameras
rpicam-still -o test.jpg
sudo apt install -y python3-picamera2      # only needed on Lite images

An image is just an array

Before the projects, see how the camera's output looks to your code. A greyscale frame is a 2D numpy array of brightness values from 0 to 255; a colour frame adds a third dimension for the three channels. Most camera tricks are array operations on these numbers. If numpy is new to you, read numpy arrays explained.

Python
import numpy as np

# A tiny 6 x 8 greyscale "photo": a bright parcel on a dim floor (0 = black, 255 = white)
img = np.array([
    [ 40,  42,  45,  44,  41,  40,  39,  38],
    [ 41,  44, 180, 200, 190,  43,  40,  39],
    [ 43,  46, 210, 230, 220,  47,  42,  40],
    [ 42,  45, 190, 215, 205,  46,  41,  40],
    [ 40,  43,  47,  49,  46,  44,  40,  39],
    [ 39,  41,  44,  45,  43,  41,  39,  38],
], dtype=np.uint8)

print("shape (rows, cols):", img.shape, " mean brightness:", round(img.mean(), 1))
mask = img > 128                                  # threshold: bright = True
print(mask.astype(int))
rows, cols = np.nonzero(mask)
print("object pixels:", mask.sum(), " rows", rows.min(), "to", rows.max(),
      " cols", cols.min(), "to", cols.max())

brighter = np.clip(img.astype(int) * 2, 0, 255)  # what too much gain does
print("pixels clipped at 255 after 2x gain:", int((brighter == 255).sum()))

Thresholding turns the photo into a yes/no mask, and the mask's rows and columns give the object's bounding box. The last line shows why exposure matters: doubling the gain pushes every parcel pixel to 255, and the detail inside the object is lost for good.

Three Raspberry Pi camera projects to build

Project 1: a timelapse camera

A timelapse takes a photo every few seconds and plays them back quickly, a gentle first project that only captures and saves.

Python
import time
from picamera2 import Picamera2

picam2 = Picamera2()
picam2.configure(picam2.create_still_configuration(main={"size": (1920, 1080)}))
picam2.start()
time.sleep(2)                          # let auto exposure and white balance settle

for i in range(1, 121):                # 120 photos, one every 30 s = 1 hour
    picam2.capture_file(f"plant_{i:03d}.jpg")
    print("saved", i)
    time.sleep(30)

picam2.stop()

Join the photos into a video with ffmpeg, at 24 frames per second:

Terminal
ffmpeg -framerate 24 -i plant_%03d.jpg -c:v libx264 -pix_fmt yuv420p timelapse.mp4

If the brightness flickers between frames, auto exposure is adjusting each shot. Fix it after the warm-up with picam2.set_controls({"AeEnable": False, "AwbEnable": False}).

Project 2: a motion-detecting security camera

This is the watchman in code. The camera runs two streams. Every 0.1 seconds the program compares the small greyscale frame with the previous one, counts how many pixels changed a lot, and saves a full-size photo when enough have.

Motion detection flow for a Raspberry Pi camera: previous and current low-resolution frames, absolute difference, threshold at 25, fraction of changed pixels above 2 percent, cooldown check, then save a full-resolution photo

Difference, threshold, count, then decide. The cooldown stops one event saving fifty photos.

Python
import time
import numpy as np
from picamera2 import Picamera2

picam2 = Picamera2()
config = picam2.create_preview_configuration(
    main={"size": (1280, 720), "format": "RGB888"},
    lores={"size": (320, 240), "format": "YUV420"})
picam2.configure(config)
picam2.start()
time.sleep(2)

w, h = 320, 240
prev, last_save = None, 0
while True:
    grey = picam2.capture_array("lores")[:h, :w].astype(np.int16)  # Y plane = brightness
    if prev is not None:
        fraction = (np.abs(grey - prev) > 25).mean()               # share of changed pixels
        if fraction > 0.02 and time.time() - last_save > 5:
            name = time.strftime("motion_%Y%m%d_%H%M%S.jpg")
            picam2.capture_file(name)                               # full-size main stream
            print(f"motion {fraction:.1%} -> saved {name}")
            last_save = time.time()
    prev = grey
    time.sleep(0.1)

The YUV420 format stores brightness (the Y plane) first, so slicing the first h rows gives a ready-made greyscale image. Converting to int16 before subtracting matters: with uint8, 10 − 20 wraps round to 246 instead of giving −10.

Here is the same logic on simulated frames, so you can tune the threshold, the 2% trigger and the cooldown without a camera:

Python
import numpy as np
rng = np.random.default_rng(1)
H, W, THRESH, MIN_FRACTION, COOLDOWN = 24, 32, 25, 0.02, 3

def frame(t):
    img = 60 + rng.normal(0, 4, (H, W))            # dim room plus sensor noise
    if 4 <= t <= 8:                                # a person walks across
        x = 4 + (t - 4) * 5
        img[6:20, x:x + 5] = 170
    return img.astype(np.int16)

prev, last_saved = frame(0), -99
for t in range(1, 12):                             # one frame every 0.5 s
    cur = frame(t)
    changed = np.abs(cur - prev) > THRESH
    fraction = changed.mean()
    action = ""
    if fraction > MIN_FRACTION:
        action = "SAVE photo" if t - last_saved >= COOLDOWN else "motion (cooldown)"
        if action == "SAVE photo":
            last_saved = t
    print(f"frame {t:2}: {fraction:6.1%} of pixels changed  {action}")
    prev = cur

Sensor noise alone never crosses the threshold, so frames 1 to 3 stay quiet. The walker triggers a save at frame 4, the cooldown suppresses the next two, and a second save comes at frame 7. Set THRESH to 5 and the noise starts triggering by itself, a common cause of a camera that fills the SD card overnight.

Project 3: a robot dashcam

On a moving robot, a short video of each run is the best debugging tool you have: when the line follower leaves the track, the video shows why.

Python
from picamera2 import Picamera2

picam2 = Picamera2()
picam2.start_and_record_video("run.mp4", duration=10)   # records 10 s, then stops
picam2.close()

start_and_record_video picks the right encoder and container from the file extension. For longer runs, record at 1280 × 720 to keep files small, and mount the camera low and tilted slightly down so the floor ahead fills the frame.

Quick check

Why does the motion camera analyse the 320 × 240 lores stream instead of the 1280 × 720 main stream?

Quick check

Why convert frames to int16 before subtracting them?

Testing and debugging

"No cameras available" almost always means the cable: check that it is fully inserted at both ends, the right way round, and the right type for a Pi 5. "Device or resource busy" means another program, often a previous script, still holds the camera; close it or reboot.

Pictures are blurry: the Camera Module 3 has autofocus, so give it a second after starting, or set picam2.set_controls({"AfMode": 2}) for continuous focus. Colours look blue in OpenCV: OpenCV expects BGR order. Picamera2's RGB888 format already stores pixels as B, G, R in memory, so you can pass it to OpenCV directly; with PIL, convert first.

For a breather between captures, try quick numpy and logic quizzes on Debugshala Test.

Extensions to try next

  • Send alerts. When the motion camera saves a photo, publish a message over MQTT to your phone.
  • Track colours. Find a coloured ball and steer towards it, the first project in computer vision for robots with OpenCV.
  • Stream to a phone. The official Picamera2 examples include an MJPEG streaming server you can adapt for a robot's first-person view.
  • On-device AI. Run a small object detector on the Pi to recognise people or parcels, not just motion.

Key takeaways

  • Raspberry Pi OS uses libcamera, with rpicam-apps for the command line and Picamera2 for Python.
  • Install Picamera2 from apt, and use --system-site-packages if you work in a venv.
  • Every frame is a numpy array; thresholding and differencing are simple array operations.
  • Analyse a small stream, save the large one, and use a cooldown to avoid floods of photos.
  • Most "camera not found" errors are cable problems.
Take the free Robot Projects & Arduino quiz10 quick questions with explanations. No sign-up needed, and you can come back to this lesson after.

FAQ

Which camera should I use with a Raspberry Pi?

For most projects, the Raspberry Pi Camera Module 3 is the best starting point: 12 MP, autofocus, good low-light performance and full support in Picamera2. Pick the wide version for robots that need a broad view, and the NoIR version with infrared lighting for night-time monitoring.

Can I use a USB webcam instead of a Camera Module?

Yes. A USB webcam appears as a standard video device, and OpenCV's VideoCapture can read it. You lose Picamera2's dual streams and fine camera controls, and some webcams use more CPU. A Camera Module is usually better for robots, while a webcam is fine for a quick desk test.

Does Picamera2 work with Raspberry Pi OS Lite?

Yes. Picamera2 is not preinstalled on Lite images, so install it with sudo apt install python3-picamera2 --no-install-recommends. That skips the desktop preview windows, which a headless robot does not need anyway. Save images to files or stream them instead of opening a preview.

Why is my Raspberry Pi camera image dark or flickering?

The camera's auto exposure needs a moment to settle after starting, so wait one or two seconds before capturing. Flicker under tube lights comes from the mains frequency; India uses 50 Hz, and matching the exposure time to multiples of 10 ms reduces banding. For timelapses, lock exposure and white balance after the warm-up.

Where can I learn Raspberry Pi camera projects in Indore?

Raspberry Pi with a camera for basic computer vision is part of Debugshala's Raspberry Pi and camera robotics sessions, within its project-based Robotics course at the Old Palasia campus. You also learn Python for robotics, sensors, motor control and ROS 2 basics, with a free demo class before you join.

From the team behind this site

Go further with the Robotics Course at Debugshala

These tutorials are written by Debugshala, a training and placement institute at Old Palasia, Indore. The classroom course adds live mentoring, real projects and interview preparation.

  • Offline classes at Old Palasia, Indore
  • Free demo class before you pay
  • Non-IT, fresher and year-gap friendly
  • Placement assistance

700+ students placed · 200+ hiring partners · 4.9★ Google rating

Robotic Arm Project: Build a 4-DOF Servo Arm with ArduinoComputer Vision for Robots with OpenCV: Build a Ball Follower