Siddhant Kumar
Project A02 · Computer Vision

Real-Time Object Detection.

A YOLO-based detector that finds and labels many objects in a live video stream at speed — the workhorse behind almost every vision application.

Advanced 14–22 hours 26 min read YOLOVisionReal-time
Jump to source Bill of materials
Real-Time Object Detection — reference build illustration MCU VCC · GND · SIG · NC
Difficulty
Advanced
Build time
14–22 hours
Indicative cost
Software + camera; compute-dependent
Platform
GPU workstation or Jetson/Pi (edge)
Category
Computer Vision
Last updated
28 July 2026
Contents — 27 sections

Project Overview

A YOLO-based detector that finds and labels many objects in a live video stream at speed — the workhorse behind almost every vision application.

Almost every practical computer-vision application — surveillance, autonomous driving, retail analytics, robotics, quality inspection — rests on one capability: looking at an image and answering what objects are in it and where. That is object detection, and doing it in real time on a live video stream is the workhorse skill of applied vision. This project builds a real-time detector around the YOLO family (You Only Look Once), which reframed detection from a slow, multi-stage pipeline into a single fast network pass, making live detection on ordinary hardware possible.

The system takes frames from a camera or video, runs each through a trained detector, and outputs bounding boxes with class labels and confidence scores — "person 0.94 here, car 0.88 there" — drawn back onto the video live. The core ideas that make this work and make it fast are the single-pass architecture (the whole image is processed once, predicting all boxes together, rather than scanning region by region), non-maximum suppression (collapsing the many overlapping raw predictions into one clean box per object), and the speed/accuracy trade-off embodied in model size (a small model runs on a Pi at lower accuracy; a large one needs a GPU but detects more, smaller, harder objects).

The value is a reusable perception layer: once you can reliably detect and locate objects live, you can count them, track them, trigger on them, or feed them to downstream logic — which is why detection underpins so much. It is honest that a detector is only as good as its training data and classes (it detects what it was trained on, and struggles with unusual angles, small or occluded objects, and domain shift), that real-time performance depends heavily on hardware and model size, and that deployment (edge vs GPU) is a real engineering choice. But as a fast, accurate, live multi-object detector built on YOLO, it is both a genuinely useful building block and the single most important hands-on lesson in modern applied computer vision.

A schematic of a feed-forward artificial neural network
A YOLO detector finds and labels many objects in a live stream — the "what and where" workhorse of applied vision. Photograph sourced from Wikimedia Commons — Artificial neural network.svg. Reused under the licence stated on that page; please check it before republishing.

What this project does

  • Detects and labels multiple objects in a live video stream
  • Draws bounding boxes with class labels and confidence
  • Runs in a single fast network pass (YOLO)
  • Cleans overlapping predictions with non-maximum suppression
  • Trades speed vs accuracy via model size (edge to GPU)
  • Provides a reusable perception layer for counting/tracking/triggering
  • Underpins surveillance, robotics, retail and autonomous vision

Real-World Applications

SettingHow it is used
Surveillance / securityDetecting people, vehicles and objects of interest live.
Robotics / autonomyPerceiving objects for navigation and manipulation.
Retail / analyticsCounting and locating products and people.
Inspection / safetyDetecting defects, PPE, or hazards in a feed.

Deployment contexts where a build of this kind earns its keep.

Features & Capabilities

  • Real-time multi-object detection (YOLO)
  • Bounding boxes + labels + confidence
  • Single-pass architecture (fast)
  • Non-maximum suppression for clean boxes
  • Model-size speed/accuracy trade-off
  • Edge or GPU deployment
  • Honest about training-data dependence and hard cases

Difficulty, Time & Required Skills

AttributeValue
Difficulty levelAdvanced
Estimated completion time14–22 hours
Indicative build costSoftware + camera; compute-dependent
Primary disciplineComputer Vision
Reference platformGPU workstation or Jetson/Pi (edge)

Skills you should have (or will pick up)

  • Object detection concepts (boxes, classes, confidence)
  • YOLO single-pass architecture and NMS
  • Real-time inference on video (edge/GPU)
  • Speed/accuracy trade-offs via model size
  • Fine-tuning on custom classes / data

Bill of Materials

Every part below is commonly available from Indian and international hobby-electronics suppliers. Prices are indicative 2026 retail figures in Indian rupees and will drift — treat them as a budgeting guide, not a quotation.

ComponentKey specificationQtyApprox. cost
Raspberry Pi Camera Module 3
Pi 5 uses a narrower 22-pin CSI cable — the old 15-pin ribbon will not fit.
12 MP IMX708, autofocus, HDR, 1080p50, CSI-2 ribbon1₹2,600
Raspberry Pi 4 Model B (4 GB)
Use an official 5 V 3 A supply — brown-outs from phone chargers corrupt SD cards.
Quad-core Cortex-A72 @ 1.8 GHz, 4 GB LPDDR4, Gigabit Ethernet, Wi-Fi 5, BT 5.0, 2× USB 3.0, 40-pin GPIO1₹5,800
Compute (GPU or edge)
Speed/accuracy depends on this
GPU workstation for training/large models, or Jetson/Pi for edge inference1
Camera / video sourceUSB/CSI camera or video files1₹1,500
Pretrained YOLO weightsCOCO-pretrained model (fine-tune for custom classes)1
Labelled dataset (if custom)
Detects only what it is trained on
Annotated images for your classes1

Estimated total: ₹9,900, excluding tools, shipping and consumables.

Tools and consumables

  • Soldering iron (temperature controlled, 350 °C) with 0.8 mm 60/40 or lead-free solder
  • Digital multimeter — continuity, DC volts and current ranges
  • Wire strippers, flush cutters and a small set of precision screwdrivers
  • Heat-shrink tubing and a heat gun (or a lighter, carefully)
  • A laptop with a USB port and the toolchain listed above

Hardware Specifications

PartSpecificationSupplyInterfaceReference
Raspberry Pi Camera Module 312 MP IMX708, autofocus, HDR, 1080p50, CSI-2 ribbon3.3 V via CSICSI-2Datasheet
Raspberry Pi 4 Model B (4 GB)Quad-core Cortex-A72 @ 1.8 GHz, 4 GB LPDDR4, Gigabit Ethernet, Wi-Fi 5, BT 5.0, 2× USB 3.0, 40-pin GPIO5 V / 3 A USB-CGPIO, SPI, I²C, UART, CSI, DSIDatasheet

Consolidated electrical and interface specifications for every active part in the build.

Power Budget & Supply Sizing

Add up the typical active current of every part, then size the supply with at least 50 % headroom so transmit bursts and motor inrush never brown out the controller.

LoadSupply railTypical current (mA)Notes
Raspberry Pi Camera Module 33.3 V via CSI250Pi 5 uses a narrower 22-pin CSI cable — the old 15-pin ribbon will not fit.
Raspberry Pi 4 Model B (4 GB)5 V / 3 A USB-C1200Use an official 5 V 3 A supply — brown-outs from phone chargers corrupt SD cards.

Summed typical draw is 1450 mA. With a 1.5× design margin the supply should deliver at least 2200 mA continuously at the stated rail voltage.

Software Requirements & Development Environment

Reference toolchain: Python 3.11 + PyTorch / Ultralytics. Anything newer normally works; anything older may lack the board definitions used here.

  • Flash Raspberry Pi OS (64-bit) with Raspberry Pi Imager; pre-configure Wi-Fi, hostname and SSH in the Imager settings so the board comes up headless.
  • Update first: sudo apt update && sudo apt full-upgrade -y, then reboot.
  • Work inside a virtual environment — python3 -m venv ~/venv && source ~/venv/bin/activate. Bookworm blocks system-wide pip install by design.
  • Enable the buses you need with sudo raspi-config → Interface Options (I²C, SPI, Serial, Camera).
  • Develop over VS Code Remote-SSH so you edit on your laptop but run on the Pi.

Required libraries

LibraryWhy it is neededInstall
Python 3.11+Runtime for the analysis, training and service code.sudo apt install python3 python3-venv python3-pip
PyTorch 2.4+Model definition, autograd and GPU training.pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121
Ultralytics YOLO 8.3+Training and inference API for YOLOv8/v11 detectors.pip install ultralytics
OpenCV 4.10+Frame capture, colour conversion, drawing and classical CV operators.pip install opencv-python
NumPy 1.26+Vectorised array maths underpinning every other library here.pip install numpy

Block Diagram

The block diagram shows the functional decomposition of the system — what senses, what decides, what acts, and where the data ends up.

Real-Time Object Detection — system block diagramFunctional block diagram of the Real-Time Object Detection system. InputCamera/videoframesDetectYOLOsingle passRaw boxesmanyCleanNMSone/objectThresholdconfidenceUseDrawboxes+labelsDownstreamcount/trackrightrightnone
Real-Time Object Detection — system block diagram

Circuit Diagram & Wiring

This is a software vision system; the "wiring" here is the data flow — a camera or video source feeds frames to the detector, which emits boxes, labels and confidences to the display and any downstream logic.

Real-Time Object Detection — wiring schematicConnection schematic showing which controller pin drives each peripheral. Sensors / InputsControllerActuators / OutputsGPU workstation orJetson/Pi (edge)5 V / 3 A USB-CCamera / videoInput imagesDetector (YOLO)Boxes + labelsNMS + drawClean boxes on videoDownstreamCount/track/trigger
Real-Time Object Detection — wiring schematic
PeripheralPeripheral pinController pinSignal
Camera / videoframesInput images
Detector (YOLO)inferenceBoxes + labels
NMS + drawpostClean boxes on video
DownstreamAPICount/track/trigger

Wire one row at a time and tick it off — most "it does not work" reports trace back to a single swapped pair.

Wiring explanation

  • A camera or video source provides frames to the detector.
  • The detector runs a single forward pass producing raw boxes, labels and confidences.
  • Non-maximum suppression collapses overlapping boxes into one per object.
  • Clean detections are drawn on the video and/or passed to downstream logic.
  • Choose model size for your hardware: small for edge, large for GPU accuracy.
A typical convolutional neural network architecture diagram
Detection localises a variable number of objects with boxes, unlike classification which labels the whole image. Photograph sourced from Wikimedia Commons — Typical cnn.png. Reused under the licence stated on that page; please check it before republishing.

System Architecture

Read the stack from the bottom up: physical hardware, the firmware that drives it, the transport that moves data off the device, and the software a human actually looks at.

Real-Time Object Detection — architecture stackLayered architecture from hardware to user interface. Hardware layerRaspberry Pi 4 Model B (4 GB) · Raspberry Pi Camera Module 3Driver layerpython · torch · ultralytics · opencvApplication logicsampling loop · filtering · thresholds · state machinePresentation layerlocal display · serial console · logged output
Real-Time Object Detection — architecture stack

Working Principle

Object detection is harder than classification: a classifier answers "what is this image?", but a detector must answer "what objects are present and where is each one?", which means localising a variable number of objects of different sizes anywhere in the frame. Early detectors did this slowly — proposing many candidate regions and classifying each — which was far too slow for video. YOLO's insight, and the reason it dominates real-time detection, is to treat detection as a single regression through one network: the whole image goes in once, and the network predicts all bounding boxes and their class probabilities together. "You Only Look Once" is literal — one pass, not thousands of region evaluations — and that is what makes live detection feasible.

Mechanically, the network divides the image into a grid and, at each location, predicts candidate boxes (position and size), an objectness/confidence score, and class probabilities. This produces many raw, overlapping predictions for the same object, so two clean-up steps follow. A confidence threshold discards weak predictions. Then non-maximum suppression (NMS) resolves the overlaps: among boxes that overlap heavily (high intersection-over-union) and predict the same class, it keeps the highest-confidence one and suppresses the rest, yielding a single clean box per object. Understanding NMS is essential, because without it a detector reports a messy pile of duplicate boxes.

The defining engineering dial is the speed/accuracy trade-off, set largely by model size. A small model (few parameters, low input resolution) runs fast — even on a Raspberry Pi or phone — but misses small, distant, or difficult objects and is less accurate. A large model detects more and harder objects accurately but needs a GPU to run at video rates. There is no universally right choice: an edge camera doing coarse person-detection wants the small model; a GPU server doing fine retail analytics wants the large one. Input resolution, batch size, and hardware (CPU vs GPU vs dedicated accelerator) all move the same dial. Choosing the point on this curve for the application and hardware is the core deployment decision.

The honest limits are as important as the capabilities. A detector only detects what it was trained on: a COCO-pretrained YOLO knows its ~80 everyday classes and nothing else, so detecting custom objects requires fine-tuning on labelled data — and the detector is only ever as good as that data's coverage of angles, lighting, scales, and occlusion. It struggles with small, distant, or occluded objects, unusual viewpoints, and domain shift (a model trained on daytime street scenes falters at night or indoors). Real-time performance is hardware-dependent and not guaranteed. And confidence scores are not calibrated probabilities to be trusted blindly. Within those bounds, though, a YOLO-based real-time detector is the single most reusable tool in applied vision — a fast, live "what and where" layer that almost every higher-level vision system is built upon, which is exactly why learning to build, run, and tune one is foundational.

The maths behind it

Detection output

plainDetection output
For each detected object:
  box = (x, y, w, h)          # location + size
  class = argmax(class_probs)  # what it is
  confidence = objectness × class_prob

Keep only detections with confidence ≥ threshold.

Intersection over Union (IoU)

plainIntersection over Union (IoU)
IoU(A,B) = area(A ∩ B) / area(A ∪ B)

Measures box overlap (0..1). Used by NMS to find duplicates
and by evaluation (a prediction matches truth if IoU ≥ 0.5).

Non-maximum suppression

plainNon-maximum suppression
sort detections by confidence (high → low)
repeat:
  keep the top box B
  remove any remaining box with IoU(B, ·) > NMS_thr
    AND same class
→ one clean box per object.

Speed / accuracy dial

plainSpeed / accuracy dial
small model / low-res  → fast, less accurate (edge)
large model / high-res → accurate, slower (GPU)

FPS ≈ compute / (model_cost × resolution)
Choose the point for your app + hardware.

Program Flowchart

The firmware is a single cooperative loop. Nothing blocks for long, so networking, sensing and the user interface all stay responsive.

Real-Time Object Detection — firmware flowchartControl flow through the main program loop. Grab a frameYOLO forward pass → rawpredictionsFilter by confidenceNon-maximum suppressionAny detections?Draw boxes/labels + emitNext frameDraw boxes/labels + emitNext frame
Real-Time Object Detection — firmware flowchart

Assembly Instructions

Build on a breadboard first and only commit to solder once the whole system has run for an hour without a fault.

  1. Set up the detector and a video source

    Install the framework, load a pretrained YOLO model, and stream frames from a camera or video.

    Pick a model size that matches your hardware (small for edge, large for GPU).

  2. Run inference with filtering and NMS

    Run each frame through the single-pass detector, filter by confidence, and apply NMS for one clean box per object.

  3. Fine-tune and deploy

    Fine-tune on custom classes if needed, evaluate with mAP, and deploy at the right speed/accuracy point for the hardware.

Step-by-Step Implementation Guide

Work through these in order. Each step ends in something you can observe, so a failure is always localised to the step you just finished.

  1. Detect, filter and clean per frame

    Run the detector on each frame, keep confident detections, and rely on NMS to remove duplicate overlapping boxes.

    pythonrealtime.py
    from ultralytics import YOLO
    model = YOLO("yolov8s.pt")
    
    def detect(frame, conf=0.35, iou=0.45):
        # single forward pass; conf filter + NMS handled by the model
        r = model(frame, conf=conf, iou=iou)[0]
        out = []
        for b in r.boxes:
            out.append({
                "box": [int(v) for v in b.xyxy[0]],   # where
                "label": model.names[int(b.cls)],     # what
                "conf": float(b.conf),                # confidence
            })
        return out                                    # clean detections
    r = model(frame, conf=conf, iou=iou)[0]One forward pass detects all objects in the frame at once — the single-pass design that makes real time possible.
    "box": [int(v) for v in b.xyxy[0]], # whereEach detection carries its bounding box — the localisation that distinguishes detection from classification.
    "conf": float(b.conf), # confidenceConfidence lets downstream logic threshold detections; the conf/iou args apply the filter and NMS that yield one clean box per object.
  2. Use the detections downstream

    Draw boxes/labels live, and feed detections to counting, tracking or triggering logic — the reusable perception layer.

Complete Source Code

The listing below is complete and compiles as written — there are no elided sections. Read the annotations under each block before you upload it.

pythonobject_detection.py
#!/usr/bin/env python3
"""
Real-Time Object Detection (YOLO)

Detects and labels multiple objects live: single-pass inference,
confidence filtering + non-maximum suppression for clean boxes, and a
speed/accuracy dial via model size. A reusable perception layer for
counting, tracking and triggering. Detects only trained classes.
"""
from ultralytics import YOLO
import cv2, time

# Model size = the speed/accuracy dial: n/s for edge, l/x for GPU.
model = YOLO("yolov8s.pt")
CONF, NMS_IOU = 0.35, 0.45

def annotate(frame, dets):
    for d in dets:
        x1, y1, x2, y2 = d["box"]
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
        cv2.putText(frame, f'{d["label"]} {d["conf"]:.2f}', (x1, y1-6),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
    return frame

def detect(frame):
    r = model(frame, conf=CONF, iou=NMS_IOU, verbose=False)[0]  # single pass + NMS
    return [{"box": [int(v) for v in b.xyxy[0]],
             "label": model.names[int(b.cls)],
             "conf": float(b.conf)} for b in r.boxes]

def main(source=0):
    cap = cv2.VideoCapture(source)
    while True:
        ok, frame = cap.read()
        if not ok: break
        t = time.time()
        dets = detect(frame)                      # what + where + confidence
        # ---- downstream hooks: count / track / trigger on 'dets' ----
        fps = 1.0 / max(time.time() - t, 1e-6)
        frame = annotate(frame, dets)
        cv2.putText(frame, f"{fps:.1f} FPS  {len(dets)} objects", (8, 24),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 200, 255), 2)
        cv2.imshow("Real-Time Detection", frame)
        if cv2.waitKey(1) == 27: break
    cap.release(); cv2.destroyAllWindows()

if __name__ == "__main__":
    main(0)                                       # 0 = webcam; or a video path
model = YOLO("yolov8s.pt")The model variant is the speed/accuracy dial — swap for nano on a Pi or extra-large on a GPU without changing the rest of the code.
r = model(frame, conf=CONF, iou=NMS_IOU, verbose=False)[0] # single pass + NMSA single forward pass with built-in confidence filtering and NMS produces clean detections — the fast core of real-time detection.
# ---- downstream hooks: count / track / trigger on 'dets' ----Detections are a reusable perception layer: counting, tracking, or triggering all hang off this same list of what-and-where.
cv2.putText(frame, f"{fps:.1f} FPS {len(dets)} objects", (8, 24),Showing live FPS makes the speed/accuracy trade-off concrete — it is what you watch when choosing model size for the hardware.

Configuration & Calibration

Configuration steps

  • Configure the model variant (speed/accuracy) for your hardware.
  • Configure confidence and NMS-IoU thresholds.
  • Configure the video source and (if custom) the fine-tuned classes.
  • Configure downstream hooks (count/track/trigger).

Calibration procedure

An uncalibrated sensor produces confident, precise, wrong numbers. Do this once per physical unit and record the constants.

  1. Thresholds

    Tune confidence to balance misses vs false detections; adjust NMS-IoU if boxes merge or duplicate.

  2. Model size

    Pick the smallest model that meets your accuracy need at real-time FPS on the hardware.

  3. Custom classes

    If fine-tuning, validate mAP on held-out images covering hard cases.

Dataset, Model & Training

Dataset

Detectors are trained on images annotated with bounding boxes and class labels. A COCO-pretrained model gives ~80 common classes out of the box; custom classes need your own labelled images.

Coverage of angles, scales, lighting and occlusion in the training data directly determines real-world accuracy.

DatasetSizeLicenceUse here
COCO~120k images, 80 classesCC BY 4.0 (images vary)Pretrained base / general detection
Custom labelled setHundreds–thousandsYoursFine-tune for your classes
Open Images / VOCLargeVariesExtra classes / pretraining
Hard-case samplesTargetedYoursSmall/occluded/night robustness

Data preprocessing

  • Resize/letterbox frames to the model input size; normalise pixels.
  • Augment training data (scale, flip, mosaic, colour) for robustness.
  • Ensure annotations are accurate — box quality caps model quality.
Real-Time Object Detection — ML pipelineFrom raw data through training to deployed inference. 1Framecamera/video2Preprocessresize/normalise3YOLOsingle pass4Filter + NMSclean boxes5Outputboxes+labels
Real-Time Object Detection — ML pipeline

Model architecture

A YOLO detector has a backbone (feature extraction), a neck (multi-scale feature fusion), and a head predicting boxes/objectness/classes at several scales — enabling detection of both large and small objects in one pass.

Model variants (n/s/m/l/x) trade parameters and input size for speed vs accuracy.

Layer / stageShape or configurationPurpose
BackboneCNN feature extractorLearns image features
Neckmulti-scale fusion (FPN/PAN)Detect large + small objects
Headbox + objectness + classPredicts all detections in one pass
Post-processconfidence filter + NMSOne clean box per object
Variantn/s/m/l/xSpeed vs accuracy dial

Hyperparameters

HyperparameterValueWhy
Confidence threshold≈ 0.25–0.5Miss vs false detections
NMS IoU threshold≈ 0.45Merge duplicates vs split objects
Input size≈ 640 pxAccuracy vs speed
Model variantn/s (edge) … l/x (GPU)Speed/accuracy for hardware

Training process

  • Start from pretrained weights and fine-tune on your labelled classes (transfer learning) — far less data than training from scratch.
  • Augment heavily; validate on held-out images covering hard cases.
  • Track mAP; watch for overfitting to a narrow set of conditions.

Evaluation, Metrics & Deployment

Detection quality is measured by mean Average Precision (mAP) across classes and IoU thresholds, alongside real-time speed (FPS) on the target hardware.

MetricValueWhat it tells you
mAP@0.5model/data-dependentOverall detection accuracy
mAP@0.5:0.95stricterLocalisation quality too
FPShardware-dependentReal-time feasibility
Precision / recallper classFalse detections vs misses

Figures from the reference training run described above — reproduce them before trusting your own changes.

Speed vs accuracy by model sizeLarger models detect more accurately but run slower — the core deployment trade-off (illustrative). Nano (edge)60Small72Medium82Large (GPU)90
Speed vs accuracy by model size

Inference example

pythondetect.py
from ultralytics import YOLO
import cv2

model = YOLO("yolov8n.pt")          # small = edge-friendly; swap for l/x on GPU
CONF = 0.35

cap = cv2.VideoCapture(0)           # live camera
while True:
    ok, frame = cap.read()
    if not ok: break
    # single-pass detection + built-in NMS
    results = model(frame, conf=CONF)[0]
    for b in results.boxes:
        x1, y1, x2, y2 = map(int, b.xyxy[0])
        label = model.names[int(b.cls)]           # what
        conf  = float(b.conf)                     # confidence
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)   # where
        cv2.putText(frame, f"{label} {conf:.2f}", (x1, y1 - 6),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
    cv2.imshow("detections", frame)
    if cv2.waitKey(1) == 27: break

Testing Procedure & Expected Output

Test from the bottom up. Confirm power, then each sensor in isolation, then the integrated loop — the first failing step tells you exactly where to look.

TestWhat you should see
Point at common objectsCorrect boxes/labels with confidence
Crowd many objectsEach detected; NMS gives one box each
Lower confidence thresholdMore (and more false) detections
Small/distant objectsSome missed — note the limit
Swap model sizeSpeed vs accuracy shifts as expected
Custom object (unfine-tuned)Not detected — needs training data

Bench-test checklist. If a row fails, stop and fix it before moving on.

Expected output

A live video with clean labelled boxes and confidences, plus a detections stream for downstream use.

jsondetections.json
[
  { "label": "person", "conf": 0.94, "box": [220, 90, 310, 360] },
  { "label": "car",    "conf": 0.88, "box": [400, 210, 560, 300] },
  { "label": "dog",    "conf": 0.81, "box": [120, 260, 210, 350] }
]

Three objects detected in one frame with locations and confidences — the "what and where" layer other vision logic builds on.

A wall-mounted CCTV surveillance camera
Model size sets the speed/accuracy trade-off — small models run on edge devices, large ones need a GPU. Photograph sourced from Wikimedia Commons — CCTV camera.jpg. Reused under the licence stated on that page; please check it before republishing.

Troubleshooting: Common Errors & Fixes

Too slow / low FPS

Likely cause. Model too big for hardware

Fix. Use a smaller variant / lower input size; use a GPU/accelerator

Duplicate boxes per object

Likely cause. NMS-IoU too high

Fix. Lower the NMS-IoU threshold

Objects merged into one box

Likely cause. NMS-IoU too low

Fix. Raise the NMS-IoU threshold

Many false detections

Likely cause. Confidence too low

Fix. Raise the confidence threshold

Misses custom objects

Likely cause. Not in training classes

Fix. Fine-tune on labelled data for those classes

Poor at night/indoors

Likely cause. Domain shift

Fix. Train on representative data for the conditions

The Python script crashes with "externally-managed-environment" on pip install

Likely cause. Raspberry Pi OS Bookworm marks the system Python as managed by apt, and refuses global pip installs.

Fix. Create and activate a virtual environment — python3 -m venv ~/venv && source ~/venv/bin/activate — and install there. Use --system-site-packages if you also need apt-installed modules such as picamera2.

The Pi reboots or shows a lightning-bolt icon under load

Likely cause. Under-voltage. The supply sags below 4.63 V when the CPU and peripherals ramp up.

Fix. Use the official supply for your model (5 V 3 A for Pi 4, 5 V 5 A for Pi 5) and a short, thick USB-C cable. Check with vcgencmd get_throttled — anything other than 0x0 means power problems.

Performance Optimisation

  • Pick the smallest model meeting accuracy at real-time FPS.
  • Tune confidence and NMS-IoU for clean, correct boxes.
  • Use a GPU/accelerator or lower resolution for speed.
  • Fine-tune on representative data for the real conditions.
  • Pin the hot loop to one core with taskset and leave the others free for the OS.
  • Prefer MJPEG over raw YUY2 when capturing from USB cameras — the decode cost is far lower than the USB bandwidth cost.
  • Log to a tmpfs RAM disk and flush to the SD card once a minute; per-sample SD writes are what kills cards.
  • Run the service under systemd with Restart=always so a crash never means a dead deployment.
  • Profile before optimising — print micros() deltas around each stage and fix the slowest one first.

Safety Precautions

  • A detector is not infallible — do not rely on it alone for safety-critical decisions without redundancy and validation.
  • Cameras raise privacy obligations — follow notice/consent rules and minimise stored imagery.
  • Confidence scores are not guarantees; validate mAP before trusting it.
  • Beware bias from unrepresentative training data.
  • Wear eye protection when soldering or cutting, and solder in a ventilated space — rosin flux fumes are a respiratory irritant.
  • Power the circuit through a bench supply with a current limit while you are testing. A 300 mA limit turns a wiring mistake into a beep instead of a dead board.
  • Disconnect power before changing any wiring. Hot-plugging a sensor onto a live bus is the fastest way to lose a controller.

Maintenance

  • Retrain/fine-tune as conditions or classes change.
  • Monitor accuracy for domain drift over time.
  • Keep thresholds tuned to the deployment.
  • Track FPS as models/hardware change.
  • Re-check every screw terminal and header after the first week — thermal cycling loosens connections that felt tight on day one.
  • Recalibrate at the interval given in the calibration section, and keep the constants in a text file next to the firmware — not only in flash.
  • Keep a short logbook of firmware versions and what changed. Six months later you will not remember why that constant is 1.083.

Future Improvements & Upgrades

A working v1 is a platform, not a finish line. These are the upgrades that add the most capability for the least rework.

  • Add multi-object tracking (assign persistent IDs across frames).
  • Add segmentation (pixel masks) or pose on top of detection.
  • Quantise/prune for faster edge inference.
  • Add active learning to target hard cases in retraining.
  • Design a proper PCB. Once the breadboard version has run for a month, moving to a two-layer board removes the intermittent-contact failures that dominate prototype faults.
  • Add connectivity — an ESP32 and an MQTT publish turn a local gadget into something you can graph, alert on and analyse over months.
  • Add persistent local storage (microSD or the on-chip flash) so a network outage does not create a hole in your data.
  • Move configuration out of the source: a captive-portal setup page or a JSON config file makes the build reusable without a recompile.
  • Add a battery and solar option so the unit survives a power cut and can be sited away from a socket.
  • Write a small test harness that feeds synthetic sensor values through the decision logic, so you can validate thresholds without physically triggering the event.

Frequently Asked Questions

What is object detection vs classification?

Classification answers "what is this image?"; detection answers "what objects are present and where is each one?", localising a variable number of objects with bounding boxes and labels.

Why is YOLO fast?

It treats detection as a single pass through one network — the whole image in, all boxes and classes out at once — instead of proposing and classifying thousands of regions. "You Only Look Once" is literal.

What is non-maximum suppression?

The clean-up that collapses the many overlapping raw predictions for one object into a single box — keeping the highest-confidence box and suppressing others that overlap it heavily and share its class.

How do I choose a model size?

By the speed/accuracy trade-off for your hardware: a small model runs on a Pi/phone but is less accurate; a large model is accurate but needs a GPU for real-time video. Pick the smallest that meets your accuracy at the FPS you need.

Can it detect my custom objects?

Only after fine-tuning on labelled images of them. A pretrained model knows its training classes and nothing else, and its accuracy is capped by how well the data covers real angles, scales, lighting and occlusion.

References & Learning Resources

These are the primary sources worth reading in full. Manufacturer datasheets always outrank forum posts when the two disagree.

  1. Object detectionReference
  2. YOLO (You Only Look Once)Reference
  3. Non-maximum suppression / IoUReference
  4. Ultralytics YOLODocs
  5. COCO datasetDataset