Build a Robot That Can
Read Road Signs
Teach a Raspberry Pi to look through a camera and recognise real traffic signs using AI — the same idea behind self-driving cars, made small enough to fit on your desk. 🚦
What Are We Actually Building?
Every self-driving car on the road has to do one very important thing: look at road signs and understand what they mean. In this project, you'll build a miniature version of that exact system using a Raspberry Pi — a tiny computer the size of a credit card — and a small camera module.
The robot will:
- Capture a live video feed using the Pi Camera
- Run an AI model on every frame that looks for road signs
- Identify what kind of sign it sees (Stop, Speed Limit, Yield, etc.)
- Print or speak the sign name out loud in real time
This is called computer vision — where a computer "sees" the world and figures out what's in a picture. Once you understand the idea, you'll see it everywhere: in your phone's face unlock, in supermarket checkouts, in hospital scanners, and yes — in self-driving cars.
How Does AI "See" a Road Sign?
Your eyes send pictures to your brain, your brain compares them to everything you've learned, and — snap — you know it's a stop sign. AI does something similar, but using maths instead of a brain. Here's the journey from lens to label:
1. Camera
Pi Cam captures 30 frames per second of whatever is in front of it
›2. Detect
OpenCV scans for sign-shaped regions — red octagons, triangles, blue circles
›3. Classify
A pre-trained AI model inspects the region and picks the most likely sign label
›4. Output
The Pi draws a box on screen, prints the sign name, and can speak it aloud
›5. Repeat
This whole loop runs 10–15 times every second
The Three Big Ideas Your Robot Uses
Computer Vision
The ability for a computer to understand pictures and video — find objects, shapes, colours, and patterns in pixels.
Convolutional Neural Network
The type of AI model used. It was trained by looking at thousands of road sign photos until it learned to spot them reliably.
Edge AI
Running the AI directly on the small Pi chip — no internet needed. The same idea powers smart speakers and phone cameras.
Parts Checklist
Everything here is beginner-friendly and available from online electronics shops or well-stocked hobby stores.
Raspberry Pi 4 (2GB+)
The brain. Runs Python, OpenCV, and the AI model all at once.
Raspberry Pi Camera Module v2
The eyes. Connects directly to the Pi via a flat ribbon cable.
16 GB MicroSD Card (Class 10)
Stores Raspberry Pi OS and all the AI code and model files.
Pi 4 Power Supply (USB-C 5V/3A)
Official adapter recommended — underpowered supplies cause odd crashes.
Small LED + 220Ω Resistors (×3)
Red, yellow, green LEDs to light up when each sign type is spotted.
Mini Breadboard + Jumper Wires
For wiring up the indicator LEDs without soldering.
Tiny HDMI Display or SSH Setup
Either a small display to see the camera feed, or a laptop to connect wirelessly via SSH.
Small USB Speaker
Lets the Pi say the sign name out loud using Python's text-to-speech library.
GTSRB Dataset (model training)
Over 50,000 real road sign photos used to train the AI — free from the internet.
Circuit Wiring Diagram
The camera connects directly to the Pi via its ribbon cable (no breadboard needed). The LEDs on the breadboard give a physical light indicator when each sign type is detected.
Each LED has a 220Ω resistor in series to limit current. The Pi Camera uses the flat CSI ribbon cable that plugs into the dedicated camera port (NOT the USB ports) on the Pi. All LED cathodes (short leg) connect to a shared ground rail back to Pi GND pin.
Setting Up Your Raspberry Pi
Flash the MicroSD Card
Download Raspberry Pi Imager on your laptop, choose Raspberry Pi OS (64-bit), select your SD card, and click Write. When it's done, pop the card into the Pi.
Enable the Camera
- Boot the Pi and open a Terminal (or SSH in from your laptop).
- Type
sudo raspi-config→ Interface Options → Camera → Enable. - Reboot the Pi.
- Test it: type
libcamera-still -o test.jpgand check that a photo appears.
Install the Libraries
Open the terminal and run these commands one by one (each one downloads a tool the AI code needs):
# Update the Pi's software list first sudo apt update && sudo apt upgrade -y # Install OpenCV (computer vision), TFLite (AI), and GPIO tools pip3 install opencv-python tflite-runtime RPi.GPIO pyttsx3 # Install picamera2 (the modern Pi Camera driver) sudo apt install -y python3-picamera2
Step-by-Step Build (6 Steps)
Connect the Pi Camera
Locate the CSI camera port on the Raspberry Pi — it's a thin black slot near the USB ports with a small plastic clip.
- Gently pull up the black clip on the CSI port.
- Slide the flat ribbon cable in with the blue side facing the USB ports.
- Push the clip back down firmly until it clicks.
Wire Up the LEDs
Use your breadboard and jumper wires to build the LED indicator circuit from the diagram above:
- Push a 220Ω resistor into the breadboard for each LED.
- Connect the anode (long leg) of each LED after its resistor.
- Connect the cathode (short leg) of all LEDs to the ground rail.
- Connect jumper wires from Pi GPIO 17, 27, 22 to the input side of each resistor.
- Connect a jumper from Pi GND (Pin 6) to the ground rail on the breadboard.
Mount the Camera
Position the Pi Camera so it has a clear, unobstructed view in front of it. You can:
- Tape or rubber-band it to a small cardboard stand
- Use a 3D-printed Pi Camera mount (many free designs online)
- Clip it to the inside of a project box with a hole cut in the front
Aim for a comfortable working height — about 20–30 cm off the desk works well for reading printed sign cards in front of it.
Download the AI Model
We'll use a lightweight pre-trained model from TensorFlow Lite that was trained on the GTSRB road sign dataset. In the Terminal:
# Make a folder for the project mkdir ~/roadsign-reader && cd ~/roadsign-reader # Download a lightweight TFLite model trained on road signs wget -O sign_model.tflite \ https://storage.googleapis.com/download.tensorflow.org/models/tflite/task_library/image_classification/android/mobilenet_v1_1.0_224_quant.tflite # You can also copy your own trained model here later!
scp.Create the Code File
In the Terminal, type nano ~/roadsign-reader/reader.py and paste in the Mission Code from the next section. Save with Ctrl+X → Y → Enter.
Make Some Test Signs
Print or draw some road sign cards on paper — at least one Stop sign (red octagon with STOP), one Yield sign (red/yellow triangle), and one Speed Limit sign (white rectangle with numbers). Hold them in front of the camera about 20–30 cm away when testing.
The AI Road Sign Reader — Full Python Code
This script captures live video, detects sign shapes by colour, runs the AI model, lights the right LED, and optionally speaks the sign name aloud.
""" AI Road Sign Reader — Raspberry Pi + Pi Camera Detects road signs in real time and announces them! """ import cv2 import numpy as np import RPi.GPIO as GPIO import tflite_runtime.interpreter as tflite import pyttsx3 from picamera2 import Picamera2 import time # ── GPIO Setup (LEDs) ────────────────────────────────────── LED_STOP = 17 # Red LED LED_YIELD = 27 # Yellow LED LED_SPEED = 22 # Green LED GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) for pin in [LED_STOP, LED_YIELD, LED_SPEED]: GPIO.setup(pin, GPIO.OUT) GPIO.output(pin, GPIO.LOW) # ── Text-to-Speech Setup ─────────────────────────────────── engine = pyttsx3.init() engine.setProperty('rate', 140) # speaking speed last_spoken = "" def speak(text): global last_spoken if text != last_spoken: engine.say(text) engine.runAndWait() last_spoken = text # ── AI Model Setup (TFLite) ──────────────────────────────── interpreter = tflite.Interpreter(model_path="sign_model.tflite") interpreter.allocate_tensors() input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() INPUT_SIZE = input_details[0]['shape'][1] # usually 224 # Sign label names (edit this list to match YOUR trained model) SIGN_LABELS = ["Speed Limit", "Stop", "Yield", "No Entry", "Pedestrian Crossing", "Turn Left", "Turn Right"] # ── Colour Detection (HSV ranges) ───────────────────────── # Helps pre-filter frames that likely contain a road sign def contains_sign_colour(frame): hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # Red (wraps around in HSV — needs two ranges) red1 = cv2.inRange(hsv, (0,120,70), (10,255,255)) red2 = cv2.inRange(hsv, (170,120,70), (180,255,255)) # Yellow / amber yellow = cv2.inRange(hsv, (20,100,100), (35,255,255)) mask = cv2.bitwise_or(cv2.bitwise_or(red1, red2), yellow) return cv2.countNonZero(mask) > 800 # enough pixels to be interesting # ── AI Inference ─────────────────────────────────────────── def classify_sign(roi): img = cv2.resize(roi, (INPUT_SIZE, INPUT_SIZE)) img = img.astype(np.uint8)[np.newaxis, ...] interpreter.set_tensor(input_details[0]['index'], img) interpreter.invoke() scores = interpreter.get_tensor(output_details[0]['index'])[0] top_idx = int(np.argmax(scores)) confidence = scores[top_idx] / 255.0 # quant model uses 0–255 if confidence > 0.65 and top_idx < len(SIGN_LABELS): return SIGN_LABELS[top_idx], confidence return None, 0 # ── LED Control ──────────────────────────────────────────── def set_led(label): GPIO.output(LED_STOP, GPIO.HIGH if "Stop" in label else GPIO.LOW) GPIO.output(LED_YIELD, GPIO.HIGH if "Yield" in label else GPIO.LOW) GPIO.output(LED_SPEED, GPIO.HIGH if "Speed" in label else GPIO.LOW) # ── Main Loop ────────────────────────────────────────────── picam2 = Picamera2() picam2.configure(picam2.create_preview_configuration( main={"size": (640, 480)})) picam2.start() print("Road Sign Reader is running! Press Ctrl+C to stop.") try: while True: frame = picam2.capture_array() frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) label, conf = None, 0 if contains_sign_colour(frame): label, conf = classify_sign(frame) if label: # Draw result on frame cv2.rectangle(frame, (10,10), (380,60), (26,28,34), -1) cv2.putText(frame, f"{label} {conf*100:.0f}%", (18, 44), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (245,200,0), 2) set_led(label) speak(label) else: # All LEDs off if no sign seen for pin in [LED_STOP, LED_YIELD, LED_SPEED]: GPIO.output(pin, GPIO.LOW) cv2.imshow("AI Road Sign Reader", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break time.sleep(0.05) except KeyboardInterrupt: print("\nMission complete!") finally: picam2.stop() cv2.destroyAllWindows() GPIO.cleanup() print("GPIO cleaned up. Goodbye!")
python3 ~/roadsign-reader/reader.py — a window will appear showing the live camera feed with the sign label drawn on top. Press Q to quit.Running Your First Test Drive
Power On and Start the Script
Connect the USB-C power adapter. SSH in (or plug in a keyboard and display) and navigate to the project folder. Run python3 reader.py. You should see "Road Sign Reader is running!" in the terminal.
Hold Up a Stop Sign Card
Print or draw a red octagon STOP sign and hold it clearly in front of the camera. The camera feed window should show a label. The red LED should light up, and if you have a speaker, it should say "Stop"!
Try Each Sign
Test Yield and Speed Limit signs one by one. Make sure the room is well-lit — computer vision works much better under good lighting. Watch the LEDs switch with each sign type.
Record Your Results
Keep a log! For each sign, write down whether the AI got it right, how far away you were, and the lighting conditions. This is real scientific testing — just like engineers at a car company would do.
🛑 Safety Rules
- Adult supervision required for initial wiring, GPIO connections, and whenever working near powered electronics.
- Never connect or disconnect GPIO wires while the Pi is powered on — always shut it down first.
- Double-check LED polarity (long leg = +, short leg = –) before applying power.
- Don't cover the Pi or camera while running — good airflow prevents overheating.
- If the Pi feels very hot, shut it down and check that your power supply is providing a full 5V/3A.
- This is a desk demonstration project only — never use it in or near a real vehicle.
Troubleshooting
The camera window doesn't open / camera not found.
Check that the ribbon cable is fully seated in the CSI port. Then run libcamera-hello in the terminal — if it shows a preview, the camera is working. If not, re-seat the ribbon cable and ensure the camera is enabled in raspi-config.
The AI always says the same sign no matter what I show it.
The base MobileNet model used in the setup step isn't specifically trained on road signs — it's a placeholder. For accurate results, you need to download or train a model specifically on the GTSRB dataset. Try Google Colab to train one — it's free and runs in your browser.
The LEDs don't light up at all.
Check three things: (1) Are the jumper wires going to the right GPIO pin numbers (17, 27, 22)? (2) Is the ground wire connected from Pi GND to the breadboard ground rail? (3) Are the LEDs inserted in the correct direction (long leg toward the resistor)?
The Pi freezes or reboots randomly.
This is almost always an underpowered USB-C supply. The Pi 4 with camera and AI processing needs a solid 5V/3A. Cheap cables can also cause voltage drops. Use the official Raspberry Pi power supply if possible.
The text-to-speech doesn't work.
Run sudo apt install espeak and then try python3 -c "import pyttsx3; e=pyttsx3.init(); e.say('Hello'); e.runAndWait()". If no speaker is connected, pyttsx3 will throw an error — plug in a USB speaker or headphones.
Can I use a USB webcam instead of a Pi Camera?
Yes! Replace the Picamera2 section with cap = cv2.VideoCapture(0) and ret, frame = cap.read() inside the loop. The rest of the code stays the same.
Fun Facts for Your Science Log
Number of sign classes in the German GTSRB dataset — the most popular road sign training set in the world.
Accuracy the best AI models now achieve on the GTSRB test set — better than average human performance.
When early computer vision road sign research began. It took until the 2010s for AI to make it reliable.
Running AI on a small device without internet is called "edge computing" — the same technique in smart doorbells and fitness trackers.
Next Missions — What to Build Next
You've just built something real AI engineers work on every day. The same ideas power vehicles from some of the world's most advanced companies — and now you understand how they work. 🚗🤖
Comments
Post a Comment