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

◆ track_keypoints() [1/2]

MAYAFLUX_API std::vector< TrackResult > MayaFlux::Kinesis::Vision::track_keypoints ( std::span< const float >  prev_gray,
std::span< const float >  curr_gray,
std::span< const float >  grad_dx,
std::span< const float >  grad_dy,
uint32_t  w,
uint32_t  h,
std::span< const glm::vec2 >  prev_points,
uint32_t  window_radius = 7,
uint32_t  max_iterations = 20,
float  eigen_threshold = 1e-4F,
float  error_threshold = 0.3F,
float  forward_backward_threshold = 0.0F 
)

Track keypoints using a pre-computed Sobel gradient of prev_gray.

Identical to the four-parameter overload but accepts caller-supplied dx and dy of the previous frame, avoiding recomputation when the gradient is already cached. dx and dy must be the Sobel gradient of prev_gray at the same w x h resolution.

Parameters
prev_grayPrevious frame, single-channel float, size w * h.
curr_grayCurrent frame, single-channel float, size w * h.
grad_dxHorizontal Sobel gradient of prev_gray, size w * h.
grad_dyVertical Sobel gradient of prev_gray, size w * h.
wImage width in pixels.
hImage height in pixels.
prev_pointsPoints to track in normalised [0, 1] coordinates.
window_radiusHalf-size of the tracking patch in pixels.
max_iterationsMaximum Newton-Raphson iterations per point.
eigen_thresholdMinimum eigenvalue for structure tensor validity.
error_thresholdMaximum residual error to accept a track.
forward_backward_thresholdMaximum return error in pixels; zero disables the check.
Returns
TrackResult per input point, same order.

Definition at line 192 of file OpticalFlow.cpp.

204{
205 const size_t np = prev_points.size();
206 std::vector<TrackResult> results(np);
207 std::vector<float> curr_dx;
208 std::vector<float> curr_dy;
209 if (forward_backward_threshold > 0.0F) {
210 auto grad = sobel(curr_gray, w, h);
211 curr_dx = std::move(grad.dx);
212 curr_dy = std::move(grad.dy);
213 }
214
215 std::for_each(std::execution::par_unseq,
216 std::views::iota(size_t { 0 }, np).begin(),
217 std::views::iota(size_t { 0 }, np).end(),
218 [&](size_t i) {
219 auto result = lk_point(
220 prev_gray, curr_gray,
221 grad_dx, grad_dy,
222 w, h,
223 prev_points[i],
224 window_radius,
225 max_iterations,
226 eigen_threshold,
227 error_threshold);
228
229 if (forward_backward_threshold > 0.0F && result.tracked) {
230 const auto reverse = lk_point(
231 curr_gray, prev_gray,
232 curr_dx, curr_dy,
233 w, h,
234 result.position,
235 window_radius,
236 max_iterations,
237 eigen_threshold,
238 error_threshold);
239 const glm::vec2 error_px = (reverse.position - prev_points[i])
240 * glm::vec2(static_cast<float>(w), static_cast<float>(h));
241 if (!reverse.tracked || glm::length(error_px) > forward_backward_threshold) {
242 result.position = prev_points[i];
243 result.error = 1.0F;
244 result.tracked = false;
245 }
246 }
247 result.previous = prev_points[i];
248 results[i] = result;
249 });
250
251 return results;
252}
uint32_t h
Definition InkPress.cpp:29
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:64

References h, and sobel().

+ Here is the call graph for this function: