45template <ComputeData InputType = std::shared_ptr<Kakshya::SignalSourceContainer>,
46 ComputeData OutputType = std::vector<Kakshya::DataVariant>>
79 return "VisionExtractor";
84 return {
"bbox",
"contour_tight",
"contour_masked" };
107 error<std::out_of_range>(
110 std::source_location::current(),
111 "VisionExtractor: bbox index {} out of range ({})",
115 return {
b.x,
b.y,
b.w,
b.h };
120 error<std::out_of_range>(
123 std::source_location::current(),
124 "VisionExtractor: contour index {} out of range ({})",
128 float min_x = pts[0].x, max_x = pts[0].x;
129 float min_y = pts[0].y, max_y = pts[0].y;
130 for (
const auto& p : pts) {
140 return { min_x, min_y, max_x - min_x, max_y - min_y };
143 return { 0.F, 0.F, 1.F, 1.F };
151 const auto analysis_it =
input.
metadata.find(
"vision_analysis");
152 if (analysis_it !=
input.metadata.end() && analysis_it->second.has_value()) {
153 const auto& analysis = safe_any_cast_or_throw<VisionAnalysis>(
154 analysis_it->second);
157 const auto crop_w =
static_cast<uint32_t
>(
158 std::max(1.0F, std::round(nw *
static_cast<float>(analysis.w))));
159 const auto crop_h =
static_cast<uint32_t
>(
160 std::max(1.0F, std::round(nh *
static_cast<float>(analysis.h))));
166 ctx->set_push_constants(
167 CropPC { nx, ny, nw, nh, crop_w, crop_h });
177 const auto analysis_it =
input.
metadata.find(
"vision_analysis");
178 if (analysis_it ==
input.metadata.end() || !analysis_it->second.has_value()) {
179 error<std::runtime_error>(
182 std::source_location::current(),
183 "VisionExtractor: no vision_analysis in input metadata");
186 const auto& analysis = safe_any_cast_or_throw<VisionAnalysis>(
187 analysis_it->second);
189 if (analysis.pixel_image.empty()) {
190 error<std::runtime_error>(
193 std::source_location::current(),
194 "VisionExtractor: VisionAnalysis carries no pixel data");
197 const uint32_t w = analysis.w;
198 const uint32_t
h = analysis.h;
199 const auto channels =
static_cast<uint32_t
>(
200 analysis.pixel_image.size() / (
static_cast<size_t>(w) *
h));
206 const auto crop_w =
static_cast<uint32_t
>(
208 const auto crop_h =
static_cast<uint32_t
>(
211 const uint32_t stride = w * channels;
212 const uint32_t crop_stride = crop_w * channels;
213 std::vector<float> cropped(
static_cast<size_t>(crop_w) * crop_h * channels);
215 const float* src = analysis.pixel_image.data();
216 float* dst = cropped.data();
221 for (uint32_t row = 0; row < crop_h; ++row) {
223 dst +
static_cast<size_t>(row * crop_stride),
224 src + (
static_cast<size_t>(y0 + row) * stride) +
static_cast<size_t>(x0 * channels),
225 crop_stride *
sizeof(
float));
229 const auto& contour = analysis.frame.contours[
m_index];
230 const float origin_x = nx;
231 const float origin_y = ny;
232 const float scale_x = nw /
static_cast<float>(crop_w);
233 const float scale_y = nh /
static_cast<float>(crop_h);
235 std::span<float>(cropped),
236 crop_w, crop_h, channels,
238 origin_x, origin_y, scale_x, scale_y);
242 if constexpr (std::is_same_v<OutputType, std::vector<Kakshya::DataVariant>>) {
243 out.
data = std::vector<Kakshya::DataVariant> { std::move(cropped) };
245 out.
data = OperationHelper::reconstruct_from_double<OutputType>({}, {});
276 std::shared_ptr<Kakshya::SignalSourceContainer>,
277 std::vector<Kakshya::DataVariant>>;
281 std::vector<Kakshya::DataVariant>,
282 std::vector<Kakshya::DataVariant>>;
Core::GlobalInputConfig input
Contour extraction from binary float masks.
std::shared_ptr< GpuExecutionContext< InputType, OutputType > > m_gpu_backend
virtual output_type apply_operation_internal(const input_type &input, const ExecutionContext &context)
Internal execution method - ComputeMatrix can access this.
void set_output_dimensions(uint32_t w, uint32_t h)
Override the output storage image dimensions for the next dispatch.
GpuExecutionContext specialisation for image compute shaders.
@ ComputeMatrix
Compute operations (Yantra - algorithms, matrices, DSP)
@ Yantra
DSP algorithms, computational units, matrix operations, Grammar.
@ IMAGE_COLOR
2D RGB/RGBA image
@ IMAGE_2D
2D image (grayscale or single channel)
Region normalised_rect_to_region(float nx, float ny, float nw, float nh, uint32_t pixel_w, uint32_t pixel_h)
Convert a normalised image rectangle to a pixel-space Region.
void apply_contour_mask(std::span< float > pixels, uint32_t w, uint32_t h, uint32_t channels, const Contour &contour, float origin_x, float origin_y, float scale_x, float scale_y)
Zero all pixels in pixels that fall outside contour.
ExtractionType
Categories of extraction operations for discovery and organization.
@ REGION_BASED
Extract from spatial/temporal regions.
VisionExtractionMode
Selects the spatial mask used to crop pixels from a container.
@ BBOX
Crop the axis-aligned rectangle of a BoundingBox.
@ CONTOUR_MASKED
Crop the tight bounding rect of a Contour; zero pixels outside polygon.
@ CONTOUR_TIGHT
Crop the tight bounding rect of a Contour; no polygon mask.
static DataDimension spatial_2d(uint64_t width, uint64_t height)
Convenience constructor for a 2D spatial dimension.
std::vector< uint64_t > end_coordinates
Ending frame index (inclusive)
std::vector< uint64_t > start_coordinates
Starting frame index (inclusive)
Represents a point or span in N-dimensional space.
T data
The actual computation data.
std::vector< Kakshya::DataDimension > dimensions
Data dimensional structure.
Kakshya::DataModality modality
Data modality (audio, image, spectral, etc.)
std::unordered_map< std::string, std::any > metadata
Associated metadata.
Input/Output container for computation pipeline data flow with structure preservation.
std::vector< Kinesis::Vision::Contour > contours
std::vector< Kinesis::Vision::BoundingBox > boxes
Context information controlling how a compute operation executes.
Analysis result produced by VisionAnalyzer for one frame.