22 const T*
ptr = std::get_if<T>(&p);
24 error<std::logic_error>(
26 std::source_location::current(),
27 "VisionExecutor: parameter type mismatch for op {}",
44 const size_t n =
static_cast<size_t>(w) *
h;
47 m_slots[i] = std::vector<float>(n, 0.0F);
59 const auto key = std::bit_cast<uint32_t>(
sigma);
64 const auto radius =
static_cast<int32_t
>(std::ceil(3.0F *
sigma));
65 const int32_t size = 2 *
radius + 1;
66 const float inv_2s2 = 1.0F / (2.0F *
sigma *
sigma);
68 std::vector<float>
k(
static_cast<size_t>(size));
71 const float v = std::exp(-
static_cast<float>(i * i) * inv_2s2);
72 k[
static_cast<size_t>(i +
radius)] = v;
76 auto kmap = Eigen::Map<Eigen::ArrayXf>(
k.data(),
static_cast<Eigen::Index
>(
k.size()));
99 std::span<const float> frame,
100 uint32_t w, uint32_t
h)
109 uint32_t channels = 4;
112 cur_vec.assign(frame.begin(), frame.end());
116 auto en =
static_cast<Eigen::Index
>(
static_cast<size_t>(w) *
h);
122 for (
const auto& step : sequence.steps) {
126 uint32_t new_w = 0, new_h = 0;
132 en =
static_cast<Eigen::Index
>(
static_cast<size_t>(w) *
h);
143 if (sequence.tracks_keypoints && !sequence.track_follows_peaks) {
145 slot_vec(cur).begin() +
static_cast<size_t>(w) *
h);
169 const auto& p = get_params<ThresholdParams>(step.params, step.op);
176 const auto& p = get_params<ThresholdAdaptiveParams>(step.params, step.op);
192 const float mn = m.minCoeff();
193 const float mx = m.maxCoeff();
195 m = (m - mn) / (mx - mn);
201 const auto& p = get_params<NormalizeRangeParams>(step.params, step.op);
204 m = ((m - p.lo) / (p.hi - p.lo)).max(0.0F).min(1.0F);
211 const auto& p = get_params<GaussianBlurParams>(step.params, step.op);
220 const auto& p = get_params<FilterSeparableParams>(step.params, step.op);
234 slot_map_mut(nxt, en) = (dx.square() + dy.square()).sqrt();
243 grad.
angle.resize(
static_cast<size_t>(en));
245 P::transform(P::par_unseq,
248 [](
float gx,
float gy) { return std::atan2(gy, gx); });
262 slot_map_mut(nxt, en) = (dx.square() + dy.square()).sqrt();
271 grad.
angle.resize(
static_cast<size_t>(en));
273 P::transform(P::par_unseq,
276 [](
float gx,
float gy) { return std::atan2(gy, gx); });
284 const auto& p = get_params<CannyParams>(step.params, step.op);
292 const auto& p = get_params<MorphParams>(step.params, step.op);
300 const auto& p = get_params<MorphParams>(step.params, step.op);
308 const auto& p = get_params<MorphParams>(step.params, step.op);
316 const auto& p = get_params<MorphParams>(step.params, step.op);
324 const auto& p = get_params<MorphParams>(step.params, step.op);
332 const size_t n =
static_cast<size_t>(w) *
h;
334 std::span<const float>(
slot_vec(cur)).subspan(0, n),
343 const auto& p = get_params<FindContoursParams>(step.params, step.op);
344 const size_t n =
static_cast<size_t>(w) *
h;
346 std::span<const float>(
slot_vec(cur)).subspan(0, n),
347 w,
h, p.min_area, p.max_contours);
355 const auto& p = get_params<HarrisParams>(step.params, step.op);
369 const auto& p = get_params<ExtractPeaksParams>(step.params, step.op);
373 if (sequence.tracks_keypoints && !sequence.track_follows_peaks)
377 if (!sequence.track_follows_peaks) {
386 const auto& p = get_params<TrackKeypointsParams>(step.params, step.op);
388 auto& prev_vec = std::get<std::vector<float>>(
m_prev_gray);
391 result.
structured = std::vector<TrackResult> {};
398 std::vector<glm::vec2> prev_pos;
401 prev_pos.push_back(kp.position);
406 p.window_radius, p.max_iterations,
407 p.eigen_threshold, p.error_threshold);
420 const size_t n =
static_cast<size_t>(w) *
h * channels;
426 result.
snapshots.push_back(std::move(entry));
Contour extraction from binary float masks.
Gradient and edge detection on normalised float image spans.
Harris corner detection and non-maximum suppression.
2D spatial filtering on normalised float image spans.
Sparse optical flow via Lucas-Kanade tracker.
Pointwise pixel operations for MayaFlux::Kinesis::Vision.
Dispatch engine for VisionSequence execution.
Binary morphological operations on normalised float masks.
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.
void reset()
Clear stored inter-frame state.
static constexpr size_t k_slot_sxy
std::unordered_map< uint32_t, std::vector< float > > m_kernel_cache
Kakshya::DataVariant m_prev_gray
VisionResult run(const VisionSequence &sequence, std::span< const float > frame, uint32_t w, uint32_t h)
Execute a VisionSequence on one frame.
static constexpr size_t k_slot_count
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.
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.
std::vector< Contour > find_contours(std::span< const float > mask, uint32_t w, uint32_t h, float min_area, uint32_t max_contours)
Extract outer contours from a binary mask.
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::variant< std::monostate, ThresholdParams, ThresholdAdaptiveParams, NormalizeRangeParams, GaussianBlurParams, FilterSeparableParams, CannyParams, MorphParams, HarrisParams, ExtractPeaksParams, TrackKeypointsParams, ConnectedComponentsParams, FindContoursParams > VisionParams
Parameter variant covering all ops that carry parameters.
void dilate(std::span< const float > mask, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Dilation writing into dst.
VisionOp
Named operations available in a VisionSequence.
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)
Track keypoints from prev_gray to curr_gray via Lucas-Kanade.
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.
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.
constexpr std::string_view enum_to_string(EnumType value) noexcept
Universal enum to string converter using magic_enum (original case)
double peak(const std::vector< double > &data)
Find peak amplitude in single-channel data.
std::vector< float > angle
Gradient angle in radians, [-pi, pi].
std::vector< float > magnitude
Gradient magnitude, normalised to [0, 1].
std::vector< float > dx
Horizontal gradient component.
std::vector< float > dy
Vertical gradient component.
Gradient maps produced by Sobel and Scharr operators.
std::vector< float > pixels
Pixel buffer captured mid-pipeline by a Snapshot step.
std::vector< SnapshotEntry > snapshots
Kakshya::DataVariant pixel_image
StructuredOutput structured
Result of executing a VisionSequence on one frame.
Ordered sequence of VisionSteps describing a complete vision pipeline.