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

◆ compute_shapes()

void MayaFlux::Yantra::VisionAnalyzer::compute_shapes ( Kinesis::Vision::FindElementsAnalysis &  fe,
uint32_t  w,
uint32_t  h 
)
private

Shape descriptors (element_shape.comp) and nearest-neighbour distances (nearest_neighbor.comp) over fe.boxes, filled in place.

No-op when fe.boxes is empty.

Definition at line 204 of file VisionAnalyzer.cpp.

205{
206 const auto n = fe.boxes.size();
207 fe.shapes.assign(n, {});
208 fe.nearest_neighbor_distance_px.assign(n, 0.0F);
209 if (n == 0)
210 return;
211
212 const auto fw = static_cast<float>(w);
213 const auto fh = static_cast<float>(h);
214
215 std::vector<float> element_data;
216 element_data.reserve(n * 4);
217 std::vector<float> centroid_data;
218 centroid_data.reserve(n * 2);
219
220 for (const auto& b : fe.boxes) {
221 const auto it = std::ranges::find_if(fe.contours,
222 [&](const auto& c) { return c.label_id == b.label_id; });
223 const float area_px = (it != fe.contours.end()) ? it->area * fw * fh : 0.0F;
224 const float perimeter_px = (it != fe.contours.end()) ? it->perimeter : 0.0F;
225 element_data.push_back(area_px);
226 element_data.push_back(perimeter_px);
227 element_data.push_back(b.w * fw);
228 element_data.push_back(b.h * fh);
229
230 centroid_data.push_back((b.x + b.w * 0.5F) * fw);
231 centroid_data.push_back((b.y + b.h * 0.5F) * fh);
232 }
233
234 if (!m_shape_ctx) {
235 m_shape_ctx = std::make_shared<ShaderExecutionContext<>>(
237 .shader_path = "element_shape.comp.spv",
238 .workgroup_size = { 256, 1, 1 },
239 .push_constant_size = sizeof(TrackReducePC) });
240 }
241 m_shape_ctx->input(0, element_data)
242 .output(1, n * sizeof(glm::vec2))
243 .push(TrackReducePC { .count = static_cast<uint32_t>(n) });
244
245 const auto shape_output = m_shape_ctx->execute(Datum<std::vector<Kakshya::DataVariant>> {}, ExecutionContext {});
246 const auto shape_raw = ShaderExecutionContext<>::read_output<float>(shape_output, 1);
247 for (size_t i = 0; i < n && (i + 1) * 2 <= shape_raw.size(); ++i) {
248 fe.shapes[i].compactness = shape_raw[i * 2];
249 fe.shapes[i].aspect_ratio = shape_raw[i * 2 + 1];
250 }
251
252 if (n < 2)
253 return;
254
255 if (!m_neighbor_ctx) {
256 m_neighbor_ctx = std::make_shared<ShaderExecutionContext<>>(
258 .shader_path = "nearest_neighbor.comp.spv",
259 .workgroup_size = { 256, 1, 1 },
260 .push_constant_size = sizeof(TrackReducePC) });
261 }
262 m_neighbor_ctx->input(0, centroid_data)
263 .output(1, n * sizeof(float))
264 .push(TrackReducePC { .count = static_cast<uint32_t>(n) });
265
266 const auto dist_output = m_neighbor_ctx->execute(Datum<std::vector<Kakshya::DataVariant>> {}, ExecutionContext {});
267 const auto dist_raw = ShaderExecutionContext<>::read_output<float>(dist_output, 1);
268 for (size_t i = 0; i < n && i < dist_raw.size(); ++i)
269 fe.nearest_neighbor_distance_px[i] = dist_raw[i];
270}
uint32_t h
Definition InkPress.cpp:29
size_t b
std::shared_ptr< ShaderExecutionContext<> > m_shape_ctx
std::shared_ptr< ShaderExecutionContext<> > m_neighbor_ctx
Portal::Graphics::GpuComputeConfig GpuComputeConfig

References b, MayaFlux::Kinesis::Vision::FindElementsAnalysis::boxes, MayaFlux::Kinesis::Vision::FindElementsAnalysis::contours, h, m_neighbor_ctx, m_shape_ctx, MayaFlux::Kinesis::Vision::FindElementsAnalysis::nearest_neighbor_distance_px, MayaFlux::Portal::Graphics::GpuComputeConfig::shader_path, and MayaFlux::Kinesis::Vision::FindElementsAnalysis::shapes.

Referenced by assemble().

+ Here is the caller graph for this function: