pub trait DenseDetector {
type Params;
type Buffers: Default;
type Response<'a>
where Self: 'a,
Self::Buffers: 'a;
// Required methods
fn compute_response<'a>(
&self,
view: ImageView<'_>,
params: &Self::Params,
buffers: &'a mut Self::Buffers,
) -> Self::Response<'a>;
fn detect_corners(
&self,
response: &Self::Response<'_>,
params: &Self::Params,
refine_border: i32,
) -> Vec<Corner>;
fn compute_response_patch<'a>(
&self,
base: ImageView<'_>,
roi: (i32, i32, i32, i32),
params: &Self::Params,
buffers: &'a mut Self::Buffers,
) -> Self::Response<'a>;
fn roi_border(&self, params: &Self::Params) -> i32;
fn refine_peaks_on_image(
&self,
corners: Vec<Corner>,
image: ImageView<'_>,
response: &Self::Response<'_>,
refiner: &mut dyn CornerRefiner,
) -> Vec<Corner>;
// Provided method
fn refines_on_image(&self) -> bool { ... }
}Expand description
Two-stage dense corner detector contract.
Implementors compute a dense per-pixel response over the input
image (compute_response, stage 1) and extract subpixel corner
peaks from it (detect_corners, stage 2). The two stages share
reusable scratch through Self::Buffers so a multiscale
orchestrator can amortise allocations across frames.
Subpixel refinement on the input image (Förstner, saddle-point,
center-of-mass, …) is NOT part of this trait — that runs as a
post-detection stage via
crate::detect::refine_corners_on_image, which is
detector-agnostic.
§Toolchain
Uses generic associated types (Self::Response); downstream
consumers require Rust 1.65 or newer.
Required Associated Types§
Sourcetype Buffers: Default
type Buffers: Default
Reusable scratch buffers. Allocated once via
Default::default and reused across compute_response
calls to avoid per-frame allocation.
Sourcetype Response<'a>
where
Self: 'a,
Self::Buffers: 'a
type Response<'a> where Self: 'a, Self::Buffers: 'a
Native response representation. May be owned (a borrow of an
owned ResponseMap in Self::Buffers) or a transient
view (RadonResponseView) over the same scratch. The
borrow lifetime ties the response back to the buffers that
produced it.
Required Methods§
Sourcefn compute_response<'a>(
&self,
view: ImageView<'_>,
params: &Self::Params,
buffers: &'a mut Self::Buffers,
) -> Self::Response<'a>
fn compute_response<'a>( &self, view: ImageView<'_>, params: &Self::Params, buffers: &'a mut Self::Buffers, ) -> Self::Response<'a>
Compute the dense response over view, writing into
buffers and returning a borrowed handle.
Sourcefn detect_corners(
&self,
response: &Self::Response<'_>,
params: &Self::Params,
refine_border: i32,
) -> Vec<Corner>
fn detect_corners( &self, response: &Self::Response<'_>, params: &Self::Params, refine_border: i32, ) -> Vec<Corner>
Extract corner peaks from response. Positions are in the
input-image frame (the same frame view was passed in at
Self::compute_response).
refine_border is an additional base-image-pixel margin
the implementor must keep around each accepted peak so that a
downstream image-domain refiner with that patch half-width
has full support. Passing 0 selects “no extra refiner
margin” — appropriate when refinement happens through a
separate stage that does its own bounds check. Whether the
implementor extends its own border (ChESS) or ignores the
argument (Radon — its NMS + Gaussian peak-fit already enforce
the support needed) is detector-specific.
Sourcefn compute_response_patch<'a>(
&self,
base: ImageView<'_>,
roi: (i32, i32, i32, i32),
params: &Self::Params,
buffers: &'a mut Self::Buffers,
) -> Self::Response<'a>
fn compute_response_patch<'a>( &self, base: ImageView<'_>, roi: (i32, i32, i32, i32), params: &Self::Params, buffers: &'a mut Self::Buffers, ) -> Self::Response<'a>
Compute the dense response over the sub-rectangle
[x0..x1) × [y0..y1) of base, where the ROI is given as the
tuple (x0, y0, x1, y1). The returned response is sized to
the ROI; any Corner positions produced from it by
Self::detect_corners are patch-local (origin = ROI’s
top-left), and the caller is responsible for shifting them
back into base-image coordinates by adding (x0, y0).
Implementors may reach outside the ROI to compute responses
near its borders (so that an ROI tile produces values
numerically identical to the full-frame response on the
overlapping interior). The shared buffers is reused across
calls.
Sourcefn roi_border(&self, params: &Self::Params) -> i32
fn roi_border(&self, params: &Self::Params) -> i32
Detector-specific safety border (in base-image pixels) the
orchestrator must keep around each seed when carving an ROI.
Typically the sum of the detector’s response-support radius
(e.g. ChESS ring radius, Radon ray radius) and its NMS
half-window — i.e. the minimum margin needed for
Self::compute_response_patch + Self::detect_corners to
return a non-trivial peak inside the ROI.
Sourcefn refine_peaks_on_image(
&self,
corners: Vec<Corner>,
image: ImageView<'_>,
response: &Self::Response<'_>,
refiner: &mut dyn CornerRefiner,
) -> Vec<Corner>
fn refine_peaks_on_image( &self, corners: Vec<Corner>, image: ImageView<'_>, response: &Self::Response<'_>, refiner: &mut dyn CornerRefiner, ) -> Vec<Corner>
Apply a detector-appropriate image-domain refinement step to
the peaks produced by Self::detect_corners.
The default subpixel refiners (crate::refine::Refiner
variants) expect a ResponseMap (center-of-mass,
Förstner) or an image patch (saddle-point, Radon-peak) keyed
to the detector’s response. ChESS forwards its
ResponseMap straight through; Radon’s
RadonResponseView does not fit the ResponseMap
contract (working-resolution layout, different coordinate
frame than the peak positions), so the Radon implementor
keeps the 3-point Gaussian peak fit from
Self::detect_corners as the subpixel position and skips
further refinement.
Provided Methods§
Sourcefn refines_on_image(&self) -> bool
fn refines_on_image(&self) -> bool
Whether Self::refine_peaks_on_image actually consumes the
orchestrator-supplied refiner. When false, the orchestrator
must not include the refiner’s patch radius in the per-seed
ROI margin — otherwise a no-op refiner choice would still
shrink the valid seed area near the image border (a tunable
silently coupling to an unused setting).
Default true matches the ChESS-style “refine on image”
contract; the Radon impl returns false because its
Self::refine_peaks_on_image is a no-op.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.