What you will have by the end of this part
Part 2 walked through the hardware for this project: a Raspberry Pi 5, a Camera Module 3, an AI accelerator board, a speaker, a PIR sensor and an enclosure. Part 3 explained the theory behind face recognition - detection, alignment, embeddings and matching - without writing a line of code. This part is where the project actually starts. You will install an operating system on the Raspberry Pi, physically connect the camera, and build a Python environment that can pull a frame off the camera into a format ready for processing. Nothing here recognises a face yet; that begins in part 5, which runs a face detector on the frames this part produces, and part 6, which turns detected faces into the embeddings described in part 3.
Think of this part as laying the floor before the building goes up. It is not glamorous, but every later part depends on it working cleanly: a camera that is not seated properly will produce intermittent, hard-to-debug failures three parts from now, and a Python environment set up carelessly will cause package conflicts just when you are trying to install a face recognition library. Take your time here.
Before you start
Hardware checklist
You should have the following in front of you, following the choices and approximate prices discussed in part 2. Exact prices vary by region and retailer, so treat any figures here as rough guidance rather than current quotes.
- A Raspberry Pi 5 (8 GB recommended for this project) and its official USB-C power supply - using an underpowered phone charger is the single most common cause of mysterious crashes on a Pi 5
- A microSD card, at least 32 GB, ideally a card rated A1 or A2 application class for faster random reads and writes
- A microSD card reader for your computer, if it does not have one built in
- A Raspberry Pi Camera Module 3 (the NoIR variant, as chosen in part 2, since it will later work with an infrared illuminator at night) and its ribbon cable
- The Raspberry Pi AI HAT+, or an NVIDIA Jetson Orin Nano if you chose that alternative path in part 2
- A monitor, keyboard and mouse are optional - this guide sets the Pi up headless, meaning you control it over the network from your own computer, but having a monitor nearby for the first boot is a reasonable safety net if something does not go to plan
- A computer (Windows, macOS or Linux) to flash the microSD card and to SSH into the Pi
Software versions this guide assumes
Raspberry Pi OS is updated periodically, and command names and menu wording do shift between releases. This guide was written against Raspberry Pi OS Bookworm (64-bit), which ships Python 3.11 and includes picamera2 by default. If you are reading this with a newer release installed, the broad steps should still apply, but check the official Raspberry Pi documentation if a specific command below is not found - operating systems move on, and a 45-minute hands-on guide cannot track every release.
- Raspberry Pi OS (64-bit), Bookworm or later
- Python 3.11 or later (comes with Raspberry Pi OS Bookworm)
- picamera2, the official camera library for Raspberry Pi OS, pre-installed on Bookworm images
- OpenCV, installed via pip as the opencv-python package
- NumPy, installed via pip (and also available system-wide)
- Raspberry Pi Imager, the official tool for writing OS images to an SD card, downloaded fresh from the Raspberry Pi website so you have the current version
If you chose the Jetson Orin Nano alternative in part 2, the operating system step differs: NVIDIA's JetPack is based on Ubuntu and installed with NVIDIA's SDK Manager rather than Raspberry Pi Imager, and camera access goes through a different library stack (typically GStreamer with NVIDIA's camera plugins rather than picamera2). The Python environment ideas in this part - virtual environments, OpenCV, checking your installation before moving on - still apply, but follow NVIDIA's own JetPack setup guide for the operating system and camera steps instead of the Raspberry Pi-specific instructions below. The rest of this guide assumes the Raspberry Pi 5 path.
Step 1: Flash Raspberry Pi OS onto the microSD card
Raspberry Pi Imager is the official tool for writing an operating system image to an SD card, and it also lets you pre-configure the Pi - setting a hostname, enabling remote access and joining a Wi-Fi network - before you ever plug the card into the Pi. This is what makes a headless setup possible: you never need a monitor attached to the Pi itself.
- Download Raspberry Pi Imager from the official Raspberry Pi website for your computer's operating system (Windows, macOS or Linux) and install it.
- Insert the microSD card into your computer, using a card reader if needed. Make a mental note of which drive it appears as, because the next steps will erase it completely.
- Open Raspberry Pi Imager. Click 'Choose Device' and select Raspberry Pi 5.
- Click 'Choose OS' and select Raspberry Pi OS (64-bit). You can pick the full Desktop image, which includes a graphical interface you can reach later over VNC, or Raspberry Pi OS Lite, which is smaller and has no desktop at all. For a first project, Desktop is a reasonable choice because it gives you a fallback way to see the screen if SSH ever misbehaves; Lite works equally well for everything in this project if you are already comfortable working entirely from the command line.
- Click 'Choose Storage' and select your microSD card. Double-check you have the right drive - this step overwrites everything on it.
- Click 'Next'. Imager will ask if you would like to apply OS customisation settings. Choose to edit settings (the exact wording and icon - sometimes a gear, sometimes a prompt - varies slightly between Imager versions).
In the customisation screen, set the following. These fields are typically split across a 'General' tab and a 'Services' tab in current versions of Imager:
- Hostname: something memorable and specific to this project, for example doorstep-greeter. You will use this to reach the Pi on your network as doorstep-greeter.local
- Username and password: set a real username (do not rely on the old default 'pi' account, which newer Raspberry Pi OS versions no longer create automatically) and a password you will remember - you will need it for SSH and for any sudo command
- Enable SSH: tick this, and choose 'Use password authentication' for simplicity now; you can switch to key-based authentication later once the project is further along
- Configure wireless LAN: enter your Wi-Fi network name and password if the Pi will connect over Wi-Fi, and set the correct wireless LAN country so the Pi uses the right radio regulations for your region
- Set locale settings: choose your time zone and keyboard layout
Save the settings, confirm you want to write the image, and let it run. Writing and verifying a 32 GB card typically takes somewhere in the range of five to fifteen minutes depending on the speed of your card, your card reader and your computer - treat that as a rough guide rather than a guarantee, since card speeds vary a great deal. When it finishes, Imager will tell you it is safe to remove the card. Eject it properly rather than just pulling it out, to avoid corrupting the write.
A note on Raspberry Pi OS editions
If you are unsure whether to pick Desktop or Lite, remember that this project is ultimately meant to run unattended at your front door with no screen attached. Everything you build across this series works over SSH and, from part 12 onward, through a small web dashboard viewed from your own computer or phone. The desktop environment is a convenience for you while developing, not something the finished greeter needs. Either edition will work for every step in this guide.
Step 2: First boot and connecting over SSH
Insert the freshly written microSD card into the Raspberry Pi 5's card slot (on the underside of the board) and connect the power supply. The Pi will take roughly thirty to ninety seconds to boot on first start, slightly longer than later boots, because it is expanding the filesystem to use the full size of your card and applying the settings you configured in Imager.
From your own computer, open a terminal (on Windows, use PowerShell or the Windows Terminal app; on macOS and Linux, use the built-in Terminal) and connect using SSH, replacing the username with whatever you set in Imager:
ssh yourusername@doorstep-greeter.local
The .local suffix relies on a network discovery feature (mDNS, often called Bonjour or Avahi depending on the operating system) that is usually enabled by default on recent versions of Windows, macOS and Linux. If this does not resolve, find the Pi's IP address instead - either check your router's list of connected devices, or if you used the Desktop image and have a monitor handy, open a terminal on the Pi itself and run 'hostname -I'. Then connect with 'ssh yourusername@192.168.x.x' using that address.
The first time you connect, SSH will show a fingerprint and ask whether to continue connecting. This is normal for a first connection to a new machine - type yes and press enter. You will then be asked for the password you set in Imager. Once you are in, you have a command prompt on the Pi itself, running over the network.
The first thing to do on any freshly flashed Pi is bring the software up to date:
sudo apt update
sudo apt full-upgrade -y
sudo reboot
'apt update' refreshes the list of available package versions; it does not install anything by itself. 'apt full-upgrade' then installs the newer versions, including security patches and firmware updates relevant to the Pi 5. This can take several minutes on a first run since a freshly imaged system is often a few weeks or months behind. The reboot at the end makes sure any updated kernel or firmware is actually in use. After the reboot, wait about thirty seconds and reconnect with the same ssh command as before.
Do you need to enable the camera in raspi-config?
On older Raspberry Pi OS releases (Buster and earlier), you had to explicitly enable the camera interface through 'sudo raspi-config'. On current Raspberry Pi OS releases, camera support goes through the libcamera stack and the camera is detected automatically once it is physically connected and the Pi has been rebooted - there is no separate toggle to switch on. You will still use 'sudo raspi-config' later in this project (for example, to adjust locale settings or boot behaviour), but you do not need it to get the camera recognised on the software you are using here.
Step 3: Connect the Camera Module 3
Power off the Pi completely before connecting or disconnecting the camera ribbon cable. The connector is not designed to be hot-plugged, and doing so risks damaging either the camera or the Pi's camera port.
sudo poweroff
Wait for the green activity light to stop flashing, then unplug the power supply. The Raspberry Pi 5 has two camera and display connectors on the board, usually labelled something like CAM/DISP0 and CAM/DISP1 near the ports - check the silkscreen printing on your specific board, since exact labelling can vary slightly between revisions. Either port works for this project; pick one and make a note of which one you used, since you may need to refer to it again when configuring software later.
- Gently lift the small plastic clip on the chosen camera port. It usually hinges upward and should move with light pressure; do not force it.
- Take the ribbon cable that came with your Camera Module 3. Check the quick-start guide that shipped in the box for the correct orientation of the contacts relative to the port, since this can differ depending on which cable variant you have and which end you are inserting into the Pi versus the camera.
- Insert the ribbon cable into the port so the exposed metal contacts face the correct way, and push it in evenly until it is seated as far as it will comfortably go.
- Push the plastic clip back down to lock the cable in place. It should feel secure, not loose.
- Repeat at the camera module end if it is not already attached, checking the same orientation guidance for that connector.
A note on the Raspberry Pi 5's connectors: they use a smaller connector design than earlier Raspberry Pi boards (the Pi 4, Pi 3 and Zero family use a larger connector). If you bought the Camera Module 3 bundled as part of a Raspberry Pi 5 kit, it will typically include a cable already suited to the Pi 5. If you are reusing a cable from an older Pi project, check whether you need an adapter cable before assuming it will fit - consult the documentation that came with your specific camera and cable combination rather than guessing, since getting this wrong by forcing a cable risks bending pins.
Once the cable is seated at both ends, reconnect the power supply to boot the Pi, and reconnect over SSH once it is up.
Step 4: Test the camera from the command line
Raspberry Pi OS includes command-line tools for testing a camera without writing any code. On current releases these are named rpicam-hello, rpicam-still and rpicam-vid; on slightly older releases, the same tools were named libcamera-hello, libcamera-still and libcamera-vid, since Raspberry Pi renamed this toolset after some earlier releases shipped. If one set of names does not work, try the other before assuming something is broken.
First, check that the Pi can see the camera at all:
rpicam-hello --list-cameras
If the camera is connected correctly, this prints a short description including the sensor name (for the Camera Module 3, you should see a reference to the imx708 sensor) and the resolutions and pixel formats it supports. If instead you see a message saying no cameras were detected, go back and check the ribbon cable orientation and seating at both ends, make sure the Pi was fully powered off when you connected it, and confirm you have rebooted since connecting it.
Because this guide assumes a headless setup with no monitor attached to the Pi, a live preview window is not useful here (rpicam-hello normally opens a preview window on a display connected to the Pi itself, not on your laptop screen over SSH). Instead, capture a still image to a file and copy it to your own computer to look at:
rpicam-still -o test.jpg --timeout 2000
This captures a single still photo after a two-second delay (2000 milliseconds) to let the automatic exposure and white balance settle, and saves it as test.jpg in your current directory. A typical JPEG at the camera's default still resolution is usually somewhere from a few hundred kilobytes to a couple of megabytes depending on how much detail is in the scene - exact size varies and is not something to worry about at this stage. From your own computer, copy the file off the Pi to view it:
scp yourusername@doorstep-greeter.local:~/test.jpg .
Run that command from your own computer, not over the SSH session into the Pi - it copies a file from the Pi to wherever you run it. Open test.jpg with whatever image viewer you normally use. Point the camera at yourself or an everyday object for this test; there is no reason to aim it out of a window at this stage, and doing so would mean capturing images of your street before you have even reached the parts of this series that talk about where the camera will actually point and what the law expects of you (covered in part 1).
If the commands are not found
If 'rpicam-hello' reports 'command not found', try 'libcamera-hello' instead - you are likely on a slightly older Raspberry Pi OS release where the tools kept their original name. If neither is found, the camera utilities may not be installed; run 'sudo apt install rpicam-apps' (or 'libcamera-apps' on older releases) and try again. On a standard Raspberry Pi OS image these should already be present, so needing to install them manually is unusual and worth double-checking you flashed the image you intended.
Step 5: Build the Python environment
Check the Python version that came with your OS image:
python3 --version
On Raspberry Pi OS Bookworm this should report Python 3.11.x. If you see an older version, you are likely on an older OS release; consider reflashing with a current image before continuing, since some libraries used later in this series expect Python 3.11 or newer.
Before installing anything with pip, there is a detail worth understanding rather than working around blindly. Recent versions of Raspberry Pi OS (and Debian, which it is based on) protect the system-wide Python installation from being modified by pip directly. If you try to run a plain 'pip install' on the system Python, you will see an error mentioning an 'externally managed environment'. This is deliberate: it stops pip-installed packages from silently breaking tools the operating system itself depends on. The standard fix, and good practice generally, is to use a virtual environment - an isolated copy of Python with its own set of installed packages that cannot interfere with the system.
There is one wrinkle specific to this project: picamera2, the camera library, is installed as a system package (via apt) because it depends on lower-level libraries (libcamera and its Python bindings) that are not straightforward to install with pip. A completely isolated virtual environment would not be able to see picamera2 at all. The fix is to create the virtual environment with access to the system's installed packages, using the '--system-site-packages' flag, so picamera2 remains visible inside the environment while packages you install yourself (OpenCV, and later a face recognition library) stay isolated.
python3 -m venv --system-site-packages ~/greeter-env
source ~/greeter-env/bin/activate
The first line creates the virtual environment in a folder called greeter-env in your home directory. The second line activates it for your current terminal session - you will know it worked because your command prompt now shows '(greeter-env)' at the start of the line. You need to run that 'source' command again every time you open a new terminal session and want to work on this project; it does not persist automatically. Deactivating, if you ever need to, is done with the plain command 'deactivate'.
With the environment active, install the two libraries this part needs. picamera2 is already available through the system site packages, so it is not listed here - you do not pip-install it on Raspberry Pi OS.
pip install opencv-python numpy
opencv-python is the Python package that provides OpenCV, the computer vision library this project uses from part 5 onward for tasks like drawing boxes around detected faces and handling image arrays. NumPy is the array library that both OpenCV and picamera2 use under the hood to represent images as grids of numbers; you will use it directly in a moment. On a Raspberry Pi, pip typically fetches pre-built wheels for the ARM architecture from the piwheels project, a community mirror that builds Python packages specifically for Raspberry Pi, so this should complete in a minute or two without needing to compile anything from source. If it does start compiling from source, something is unusual about your setup - check that you are using a 64-bit OS image as specified earlier, since pre-built wheels are generally more available for the 64-bit architecture.
It is worth keeping a record of exactly what you installed, so you or anyone else can recreate this environment later. Create a file called requirements.txt:
opencv-python
numpy
This file deliberately leaves out exact version numbers for now. Pinning versions (writing something like 'opencv-python==4.9.0.80') makes an environment fully reproducible, but the exact current version on PyPI changes over time and pinning a number here risks it being wrong or outdated by the time you read this. If you want reproducibility for your own setup, run 'pip freeze > requirements.txt' after installing, which captures the exact versions you actually have installed on your machine, right now. Later parts of this series will add more lines to this file as you install a face recognition library, a text-to-speech engine and a web framework.
Step 6: First scripts - capture a photo and a frame array
You now have a working camera and a Python environment that can see both picamera2 and OpenCV. The next step is to prove that from Python itself, not just from command-line tools. Create a file called capture_photo.py with the following content, using a text editor on the Pi such as nano, or editing it on your own computer and copying it over with scp.
"""capture_photo.py
Capture a single photo with the Raspberry Pi Camera Module 3 and save it
to disk. This is a smoke test: if this script runs without errors and
produces a reasonable-looking JPEG, the camera and picamera2 are both
working correctly from Python.
Tested against the picamera2 version bundled with Raspberry Pi OS
Bookworm (64-bit) and Python 3.11. Run inside the greeter-env virtual
environment created earlier.
"""
import time
from datetime import datetime
from picamera2 import Picamera2
picam2 = Picamera2()
# A still-capture configuration tuned for a doorstep camera: enough
# resolution to make out a face a few metres away, without producing
# unnecessarily large files.
config = picam2.create_still_configuration(main={"size": (1920, 1080)})
picam2.configure(config)
picam2.start()
time.sleep(2) # let auto-exposure and auto-white-balance settle
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
filename = f"test-{timestamp}.jpg"
picam2.capture_file(filename)
picam2.stop()
print(f"Saved {filename}")
Run it with the virtual environment active:
python3 capture_photo.py
Walking through what this does: 'Picamera2()' creates a handle to the camera hardware. 'create_still_configuration' builds a configuration dictionary describing how you want to capture - here, a single still image at 1920 by 1080 pixels, which is high resolution enough to recognise a face clearly in later parts without being excessive. 'picam2.configure(config)' applies that configuration to the hardware. 'picam2.start()' begins streaming from the sensor, and the two-second sleep that follows gives the camera's automatic exposure and white balance algorithms time to settle on reasonable values - skipping this often produces a first frame that is too dark, too bright, or has an odd colour cast. 'capture_file' takes a photo and writes it straight to a JPEG file on disk. 'picam2.stop()' releases the camera cleanly, which matters because only one process can hold the camera at a time, and a camera left open by a crashed script can block later scripts from using it until the Pi is rebooted or the process is killed.
You should see output similar to 'Saved test-20240115-093045.jpg' and a new JPEG file in your current directory. Copy it to your own computer with scp as before and check it looks like a reasonable photo, not black, not garbled.
The script above writes a file to disk, which is fine for a one-off test but not how the rest of this project will work. From part 5 onward, frames need to go straight into a face detector as arrays of numbers, without a disk round-trip for every single frame - a doorstep camera checking several times a second cannot afford to write and reread a JPEG file each time. The following script captures a frame directly as a NumPy array, which is exactly the shape of input OpenCV and the face detection libraries in later parts expect.
"""capture_frame_array.py
Capture a single frame as a NumPy array, the format the rest of this
project will use from part 5 onward, and save it with OpenCV so you can
check the colours look correct.
"""
import time
import cv2
from picamera2 import Picamera2
picam2 = Picamera2()
# A lower-resolution preview configuration: fast to capture, which
# matters once we are grabbing several frames a second in part 5.
config = picam2.create_preview_configuration(
main={"size": (640, 480), "format": "RGB888"}
)
picam2.configure(config)
picam2.start()
time.sleep(2)
frame = picam2.capture_array()
print("Frame shape:", frame.shape) # expect (480, 640, 3)
print("Frame dtype:", frame.dtype) # expect uint8
cv2.imwrite("frame.jpg", frame)
print("Saved frame.jpg")
picam2.stop()
Run it the same way: 'python3 capture_frame_array.py'. The printed shape should read (480, 640, 3): 480 rows, 640 columns, and 3 colour channels per pixel, which is exactly the shape OpenCV functions expect. The dtype should be uint8, meaning each colour value is stored as a whole number from 0 to 255.
There is a quirk worth knowing about here rather than discovering by accident later. picamera2's format names describe how pixel data is laid out, and despite the name 'RGB888' suggesting red-green-blue order, in practice this format is commonly arranged in blue-green-red order in memory on many picamera2 versions - which happens to match what OpenCV expects by default, so images saved with cv2.imwrite come out looking correct without any extra colour-channel swapping. This detail has been known to change in behaviour or documentation wording across picamera2 releases, so treat it as something to verify rather than take on faith: if a saved photo from your own code looks like it has red and blue swapped (skin tones look blue, a red object looks blue), that is the symptom, and the fix is either to request the 'BGR888' format name explicitly or to add a 'cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)' conversion before saving or displaying. Check the output of the test script above against a real photo of something with known colours - your own face, a red mug - before trusting it blindly in later parts.
Step 7: A checklist script to confirm everything works
Rather than relying on scattered manual checks, it is worth having one script you can run at the end of this part - and again at the start of part 5 if anything seems off - that checks every piece this project depends on so far and reports clearly what is and is not working.
"""check_setup.py
Run this after finishing the setup steps in this part to confirm the Pi
is ready for the next part of the project. It does not do any face
recognition - it only checks that the building blocks are present and
working: Python version, OpenCV, NumPy, picamera2 and the camera itself.
"""
import sys
print("== Doorstep Greeter: setup check ==\n")
# 1. Python version
major, minor = sys.version_info[:2]
print(f"Python version: {major}.{minor}")
if (major, minor) < (3, 11):
print(" WARNING: this project assumes Python 3.11 or later.")
else:
print(" OK")
# 2. OpenCV
try:
import cv2
print(f"OpenCV version: {cv2.__version__}")
print(" OK")
except ImportError:
print("OpenCV: NOT FOUND - run 'pip install opencv-python' inside your virtual environment")
# 3. NumPy
try:
import numpy
print(f"NumPy version: {numpy.__version__}")
print(" OK")
except ImportError:
print("NumPy: NOT FOUND - run 'pip install numpy' inside your virtual environment")
# 4. Picamera2 and the camera itself
try:
from picamera2 import Picamera2
cameras = Picamera2.global_camera_info()
if cameras:
print(f"Camera(s) detected: {len(cameras)}")
for cam in cameras:
print(f" - {cam}")
print(" OK")
else:
print("Picamera2 imported but no camera was detected.")
print(" Check the ribbon cable at both ends, and that the Pi has")
print(" been rebooted since connecting it.")
except ImportError:
print("Picamera2: NOT FOUND - this should be pre-installed on Raspberry Pi OS Bookworm.")
print(" Make sure your virtual environment was created with --system-site-packages.")
except Exception as e:
print(f"Picamera2 error: {e}")
print("\nIf every line above says OK, you are ready for the next part.")
Run it with 'python3 check_setup.py' inside the activated virtual environment. If you see 'OK' after every check, you are genuinely ready to move on to part 5. If picamera2 imports but no camera is detected, that specifically points to a physical connection problem rather than a software one, since the library loaded correctly but found nothing attached - revisit step 3. If picamera2 fails to import at all and you are sure you created the virtual environment with '--system-site-packages', double check by running 'python3 -c "import picamera2"' with the system Python directly (outside the virtual environment, i.e. without having run the 'source' activation command) to confirm it is genuinely installed at the system level.
Keeping the Pi reachable for the rest of this project
You will come back to this Pi over SSH repeatedly across the next several parts, so it is worth spending a couple of minutes now making sure it stays easy to find on your network. Most home routers hand out IP addresses dynamically and can, in principle, assign the Pi a different address after a reboot or after being off the network for a while, which would break a connection script that hardcodes an IP address. The hostname-based approach used throughout this guide ('doorstep-greeter.local') sidesteps that problem, since it resolves to whatever address the Pi currently has, so there is no strict need to set up a fixed IP address for this project to work. If your router supports it, you can optionally reserve a fixed address for the Pi's network hardware address (often called a DHCP reservation) through your router's admin page, which some people find more predictable for remote-access setups, but it is not required for anything in this series.
One habit worth starting now: keep a short note (a text file on your own computer is fine) of the hostname, the username you created, and which camera port you used. It sounds trivial, but across a project with this many parts, re-deriving small facts like this from memory each time wastes time you could spend on the interesting parts.
A word about the AI accelerator board
If you fitted the Raspberry Pi AI HAT+ chosen in part 2, this is a good point to physically confirm it is seated correctly on the GPIO header and, where applicable, connected to the board's PCIe connector, following the instructions that came in its box - different revisions of the HAT and the Pi 5's own PCIe connector have specific seating and cable requirements that are safer to follow from the printed guide than from a general description here. You do not need to install its drivers or runtime yet. This project does not need the accelerator until part 6, when you start running face embedding models and want them to run faster and with less load on the Pi's CPU than running everything in plain software. Installing accelerator drivers now, before you have anything that uses them, adds a step you would have to debug in isolation with nothing to show for it; it is simpler to install them in part 6 alongside the first script that actually exercises the hardware, so that if something goes wrong you have an immediate, concrete test of whether it is fixed.
If you chose the Jetson Orin Nano alternative instead, its GPU is built into the board itself rather than being a separate HAT, so there is no equivalent physical attachment step - NVIDIA's JetPack image includes the GPU drivers from the start. The same principle applies, though: you do not need to do anything accelerator-specific until part 6 introduces the workload that benefits from it.
Troubleshooting
- pip reports an 'externally managed environment' error: you are trying to pip install outside a virtual environment. Activate your virtual environment first with 'source ~/greeter-env/bin/activate', which you can tell is active because your prompt shows '(greeter-env)'.
- 'ModuleNotFoundError: No module named picamera2' inside your virtual environment: the environment was likely created without system site packages. Delete it ('rm -rf ~/greeter-env') and recreate it with 'python3 -m venv --system-site-packages ~/greeter-env' exactly as shown in step 5.
- rpicam-hello says no cameras were detected: power off the Pi fully, re-seat the ribbon cable at both ends checking it is pushed in evenly and the locking clip is fully down, confirm orientation against the guide that shipped with your specific camera and cable, then reboot.
- SSH connection refused or times out: confirm SSH was enabled in the Imager customisation screen before you flashed the card (reflash if unsure), check the Pi is actually powered on and has had time to fully boot, and try connecting with the Pi's numeric IP address instead of its hostname in case mDNS resolution is not working on your network.
- The Pi behaves erratically, randomly reboots, or the desktop shows a lightning-bolt icon: this is almost always an underpowered supply. Run 'vcgencmd get_throttled' in a terminal on the Pi; a result other than '0x0' indicates the Pi has detected undervoltage or thermal throttling at some point since boot. Use the official Raspberry Pi 5 power supply, as recommended in part 2, rather than a generic phone charger.
- A saved photo looks like it has swapped red and blue colours: this is the RGB888/BGR888 naming quirk described earlier in step 6. Try the other format name, or add an explicit colour conversion with OpenCV.
- The Pi cannot find the microSD card, or Imager fails partway through writing: try a different card reader or USB port, and consider trying a different microSD card - cheap or very old cards sometimes fail silently during a write.
Responsible setup from day one
Part 1 covered the rules around filming people at your door in general terms, including considerations under data protection law such as GDPR in the UK and the EU, and state-level laws such as Illinois' BIPA in the United States that specifically cover biometric data like face measurements. None of that changes at this stage, because this part does not yet process or store any face data at all - you have only captured a handful of test photographs of yourself or an object on your desk, for your own debugging purposes.
Even so, it is worth building the right habits before the project gets more capable than a camera that saves a JPEG when you tell it to. Delete the test photos you made in this part once you have confirmed they look correct - there is no reason to keep random snapshots of yourself lying around in a home directory, and it costs nothing to clear them out now. When you eventually point this camera at your actual doorstep, you will want a sign telling visitors a camera is in use (as discussed in part 1), and you will want the camera's field of view to avoid capturing a public pavement or a neighbour's property more than is reasonably necessary - but that is a concern for when the camera is actually mounted outdoors, which is covered in part 12. For now, keep testing indoors, pointed at yourself, a wall, or an object, not out of a window.
Summary and what's next
You now have a Raspberry Pi 5 running an up-to-date Raspberry Pi OS (64-bit), reachable over SSH by hostname, with a Camera Module 3 physically connected and confirmed working both from the command line and from Python. You have a virtual environment - created with access to system site packages so it can see picamera2 - with OpenCV and NumPy installed inside it, and a small checklist script that verifies all of this in one go. Most importantly for what comes next, you have proven that you can pull a single camera frame into a NumPy array of shape (480, 640, 3) with uint8 values, which is exactly the input format that face detection expects.
Part 5 picks up from exactly this point: instead of capturing one still frame and stopping, it runs a continuous loop pulling frames from the camera, passes each one to a face detector, and draws a box around any face it finds, so you can watch the detector work in something close to real time. Nothing you set up here changes - the same picamera2 capture call, the same virtual environment, the same NumPy array shape - part 5 simply does something with the frames beyond saving them to disk.
Comments (0)
No comments yet. Be the first to share your thoughts.