chess-corners
Ergonomic ChESS (Chess-board Extraction by Subtraction and Summation) detector
on top of chess-corners-core.
This crate is the public Rust API:
- flat
ChessConfigwith explicit semantic modes, threshold mode, and refiner selection - single-scale and multiscale detection entry points
- optional
image::GrayImagehelpers - optional CLI binary and ML-backed refinement entry points
chess-corners-core and box-image-pyramid remain available as lower-level
sharp tools, but chess-corners is the intended compatibility boundary.
Quick start
use ;
use ImageReader;
Public config shape
ChessConfig is intentionally flat:
use ;
let mut cfg = single_scale;
cfg.detector_mode = Canonical;
cfg.descriptor_mode = FollowDetector;
cfg.threshold_mode = Relative;
cfg.threshold_value = 0.2;
cfg.nms_radius = 2;
cfg.min_cluster_size = 2;
cfg.pyramid_levels = 1;
cfg.pyramid_min_size = 128;
cfg.refinement_radius = 3;
cfg.merge_radius = 3.0;
cfg.refiner.kind = CenterOfMass;
Use ChessConfig::single_scale() for the default one-level detector and
ChessConfig::multiscale() for the recommended 3-level preset.
DetectorMode::Broad enables the wider, blur-tolerant detector response mode.
DescriptorMode can either follow the detector or override the descriptor
ring radius explicitly (each descriptor is built by fitting a two-axis tanh
model to the ring samples — see the book's Part III, §3.4).
Descriptor output
Each detection is a CornerDescriptor with:
x,y— subpixel position.response— raw unnormalized ChESS responseR(paper's score;R > 0is the default acceptance criterion).contrast— fitted bright/dark amplitude|A|in gray levels.fit_rms— RMS residual of the two-axis fit in gray levels.axes[0],axes[1]— the two local grid axes with per-axis 1σ angular uncertainty from the Gauss–Newton covariance (σθᵢ = √((SSR / 12) · (JᵀJ)⁻¹[i,i])). Axes are not assumed orthogonal;axes[0].angle ∈ [0, π)andaxes[1].angle ∈ (axes[0].angle, axes[0].angle + π), with the CCW arc between them spanning a dark sector.
Refiner configuration
cfg.refiner always contains all supported leaf configs:
cfg.refiner.center_of_masscfg.refiner.forstnercfg.refiner.saddle_point
Only cfg.refiner.kind selects which one is active:
use ;
let mut cfg = single_scale;
cfg.refiner.kind = Forstner;
cfg.refiner.forstner.max_offset = 2.0;
You can also bypass the configured refiner for a single call with
find_chess_corners_image_with_refiner or find_chess_corners_with_refiner.
CLI config shape
The CLI uses the same flat algorithm schema at the top level, combined with
application fields such as image, output_json, output_png, log_level,
and ml.
See:
config/chess_algorithm_config_example.jsonfor the shared algorithm configconfig/chess_cli_config_example.jsonfor a complete CLI input
ML refiner
Enable the ml-refiner feature to use the separate ML-backed pipeline:
use ;
use GrayImage;
let img = new;
let cfg = single_scale;
let corners = find_chess_corners_image_with_ml;
The ML path is slower than the classic refiners and intentionally stays outside
the canonical ChessConfig schema.
Examples
- Single-scale:
cargo run -p chess-corners --example single_scale_image -- testimages/mid.png - Multiscale:
cargo run -p chess-corners --example multiscale_image -- testimages/large.png
Feature flags
image(default):image::GrayImageintegrationrayon: parallel response/refinementsimd: portable-SIMD acceleration in the core response pathpar_pyramid: SIMD/rayonin pyramid constructiontracing: structured spansml-refiner: ONNX-backed ML refinementcli: build thechess-cornersbinary