All projects

Embedded systems · AI / 2026

Edge AI Security Camera & Cloud Alerting

A smart security camera that runs object detection locally on a Raspberry Pi 5, saving bandwidth and only alerting the cloud when it matters.

Raspberry Pi 5PythonOpenCV

The Problem with Cloud Cameras

Most smart security cameras just blindly stream video to the cloud 24/7. That eats up a massive amount of bandwidth and introduces unnecessary lag. I wanted to build something faster and more efficient, so I engineered an edge-computing camera using a Raspberry Pi 5.

Instead of sending raw video out to a server for processing, my system handles all the computer vision locally. By leveraging the YOLOv4-tiny model, the camera detects objects in real time on the device itself. It only actually pings the cloud when it confidently spots a specific target, like a person or a vehicle.

Squeezing Performance out of the Hardware

Running neural networks on a single-board computer is a balancing act. You have to carefully manage resources to keep the frame rate (FPS) smooth without thermal throttling the CPU. Here is how I made it work:

  • The Hardware: The Raspberry Pi 5 provided a massive jump in processing power over older generations. It gave me the throughput needed to continuously process frames straight from the CSI camera module.
  • The Model: I chose YOLOv4-tiny over the standard YOLO variants. Its smaller footprint and lower computational overhead make it a perfect fit for edge deployment.
  • The Acceleration: To speed things up, I used OpenCV’s Deep Neural Network (DNN) module to load the weights. By optimizing the inference loop, the system can reliably extract bounding boxes and confidence scores in real time without stuttering.
# Prepare a frame and run the YOLOv4-tiny network.
import cv2

net = cv2.dnn.readNet("yolov4-tiny.weights", "yolov4-tiny.cfg")
output_layers = net.getUnconnectedOutLayersNames()

def process_frame(frame):
    blob = cv2.dnn.blobFromImage(
        frame, 1 / 255.0, (416, 416),
        swapRB=True, crop=False
    )
    net.setInput(blob)
    return net.forward(output_layers)

This excerpt covers inference only. The network outputs still need confidence filtering, bounding-box decoding, and non-maximum suppression before they can trigger an alert.