160{
167
169 cur_vec.assign(frame.begin(), frame.end());
170
173
177 std::vector<Keypoint> current_keypoints;
178
181
182 switch (step.op) {
184 uint32_t new_w = 0, new_h = 0;
186 w = new_w;
192 break;
193 }
194
199
200 if (wants_tracking) {
203 }
204
206 break;
207 }
208
214 break;
215 }
216
222 break;
223 }
224
226 const auto& p = get_params<ThresholdParams>(step.params, step.op);
229 break;
230 }
231
233 const auto& p = get_params<ThresholdAdaptiveParams>(step.params, step.op);
237 break;
238 }
239
244 std::span<float>(
slot_vec(nxt)).first(n));
247 break;
248 }
249
252 const float mn = m.minCoeff();
253 const float mx = m.maxCoeff();
254 if (mx > mn)
255 m = (m - mn) / (mx - mn);
257 break;
258 }
259
261 const auto& p = get_params<NormalizeRangeParams>(step.params, step.op);
262 if (p.hi > p.lo) {
264 m = ((m - p.lo) / (p.hi - p.lo)).
max(0.0F).min(1.0F);
265 }
267 break;
268 }
269
271 const auto& p = get_params<GaussianBlurParams>(step.params, step.op);
276 break;
277 }
278
280 const auto& p = get_params<FilterSeparableParams>(step.params, step.op);
284 break;
285 }
286
288 GradientResult grad;
291
294 slot_map_mut(nxt, en) = (dx.square() + dy.square()).sqrt();
296
297 if (peak > 0.0F)
299
303 grad.angle.resize(static_cast<size_t>(en));
304
305 std::transform(std::execution::par_unseq,
308 [](float gx, float gy) { return std::atan2(gy, gx); });
309
312 break;
313 }
314
316 GradientResult grad;
319
322 slot_map_mut(nxt, en) = (dx.square() + dy.square()).sqrt();
323
325 if (peak > 0.0F)
327
331 grad.angle.resize(static_cast<size_t>(en));
332
333 std::transform(std::execution::par_unseq,
336 [](float gx, float gy) { return std::atan2(gy, gx); });
337
340 break;
341 }
342
344 const auto& p = get_params<CannyParams>(step.params, step.op);
348 break;
349 }
350
352 const auto& p = get_params<MorphParams>(step.params, step.op);
356 break;
357 }
358
360 const auto& p = get_params<MorphParams>(step.params, step.op);
364 break;
365 }
366
368 const auto& p = get_params<MorphParams>(step.params, step.op);
372 break;
373 }
374
376 const auto& p = get_params<MorphParams>(step.params, step.op);
380 break;
381 }
382
384 const auto& p = get_params<MorphParams>(step.params, step.op);
388 break;
389 }
390
392 const auto& p = get_params<ConnectedComponentsParams>(step.params, step.op);
397
400 if (p.with_colors) {
404 } else if (!contours_follow) {
408 }
409
410 if (!p.export_labels && !contours_follow)
411 components.label_map.clear();
413 break;
414 }
415
420 "VisionExecutor: FindContours requires ConnectedComponents as the immediately preceding step");
421 return {};
422 }
423
425 if (!components) {
427 "VisionExecutor: FindContours requires a connected-component result");
428 return {};
429 }
430
431 const auto& p = get_params<FindContoursParams>(step.params, step.op);
433 p.min_area, p.max_contours, p.max_points_per_contour);
434 if (p.as_image) {
439 } else {
444 }
445 break;
446 }
447
449 const auto& p = get_params<HarrisParams>(step.params, step.op);
459 break;
460 }
461
463 const auto& p = get_params<ExtractPeaksParams>(step.params, step.op);
467 if (peaks_feed_track)
468 current_keypoints = kpts;
469 else
471
472 if (wants_tracking && !peaks_feed_track)
474
476 if (!peaks_feed_track) {
480 }
481 break;
482 }
483
485 const auto& p = get_params<TrackKeypointsParams>(step.params, step.op);
488 const auto curr_gray = peaks_feed_track
491 auto& prev_vec = std::get<std::vector<float>>(
m_prev_gray);
492 std::vector<TrackResult> tracked;
494 std::vector<glm::vec2> prev_pos;
498
500 prev_vec, curr_gray,
502 p.window_radius, p.max_iterations,
503 p.eigen_threshold, p.error_threshold,
504 p.forward_backward_threshold);
505 }
506
507 if (peaks_feed_track) {
510 } else {
512 }
517 break;
518 }
519
522 break;
524 SnapshotEntry entry;
526 entry.w = w;
530 break;
531 }
532
535 "VisionExecutor: OpticalFlowDense has no CPU implementation");
536 break;
537 }
538 }
539
542
545
549}
#define MF_ERROR(comp, ctx,...)
std::optional< glm::vec3 > position
std::vector< float > * out
std::array< Kakshya::DataVariant, k_slot_count > m_slots
Eigen::Map< Eigen::ArrayXf > slot_map_mut(size_t i, Eigen::Index n) noexcept
Zero-copy mutable Eigen::Map<ArrayXf> over slot i.
std::vector< float > m_curr_gray_cache
static constexpr size_t k_slot_iyy
static constexpr size_t k_slot_syy
static constexpr size_t k_slot_dx
std::vector< float > & slot_vec(size_t i) noexcept
Mutable reference to the vector<float> inside slot i.
static constexpr size_t k_slot_sxy
Kakshya::DataVariant m_prev_gray
CpuVisionPass m_pass
Walk state for the current run: sequence position, geometry, working slot index, and the result under...
static constexpr size_t k_slot_dy
static constexpr size_t k_slot_ixy
static constexpr size_t k_slot_ixx
static constexpr size_t k_slot_tmp
void ensure_slots(uint32_t w, uint32_t h)
Ensure all slots are sized to n_pixels floats.
static constexpr size_t k_slot_cur
const std::vector< float > & gaussian_kernel(float sigma)
Return a reference to the precomputed 1D Gaussian kernel for sigma.
static constexpr size_t k_slot_sxx
static constexpr size_t k_slot_nxt
std::vector< Keypoint > m_prev_keypoints
Eigen::Map< const Eigen::ArrayXf > slot_map(size_t i, Eigen::Index n) const noexcept
Zero-copy read-only Eigen::Map<const ArrayXf> over slot i.
@ Runtime
General runtime operations (default fallback)
@ Kinesis
General mathematical and physics algorithns.
std::vector< double > peak(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Peak amplitude per window.
void rgba_to_gray(std::span< const float > rgba, std::span< float > dst, uint32_t w, uint32_t h)
Convert RGBA to luminance gray using BT.601 coefficients.
std::vector< float > filter_separable(std::span< const float > src, uint32_t w, uint32_t h, std::span< const float > kernel_x, std::span< const float > kernel_y)
Apply a separable 2D filter via two 1D passes.
std::vector< float > canny(std::span< const float > gray, uint32_t w, uint32_t h, float sigma, float low_threshold, float high_threshold)
Canny edge detector.
void gray_to_rgba(std::span< const float > gray, std::span< float > dst, uint32_t w, uint32_t h)
Global threshold writing into caller-supplied buffer.
std::vector< Keypoint > extract_peaks(std::span< const float > response, uint32_t w, uint32_t h, float threshold, uint32_t nms_radius)
Extract peaks from a response map via non-maximum suppression.
void erode(std::span< const float > mask, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Erosion writing into dst.
std::vector< float > harris_response(std::span< const float > gray, uint32_t w, uint32_t h, float k, float sigma)
Compute the Harris corner response map.
ComponentResult connected_components(std::span< const float > mask, uint32_t w, uint32_t h)
Label connected foreground components in a binary mask.
void rgba_to_hsv(std::span< const float > rgba, std::span< float > dst, uint32_t w, uint32_t h)
Convert RGBA to HSV writing into caller-supplied buffer.
void close(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological closing writing into dst.
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.
std::vector< Contour > find_contours(std::span< const float > mask, uint32_t w, uint32_t h, float min_area, uint32_t max_contours, uint32_t max_points_per_contour)
Extract outer and hole contours from a binary mask.
void dilate(std::span< const float > mask, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Dilation writing into dst.
bool tracks_keypoints(const VisionSequence &seq)
True when any step tracks keypoints.
void scharr(std::span< const float > gray, std::span< float > dx, std::span< float > dy, std::span< float > tmp, uint32_t w, uint32_t h)
Scharr gradient writing dx and dy into caller-supplied buffers.
std::vector< TrackResult > track_keypoints(std::span< const float > prev_gray, std::span< const float > curr_gray, uint32_t w, uint32_t h, std::span< const glm::vec2 > prev_points, uint32_t window_radius, uint32_t max_iterations, float eigen_threshold, float error_threshold, float forward_backward_threshold)
Track keypoints from prev_gray to curr_gray via Lucas-Kanade.
void threshold_otsu(std::span< const float > gray, std::span< float > dst)
Otsu threshold writing into caller-supplied buffer.
void threshold_adaptive(std::span< const float > gray, std::span< float > dst, uint32_t w, uint32_t h, uint32_t block_size, float offset)
Adaptive threshold writing into caller-supplied buffer.
void downsample_2x(std::span< const float > src, std::span< float > dst, uint32_t w, uint32_t h, uint32_t &new_w, uint32_t &new_h)
2x box-filter downsample writing into a caller-supplied buffer.
void morph_gradient(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological gradient (dilate - erode) writing into dst.
void open(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological opening writing into dst.
std::shared_ptr< Vruta::Routine > sequence(std::vector< std::pair< double, std::function< void()> > > sequence, Vruta::ProcessingToken token)
Creates a temporal sequence that executes callbacks at specified time offsets.
void begin(const VisionSequence &seq, uint32_t width, uint32_t height)
Reset the walk band for a fresh run.
const VisionStep & step() const noexcept
size_t plane_size() const noexcept
const VisionStep * behind(size_t offset=1) const noexcept
Op at offset steps back, or nullptr before the start.
const VisionStep * ahead(size_t offset=1) const noexcept
Op at offset steps ahead, or nullptr past the end.
void set_geometry(uint32_t width, uint32_t height) noexcept
std::vector< SnapshotEntry > snapshots
Kakshya::DataVariant pixel_image
StructuredOutput structured