pub fn chess_response_u8(
img: &[u8],
w: usize,
h: usize,
params: &ChessParams,
) -> ResponseMapExpand 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_abs = Some(0.0)
combined with a strict comparison in
crate::detect::detect_corners_from_response. The optional
threshold_rel / threshold_abs fields are adaptive policies
layered on top of the paper’s score — they are 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_u8uses a straightforward nestedfor y { for x { ... } }scalar loop and relies on the compiler’s auto‑vectorization in release builds. - With the
rayonfeature, the work is split into independent row slices and processed in parallel usingrayon::par_chunks_mut. - With the
simdfeature, the inner loop overxis rewritten to operate onLANESpixels at a time using portable SIMD vectors (currently 16 lanes ofu8). The ring samples are gathered into SIMD registers,SR/DR/μₙare accumulated in integer vectors, and the final response is written back per lane. - With both
rayonandsimdenabled, 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.