KevsRobots Learning Platform
66% Percent Complete
By Kevin McAleer, 8 Minutes
Now that you have a trained model in ONNX format, let’s deploy it to the Raspberry Pi AI Camera! This lesson covers transferring your model, installing dependencies, converting for IMX500 hardware, and running your first inference on the Pi.
By the end of this lesson, you will:
Before starting:
Running object detection on the Raspberry Pi (edge device) instead of the cloud offers huge advantages:
Benefits of edge deployment:
Real-world uses:
First, get your ONNX model onto the Pi.
From your computer’s terminal:
# Replace 'raspberrypi.local' with your Pi's hostname or IP address
scp custom_detector.onnx [email protected]:~/models/
# You'll be prompted for the Pi's password
Can’t find your Pi’s address?
# On the Pi, run:
hostname -I
# Or use:
ping raspberrypi.local
custom_detector.onnx to a USB drive# Find the USB drive
lsblk
# Mount if needed (usually auto-mounts to /media/pi/)
sudo mount /dev/sda1 /mnt
# Copy the model
mkdir -p ~/models
cp /media/pi/YOUR_USB_NAME/custom_detector.onnx ~/models/
# Verify it copied
ls -lh ~/models/custom_detector.onnx
If your model is hosted somewhere:
mkdir -p ~/models
cd ~/models
wget https://your-server.com/custom_detector.onnx
On your Raspberry Pi, install the required tools:
# Update package list (important!)
sudo apt update
# Install IMX500 tools and Python bindings
sudo apt install -y imx500-tools python3-imx500-tools
# Install additional Python packages
sudo apt install -y python3-picamera2 python3-opencv python3-numpy
# Verify installation
imx500-package.sh --version
Expected output:
imx500-package version 1.0.2
If installation fails: Make sure you’re on the latest Raspberry Pi OS:
sudo apt update
sudo apt full-upgrade -y
sudo reboot
The IMX500 sensor has its own neural processor. Convert your model to its optimized format:
# Navigate to your models directory
cd ~/models
# Convert ONNX to IMX500 format (.rpk file)
imx500-package.sh -i custom_detector.onnx -o detector_imx500
# This takes 2-5 minutes depending on model size
What’s happening:
.rpk (Raspberry Pi Package) fileExpected output:
Processing custom_detector.onnx...
Analyzing model structure...
Converting layers to IMX500 format...
Quantizing weights...
✓ Conversion successful
✓ Created detector_imx500/network.rpk
✓ Model size: 12.3 MB (reduced from 45.3 MB)
Check the output:
ls -lh detector_imx500/
You should see:
network.rpk - The converted modellabels.txt - Class names (if you provided them)metadata.json - Model configurationMake sure your AI Camera is properly connected:
# List available cameras
libcamera-still --list-cameras
# Should show the IMX500 camera
Expected output:
Available cameras:
0 : imx500 [4056x3040] (/base/axi/pcie@120000/rp1/i2c@88000/imx500@1a)
If camera not found:
sudo raspi-config
# Navigate to: Interface Options → Camera → Enable
# Reboot: sudo reboot
vcgencmd get_camera
# Should return: detected=1
Take a test photo to verify everything works:
# Capture a still image
libcamera-still -o test.jpg --width 640 --height 480
# View the file
ls -lh test.jpg
If successful, you’ll have a test.jpg file. Transfer it to your computer to view:
# On your computer:
scp [email protected]:~/test.jpg ./
Now let’s run your model on a test image:
# test_deployment.py
from picamera2 import Picamera2
from picamera2.devices.imx500 import IMX500
import numpy as np
import time
print("Initializing camera and model...")
# Initialize camera
picam2 = Picamera2()
# Load IMX500 model
imx500 = IMX500(picam2)
imx500.load_network("/home/pi/models/detector_imx500/network.rpk")
# Configure camera
config = picam2.create_still_configuration()
picam2.configure(config)
picam2.start()
print("✓ Camera initialized")
print("✓ Model loaded")
# Capture and process
print("\nCapturing image...")
start_time = time.time()
image = picam2.capture_array()
print(f"✓ Image captured: {image.shape}")
# Run inference
results = imx500.get_inference_result()
inference_time = (time.time() - start_time) * 1000
print(f"✓ Inference complete in {inference_time:.1f} ms")
# Print detections
if results and len(results['boxes']) > 0:
print(f"\nDetected {len(results['boxes'])} objects:")
for i, (box, label, score) in enumerate(zip(
results['boxes'],
results['labels'],
results['scores']
)):
if score > 0.5: # Confidence threshold
print(f" {i+1}. Class {label}: {score:.2f} - {box}")
else:
print("\nNo objects detected")
picam2.stop()
print("\n✓ Test complete!")
Run it:
python3 test_deployment.py
Expected output:
Initializing camera and model...
✓ Camera initialized
✓ Model loaded
Capturing image...
✓ Image captured: (480, 640, 3)
✓ Inference complete in 45.3 ms
Detected 2 objects:
1. Class 1: 0.92 - [120, 80, 340, 420]
2. Class 2: 0.78 - [400, 150, 580, 380]
✓ Test complete!
On Raspberry Pi 5 with AI Camera:
| Metric | Value | Notes |
|---|---|---|
| Inference speed | 10-30 FPS | Depends on model complexity |
| Latency | 30-100ms | Per frame processing |
| Power consumption | ~5W | Total system power |
| Accuracy | Same as validation | Should match your test set results |
| Startup time | 2-3 seconds | Model loading time |
Raspberry Pi 4 will be slightly slower (~20-50% depending on model).
Challenge: Create a script that automatically takes a photo when it detects your target object.
Problem: “imx500-tools: command not found”
Solution: Update OS: sudo apt update && sudo apt full-upgrade, then reinstall
Why: IMX500 support is recent, requires latest Raspberry Pi OS (Bookworm or newer)
Problem: “Conversion failed: unsupported operator” Solution: Some PyTorch operations aren’t supported by IMX500. Simplify your model Why: Edge hardware has limited operator support compared to full PyTorch
Problem: “Camera not detected”
Solution: Check cable connection, run sudo raspi-config and enable camera, reboot
Why: Camera interface needs to be enabled in system configuration
Problem: Model loads but gets no detections Solution: Check class mappings, verify confidence threshold isn’t too high, test on training images first Why: Mismatched class indices or overly strict filtering
Problem: “Permission denied” when accessing camera
Solution: Add user to video group: sudo usermod -a -G video $USER, then logout/login
Why: Camera devices require video group membership
Problem: Very slow inference (>500ms) Solution: Verify model was converted to .rpk format, check you’re using IMX500 not CPU inference Why: ONNX model runs on CPU, .rpk runs on dedicated neural processor
Before moving to the next lesson:
You’ve learned:
Your model is now running on the edge! In the next lesson, you’ll build a complete real-time detection application.
In the next lesson, you’ll build a real-time object detection application with live camera feed, bounding box visualization, and performance monitoring.
You can use the arrows ← → on your keyboard to navigate between lessons.
Comments