Skip to main content

Crate chess_corners

Crate chess_corners 

Source
Expand description

Ergonomic ChESS detector facade over chess-corners-core.

§Overview

This crate is the high-level entry point for the ChESS (Chess-board Extraction by Subtraction and Summation) corner detector. It exposes:

  • single-scale detection on raw grayscale buffers via find_chess_corners,
  • optional image::GrayImage helpers (see find_chess_corners_image) when the image feature is enabled,
  • a flat user-facing ChessConfig with explicit modes for thresholding, ring selection, and multiscale tuning.

The detector returns subpixel CornerDescriptor values in full-resolution image coordinates. In most applications you construct a ChessConfig, optionally tweak its fields, and call find_chess_corners or find_chess_corners_image.

§Quick start

§Using image (default)

The default feature set includes integration with the image crate:

use chess_corners::{ChessConfig, RefinementMethod, find_chess_corners_image};
use image::io::Reader as ImageReader;

// Load a grayscale chessboard image.
let img = ImageReader::open("board.png")?
    .decode()?
    .to_luma8();

// Start from the recommended coarse-to-fine preset.
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());

for c in &corners {
    println!(
        "corner at ({:.2}, {:.2}), response {:.1}, axes [{:.2}, {:.2}] rad",
        c.x, c.y, c.response, c.axes[0].angle, c.axes[1].angle,
    );
}

§Raw grayscale buffer

If you already have an 8-bit grayscale buffer, you can call the detector directly without depending on image:

use chess_corners::{ChessConfig, find_chess_corners_u8};

// Single-scale convenience configuration.
let cfg = ChessConfig::single_scale();

let corners = find_chess_corners_u8(img, width, height, &cfg)?;
println!("found {} corners", corners.len());

§ML refiner (feature ml-refiner)

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).unwrap();

The ML refiner runs a small ONNX model on normalized intensity patches (uint8 / 255.0) centered at each candidate. The model predicts [dx, dy, conf_logit], but the confidence output is currently ignored; the offsets are applied directly. Current benchmarks are synthetic; real-world accuracy still needs validation. It is also slower (about 23.5 ms vs 0.6 ms for 77 corners on testimages/mid.png).

§Python bindings

The workspace includes a PyO3-based Python extension crate at crates/chess-corners-py. It exposes chess_corners.find_chess_corners, which accepts a 2D uint8 NumPy array and returns a float32 (N, 9) array with columns [x, y, response, contrast, fit_rms, axis0_angle, axis0_sigma, axis1_angle, axis1_sigma]. See crates/chess-corners-py/README.md for usage and configuration details.

For tight processing loops you can also reuse pyramid storage explicitly via find_chess_corners_buff and the internal pyramid module; this avoids reallocating intermediate pyramid levels across frames. Most users should stick to find_chess_corners / find_chess_corners_image unless they need fine-grained control over allocations.

§Configuration

ChessConfig is intentionally flat. It exposes detector ring, descriptor ring, threshold mode/value, NMS controls, refiner choice, and multiscale settings directly. The detector translates that high-level config into lower-level ChessParams and CoarseToFineParams internally.

If you need raw response maps or more control, the most useful low-level primitives are re-exported here: chess_response_u8, chess_response_u8_patch, Roi, detect_corners_from_response_with_refiner, Corner, and corners_to_descriptors. For deeper internals (ring offsets, SAT views, scalar reference paths) depend on chess-corners-core directly.

§Features

  • image (default) – enables find_chess_corners_image and image::GrayImage integration.
  • rayon – parallelizes response computation and multiscale refinement over image rows. Combine with par_pyramid to parallelize pyramid downsampling as well.
  • ml-refiner – enables the ML-backed refiner entry points via the chess-corners-ml crate and embedded ONNX model.
  • simd – enables portable-SIMD accelerated inner loops for the response kernel (requires a nightly compiler). Combine with par_pyramid to SIMD-accelerate pyramid downsampling.
  • par_pyramid – opt-in gate for SIMD/rayon acceleration inside the pyramid builder.
  • tracing – emits structured spans for multiscale detection, suitable for use with tracing-subscriber or JSON tracing from the CLI.
  • cli – builds the chess-corners binary shipped with this crate; it is not required when using the library as a dependency.

The library API is stable across feature combinations; features only affect performance and observability, not numerical results.

The ChESS idea was proposed in the papaer Bennett, Lasenby, ChESS: A Fast and Accurate Chessboard Corner Detector, CVIU 2014

Re-exports§

pub use image::find_chess_corners_image;
pub use image::find_chess_corners_image_with_refiner;

Modules§

image
Optional image::GrayImage helpers for the unified corner detector.

Structs§

AxisEstimate
Direction of one local grid axis with its 1σ angular uncertainty.
CenterOfMassConfig
Legacy center-of-mass refinement on the response map.
ChessConfig
ChessParams
Tunable parameters for the ChESS response computation and corner detection.
CoarseToFineParams
Parameters controlling the coarse-to-fine multiscale detector.
Corner
A detected ChESS corner (subpixel).
CornerDescriptor
Describes a detected chessboard corner in full-resolution image coordinates.
ForstnerConfig
Förstner-style gradient-based refiner.
ImageBuffer
Owned grayscale image buffer (u8).
ImageView
Minimal grayscale view for refinement without taking a dependency on image.
PyramidBuffers
Reusable backing storage for pyramid construction.
PyramidParams
Parameters controlling pyramid generation.
RadonBuffers
Reusable scratch for the whole-image Radon detector. Holds the upsampled image buffer, the four summed-area tables, the response map, and the box-blur scratch. All buffers grow on demand and are reused across frames — same pattern as PyramidBuffers.
RadonDetectorParams
Configuration for the whole-image Radon detector.
RadonPeakConfig
Configuration for RadonPeakRefiner.
RefineResult
Result of refining a single corner candidate.
RefinerConfig
ResponseMap
Dense response map in row-major layout.
Roi
Rectangular region of interest with half-open coordinate semantics [x0, x1) × [y0, y1).
SaddlePointConfig
Quadratic saddle-point surface refiner.
UpscaleBuffers
Reusable scratch buffer for the upscaling stage.
UpscaleConfig
Upscaling configuration exposed through crate::ChessConfig.

Enums§

ChessError
Errors returned by detection and heatmap entry points.
DescriptorMode
DetectorMode
Detector kernel selection. Canonical and Broad are the two ChESS variants (radius-5 and radius-10 rings); Radon picks the whole-image Duda-Frese detector via chess_corners_core::radon_response_u8 / chess_corners_core::detect_corners_from_radon. The Radon detector is useful under heavy blur, low contrast, or cells smaller than the ChESS ring support.
PeakFitMode
Subpixel peak-fitting mode.
RefineStatus
Status of a refinement attempt.
RefinementMethod
Refiner
Runtime refiner with reusable scratch buffers.
RefinerKind
User-facing enum selecting a refinement backend.
ThresholdMode
UpscaleError
Errors returned by upscaling setup or execution.
UpscaleMode
Upscaling mode, encoded into JSON as "disabled" or "fixed".

Traits§

CornerRefiner
Trait implemented by pluggable refinement backends.

Functions§

chess_response_u8
Compute the dense ChESS response for an 8-bit grayscale image.
chess_response_u8_patch
Compute the ChESS response only inside a rectangular ROI of the image.
corners_to_descriptors
Convert raw corner candidates into full descriptors by sampling the source image.
detect_corners_from_response
Core detector: run NMS + refinement on an existing response map.
detect_corners_from_response_with_refiner
Detector variant that accepts a user-provided refiner implementation.
find_chess_corners
Detect corners from a base-level grayscale view, allocating pyramid storage internally.
find_chess_corners_buff
Detect corners using a caller-provided pyramid buffer.
find_chess_corners_buff_with_refiner
Variant of find_chess_corners_buff that accepts an explicit refiner selection.
find_chess_corners_u8
Detect chessboard corners from a raw grayscale image buffer.
find_chess_corners_u8_with_refiner
Detect corners from a raw grayscale buffer with an explicit refiner choice.
find_chess_corners_with_refiner
Single-call helper that lets callers pick the refiner.
radon_heatmap_image
Compute the Radon response heatmap from an image::GrayImage.
radon_heatmap_u8
Compute the whole-image Radon response heatmap from a raw grayscale buffer.
rescale_descriptors_to_input
Rescale corner positions from an upscaled image back to the original input-image pixel frame.
upscale_bilinear_u8
Bilinear upscaling by an integer factor into the provided buffer.