Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Proposal Diagnostics

The proposal stage can be run standalone to inspect candidate centers and the vote accumulator heatmap without running the full detection pipeline.

Python API

Raw mode (no scale prior)

import ringgrid
from ringgrid import viz

# Default ProposalConfig
proposals = ringgrid.propose("photo.png")
result = ringgrid.propose_with_heatmap("photo.png")

print(len(result.proposals))
print(result.heatmap.shape)  # (H, W), float32

viz.plot_proposal_diagnostics(
    image="photo.png",
    diagnostics=result,
    out="proposal_overlay.png",
)

Detector-aware mode (scale-tuned)

When a board layout and marker diameter are available, the proposal config is derived from MarkerScalePrior for tighter search windows:

board = ringgrid.BoardLayout.default()
cfg = ringgrid.DetectConfig(board)
detector = ringgrid.Detector(cfg)

result = detector.propose_with_heatmap("photo.png")

Or via the module-level convenience function:

result = ringgrid.propose_with_heatmap(
    "photo.png",
    target=board,
    marker_diameter=32.0,
)

Custom ProposalConfig

config = ringgrid.ProposalConfig(
    r_min=5.0,
    r_max=40.0,
    min_distance=15.0,
    edge_thinning=True,
)
result = ringgrid.propose_with_heatmap("photo.png", config=config)

Rust API

The standalone proposal module provides entry points that work on any grayscale image, independent of the ringgrid detection pipeline:

#![allow(unused)]
fn main() {
use ringgrid::proposal::{find_ellipse_centers, find_ellipse_centers_with_heatmap, ProposalConfig};

let config = ProposalConfig {
    r_min: 5.0,
    r_max: 30.0,
    min_distance: 15.0,
    ..Default::default()
};

// Proposals only
let proposals = find_ellipse_centers(&gray, &config);

// Proposals + heatmap
let result = find_ellipse_centers_with_heatmap(&gray, &config);
println!("heatmap size: {:?}", result.image_size);
}

ProposalResult Fields

FieldTypeDescription
proposalslist[Proposal]Detected center candidates with (x, y, score)
heatmapnp.ndarray (H, W), float32Post-smoothed vote accumulator used for NMS
image_size[int, int][width, height] of the input image

The heatmap is the Gaussian-smoothed vote accumulator that the proposal stage uses for thresholding and NMS. It is useful for understanding where the detector sees radial symmetry evidence.

ProposalConfig Parameters

ParameterDefaultDescription
r_min3.0Minimum voting radius (pixels)
r_max12.0Maximum voting radius (pixels)
min_distance10.0Minimum distance between output proposals (pixels)
grad_threshold0.05Gradient magnitude threshold (fraction of max)
min_vote_frac0.1Minimum accumulator peak (fraction of max)
accum_sigma2.0Gaussian smoothing sigma
edge_thinningtrueApply Canny-style gradient NMS before voting
max_candidatesNoneOptional hard cap on proposals

Visualization Tool

The repo includes a CLI tool for proposal visualization with optional ground-truth recall overlay:

python tools/plot_proposal.py \
    --image tools/out/synth_001/img_0000.png \
    --gt tools/out/synth_001/gt_0000.json \
    --out tools/out/synth_001/proposals_0000.png

Detector-aware mode (with marker scale prior):

python tools/plot_proposal.py \
    --image testdata/target_3_split_00.png \
    --target tools/out/target_faststart/board_spec.json \
    --marker-diameter 32.0 \
    --out proposals_overlay.png

Backward Compatibility

The Python class ProposalDiagnostics is a deprecated alias for ProposalResult. Existing code using ProposalDiagnostics will continue to work.