9 releases (4 breaking)
| new 0.5.0 | Mar 30, 2026 |
|---|---|
| 0.4.2 | Mar 27, 2026 |
| 0.3.2 | Mar 9, 2026 |
| 0.3.1 | Jan 1, 2026 |
| 0.1.2 | Dec 7, 2025 |
#186 in Images
252 downloads per month
Used in 6 crates
385KB
3.5K
SLoC
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 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 descriptor and
orientation sampling explicitly.
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 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.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 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::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
Dependencies
~8–19MB
~366K SLoC