chess-corners 0.8.0

High-level chessboard / ChESS corner detection API
Documentation

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 ChessConfig with explicit semantic modes, threshold mode, and refiner selection
  • single-scale and multiscale detection entry points
  • optional image::GrayImage helpers
  • 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 chess_corners::{ChessConfig, RefinementMethod, find_chess_corners_image};
use image::ImageReader;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let img = ImageReader::open("board.png")?.decode()?.to_luma8();

    let mut cfg = ChessConfig::multiscale();
    cfg.threshold_value = 0.15;
    cfg.refiner.kind = RefinementMethod::Forstner;

    let corners = find_chess_corners_image(&img, &cfg);
    println!("found {} corners", corners.len());
    Ok(())
}

Public config shape

ChessConfig is intentionally flat:

use chess_corners::{
    ChessConfig, DescriptorMode, DetectorMode, RefinementMethod, ThresholdMode,
};

let mut cfg = ChessConfig::single_scale();
cfg.detector_mode = DetectorMode::Canonical;
cfg.descriptor_mode = DescriptorMode::FollowDetector;
cfg.threshold_mode = ThresholdMode::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 = RefinementMethod::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 response R (paper's score; R > 0 is 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, π) and axes[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_mass
  • cfg.refiner.forstner
  • cfg.refiner.saddle_point

Only cfg.refiner.kind selects which one is active:

use chess_corners::{ChessConfig, RefinementMethod};

let mut cfg = ChessConfig::single_scale();
cfg.refiner.kind = RefinementMethod::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.json for the shared algorithm config
  • config/chess_cli_config_example.json for a complete CLI input

ML refiner

Enable the ml-refiner feature to use the separate ML-backed pipeline:

use chess_corners::{ChessConfig, find_chess_corners_image_with_ml};
use image::GrayImage;

let img = GrayImage::new(1, 1);
let cfg = ChessConfig::single_scale();
let corners = find_chess_corners_image_with_ml(&img, &cfg);

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::GrayImage integration
  • rayon: parallel response/refinement
  • simd: portable-SIMD acceleration in the core response path
  • par_pyramid: SIMD/rayon in pyramid construction
  • tracing: structured spans
  • ml-refiner: ONNX-backed ML refinement
  • cli: build the chess-corners binary