MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ harris_response() [2/2]

MAYAFLUX_API std::vector< float > MayaFlux::Kinesis::Vision::harris_response ( std::span< const float >  gray,
uint32_t  w,
uint32_t  h,
float  k = 0.04F,
float  sigma = 1.0F 
)

Compute the Harris corner response map.

For each pixel computes R = det(M) - k * trace(M)^2 where M is the structure tensor accumulated over a sigma-weighted window. Negative responses are clamped to 0. Output is normalised to [0, 1] by the observed peak response.

Structure tensor gradients are computed via a 3x3 Sobel operator. The tensor is smoothed with a Gaussian of standard deviation sigma before computing det and trace.

Parameters
graySingle-channel float span, size must be w * h.
wImage width in pixels.
hImage height in pixels.
kHarris sensitivity parameter. Typical range [0.04, 0.06].
sigmaGaussian smoothing sigma for structure tensor. Must be > 0.
Returns
Response map float vector of length w * h, values in [0, 1].

Definition at line 19 of file Harris.cpp.

22{
23 const size_t n = static_cast<size_t>(w) * h;
24
25 auto grad = sobel(gray, w, h);
26
27 std::vector<float> ixx(n), iyy(n), ixy(n);
28
29 P::for_each(P::par_unseq,
30 std::views::iota(size_t { 0 }, n).begin(),
31 std::views::iota(size_t { 0 }, n).end(),
32 [&](size_t i) {
33 const float dx = grad.dx[i];
34 const float dy = grad.dy[i];
35 ixx[i] = dx * dx;
36 iyy[i] = dy * dy;
37 ixy[i] = dx * dy;
38 });
39
40 auto sxx = gaussian_blur(ixx, w, h, sigma);
41 auto syy = gaussian_blur(iyy, w, h, sigma);
42 auto sxy = gaussian_blur(ixy, w, h, sigma);
43
44 std::vector<float> response(n);
45
46 P::for_each(P::par_unseq,
47 std::views::iota(size_t { 0 }, n).begin(),
48 std::views::iota(size_t { 0 }, n).end(),
49 [&](size_t i) {
50 const float det = sxx[i] * syy[i] - sxy[i] * sxy[i];
51 const float trace = sxx[i] + syy[i];
52 response[i] = std::max(0.0F, det - k * trace * trace);
53 });
54
55 const float peak = *std::ranges::max_element(response);
56 if (peak > 0.0F) {
57 const float inv = 1.0F / peak;
58 P::transform(P::par_unseq,
59 response.begin(), response.end(), response.begin(),
60 [inv](float v) { return v * inv; });
61 }
62
63 return response;
64}
uint32_t h
Definition InkPress.cpp:28
float k
float sigma
void sobel(std::span< const float > gray, std::span< float > dx, std::span< float > dy, std::span< float > tmp, uint32_t w, uint32_t h)
Sobel gradient writing dx and dy into caller-supplied buffers.
Definition Gradient.cpp:66
double peak(const std::vector< double > &data)
Find peak amplitude in single-channel data.
Definition Yantra.cpp:268

References gaussian_blur(), h, k, MayaFlux::peak(), sigma, and sobel().

Referenced by MayaFlux::Kinesis::Vision::VisionExecutor::run().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: