Skip to content

Repository files navigation

Coin Webcam Detector

A minimal local Python proof of concept for detecting coin-like objects from a laptop webcam or video file.

The app can run in two modes:

  • yolo: uses a coin-trained Ultralytics YOLO model, expected at models/best.pt.
  • circle: uses OpenCV Hough circle detection so the webcam pipeline can be tested without a trained model.

What it does

  • Opens a webcam or MP4/video file.
  • Detects coins or coin-like circles in each frame.
  • Draws bounding boxes, labels, and confidence scores where available.
  • Shows live video in an OpenCV window.
  • Optionally saves an annotated MP4 output video.
  • Press q to quit cleanly.
  • Press s to save a screenshot and matching detection metadata JSON.
  • Emits a coin_out_of_frame event when a previously visible coin disappears.

Setup

Use Python 3.10 or 3.11.

cd coin-webcam-detector
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

On Windows PowerShell:

cd coin-webcam-detector
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt

Run commands

YOLO mode with a coin-trained model:

python main.py --webcam --mode yolo --model models/best.pt

Circle fallback mode:

python main.py --webcam --mode circle

Different webcam index:

python main.py --webcam --mode circle --camera 1

Print JSON detections:

python main.py --webcam --mode yolo --print-json

Run with the local event API enabled:

python main.py --webcam --mode circle --event-server

Process an MP4/video file:

python main.py --video path/to/input.mp4 --mode yolo --model models/best.pt

Filter out giant false-positive boxes and use thinner rectangles:

python main.py \
  --video path/to/input.mp4 \
  --mode yolo \
  --model models/best.pt \
  --conf 0.30 \
  --max-box-area 0.20 \
  --box-thickness 1

Process a video and save an annotated MP4:

python main.py \
  --video path/to/input.mp4 \
  --mode yolo \
  --model models/best.pt \
  --save-video outputs/annotated_input.mp4

Process and save without opening a preview window:

python main.py \
  --video path/to/input.mp4 \
  --mode yolo \
  --model models/best.pt \
  --save-video outputs/annotated_input.mp4 \
  --no-display

Video fallback mode without a trained model:

python main.py --video path/to/input.mp4 --mode circle --save-video outputs/circle_output.mp4

Querying coin-out-of-frame events

When a coin is detected and then disappears for several consecutive frames, the app emits:

{
  "type": "coin_out_of_frame"
}

Events are always appended to:

outputs/events.jsonl

You can watch them in another terminal:

tail -f outputs/events.jsonl

If you start the app with --event-server, query recent events over HTTP:

curl "http://127.0.0.1:8765/events?type=coin_out_of_frame"

Poll only events after a known event ID:

curl "http://127.0.0.1:8765/events?type=coin_out_of_frame&since_id=3"

Tune how long the detector waits before emitting the event:

python main.py --webcam --mode circle --absence-frames 8 --event-server

The same event system works for video files:

python main.py --video path/to/input.mp4 --mode yolo --model models/best.pt --event-server

Screenshot metadata

Pressing s saves both files:

outputs/frame_YYYYMMDD_HHMMSS.jpg
outputs/frame_YYYYMMDD_HHMMSS.json

The JSON file includes the timestamp, image path, and detections for that frame.

Notes

  • YOLO mode needs a coin-trained model. Put it at models/best.pt or pass --model path/to/model.pt.
  • Default YOLO weights usually do not include coin classes, so they may not detect coins reliably.
  • Circle mode does not require training, but it detects circular objects, not coins specifically.
  • The models directory is included, but models/best.pt is not bundled because trained model weights are project-specific.

Next steps

  • Improve the dataset with varied coin angles, backgrounds, lighting, and distances.
  • Train or fine-tune a custom YOLO coin detector.
  • Add simple object tracking IDs if you need per-coin enter/exit events.
  • Export a trained model to ONNX for later Rust usage.

Export YOLO to ONNX

from ultralytics import YOLO

model = YOLO("models/best.pt")
model.export(format="onnx")

About

PoC of Livy's camera Vision

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages