Skip to content

About

A GUI for exploring circle detection (OpenCV Hough Circle Transform) on images or a camera feed

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

⭕ Circle Detection Explorer

A GUI for exploring circle detection (the OpenCV Hough Circle Transform) on uploaded images or a live camera feed. Adjust every parameter with sliders and watch the whole pipeline — grayscale → blur → edges → detected circles — update in real time.

This is a sibling of the HSV Picker GUI: same layout, same workflow, but for finding circles instead of filtering colours.

📦 Prerequisites

  • Python 3.12.3 or higher

🚀 Getting Started

Before diving into the algorithms, make sure you have the required tools and libraries installed.

  1. Setup your development environment.
  2. Run the command to start the GUI:

Use the run script to start the GUI:

./run

Or run the following command directly:

streamlit run ./gui/main.py --server.port 8503
  1. Open the link in your browser: http://localhost:8503/

🎛️ Understanding the Parameters

Circle detection uses cv2.HoughCircles. Each slider maps directly to one of its arguments:

Parameter What it does
Median blur kernel Smooths the image before detection. Larger removes more noise but softens edges. Must be odd.
dp Inverse ratio of accumulator resolution to image resolution. 1 = same resolution; larger finds coarser circles faster.
minDist Minimum distance between the centres of two detected circles. Too small produces many overlapping false circles.
param1 Upper threshold for the internal Canny edge detector (the lower one is half of it). Use the Edges panel to tune it visually.
param2 Accumulator vote threshold for circle centres. Smaller = more circles (including false ones); larger = only strong circles.
minRadius / maxRadius Restrict the size of circles to detect, in pixels. 0 means unbounded.

How to tune it

  1. Start with the Edges panel and adjust param1 until the circle outlines you care about are clean and continuous.
  2. Lower param2 until your circles appear, then raise it just enough to drop the false positives.
  3. Set minRadius / maxRadius to ignore blobs that are the wrong size, and raise minDist if you get clusters of overlapping detections.

Detected circles are drawn in green with a red centre dot, and the current parameters can be exported as JSON from the sidebar.

🔎 Automatic tuning

Tuning by hand is fine for one image. For a folder of them, tuning/ does it automatically: tell it how many circles are in each image and it searches for the parameters that find exactly that many.

1. Label your images

The count goes in the filename, as the last _n<count> (or -n<count>) token:

data/images/coins_n7.jpg        ->  7 circles
data/images/wafer-n12.png       -> 12 circles
data/images/2024_batch_n3.jpg   ->  3 circles
data/images/IMG_0042.jpg        -> unlabelled; reported, not guessed at

Filename labels fail silently when mistyped, so check what was parsed before committing to a long run:

python -m tuning labels

2. Search

python -m tuning search

Each image is searched independently and the winning parameters recorded. Common options:

python -m tuning search --dir data/samples    # a different folder
python -m tuning search --image coins_n7.jpg  # one image (repeatable)
python -m tuning search --quick               # small grid, for a first look
python -m tuning search --jobs 4              # cap the worker processes
python -m tuning search --force               # re-search images already recorded
python -m tuning search --grid my_grid.json   # custom search space

Images already matched in results/best_params.json are skipped, so adding a new batch later only searches the new files. A recorded miss is tried again — the grid may have changed since.

3. Read the results

File Contents
results/best_params.json The winning config per image, in both pixel and fractional form
results/global_params.json The single config that fits the most images, with a per-image hit/miss list
results/search_log.csv Every parameter set that produced the right count, ranked
results/overlays/*.png The winning detections drawn on each image, named <image filename>.png

Look at the overlays. Finding the right number of circles is not the same as finding the right circles, and the overlay is what tells the two apart.

Copy the config_pixels values from best_params.json straight into the GUI sliders — the keys are the same.

How the search works

param2 is the expensive axis: 200 values, and it interacts with everything else. But circle count is near-monotone in it — a higher accumulator threshold admits fewer circles — so it is searched rather than enumerated:

  1. Bracket. Try the loosest param2. If even that finds fewer circles than the target, no threshold can reach it, so the combination is discarded after one detector call. Most of the grid dies here.
  2. Bisect. About eight calls to find where the count crosses the target.
  3. Scan. Walk the integers around the crossing, because the monotonicity is only approximate and bisection can step over an exact hit.

Everything else — blur kernel, dp, minDist, param1, radius range — is a plain grid, and lengths are stored as fractions of the image's shorter side so a config means the same thing on a 640 px image and a 4000 px one.

Usually many parameter sets produce the right count and most of them are coincidences. Two things separate the real ones:

  • Run width — how many consecutive param2 values give the target count. A config that works across param2 34–41 is an operating point; one that works only at exactly 52 is a fluke.
  • Stability — whether nudging dp, minDist or param1 one grid step still gives the target count.

Trying it without your own images

python tools/make_synthetic.py
python -m tuning search --dir data/samples

This writes images with a known number of circles drawn into them, so the whole pipeline can be exercised end to end and the overlays checked against an answer that is right by construction.

Tests

pip install -r requirements-dev.txt
pytest

About

A GUI for exploring circle detection (OpenCV Hough Circle Transform) on images or a camera feed

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages