Skip to main content

chess_response_u8

Function chess_response_u8 

Source
pub fn chess_response_u8(
    img: &[u8],
    w: usize,
    h: usize,
    params: &ChessParams,
) -> ResponseMap
Expand description

Compute the dense ChESS response for an 8-bit grayscale image.

The response at each valid pixel center is computed from a 16‑sample ring around the pixel and a 5‑pixel cross at the center. For a given center c, let s[0..16) be the ring samples in the canonical order:

  • SR (sum of “square” responses) compares four opposite quadrants on the ring:

    SR = sum_{k=0..3} | (s[k] + s[k+8]) - (s[k+4] + s[k+12]) |
  • DR (sum of “difference” responses) enforces edge‑like structure:

    DR = sum_{k=0..7} | s[k] - s[k+8] |
  • μₙ is the mean of all 16 ring samples.

  • μₗ is the local mean of the 5‑pixel cross at the center (c, north, south, east, west).

The final ChESS response is:

R = SR - DR - 16 * |μₙ - μₗ|

where high positive values correspond to chessboard‑like corners.

§Score contract

R is the unnormalized ChESS response defined by Bennett and Lasenby (2014). The units are 8-bit pixel sums — not normalized to [0, 1], not divided by a local scale, not divided by the scene max. Every term is linear in the pixel values, so with 8-bit input R is bounded by SR − DR − 16·MR ∈ [−24·255, 8·255] (≈ [−6120, 2040]); in practice chessboard corners produce scores well below that upper bound.

The paper’s acceptance criterion is simply R > 0. That is what ChessParams::default() encodes via threshold = 0.0 combined with a strict comparison in crate::detect_corners_from_response. The threshold field is an absolute floor layered on top of the paper’s score — a convenience for trading off sensitivity vs false positives, not part of the score definition.

§Implementation strategy

Internally the image is processed row‑by‑row, but only pixels whose full ring lies inside the image bounds are evaluated; border pixels are left at zero in the returned ResponseMap.

  • Without any features, chess_response_u8 uses a straightforward nested for y { for x { ... } } scalar loop and relies on the compiler’s auto‑vectorization in release builds.
  • With the rayon feature, the work is split into independent row slices and processed in parallel using rayon::par_chunks_mut.
  • With the simd feature, the inner loop over x is rewritten to operate on LANES pixels at a time using portable SIMD vectors (currently 16 lanes of u8). The ring samples and the 5‑pixel local-mean cross are gathered into SIMD registers, SR/DR/μₙ/μₗ are accumulated in vector lanes, and the final response is stored a full vector at a time.
  • With both rayon and simd enabled, each row is processed in parallel and each row uses the SIMD‑accelerated inner loop.

All feature combinations produce the same output values (within a small tolerance for floating‑point rounding), and differ only in performance characteristics.

§Panics

Panics if img.len() != w * h.