7 VisionSequence find_elements_chain(
const FindElementsParams& r)
9 auto components = r.components;
10 components.export_boxes =
true;
12 VisionSequence::Builder builder;
13 switch (r.segmentation.space) {
15 builder.rgba_to_gray();
18 builder.rgba_to_hsv();
24 std::visit([&builder](
const auto& method) {
25 using T = std::decay_t<
decltype(method)>;
26 if constexpr (std::is_same_v<T, OtsuParams>) {
27 builder.threshold_otsu(method);
28 }
else if constexpr (std::is_same_v<T, ThresholdAdaptiveParams>) {
29 builder.threshold_adaptive(method);
31 builder.threshold(method);
34 r.segmentation.method);
37 .connected_components(components)
38 .find_contours(r.contours)
42 VisionSequence track_objects_chain(
const TrackObjectsParams& r)
44 auto harris = r.harris;
46 harris.region = r.region;
47 peaks.region = r.region;
49 return VisionSequence::Builder {}
51 .harris_response(harris)
53 .track_keypoints(r.track)
57 VisionSequence detect_features_chain(
const DetectFeaturesParams& r)
59 auto harris = r.harris;
61 harris.region = r.region;
62 peaks.region = r.region;
64 return VisionSequence::Builder {}
66 .harris_response(harris)
71 VisionSequence detect_edges_chain(
const DetectEdgesParams& r)
73 return VisionSequence::Builder {}
79 VisionSequence estimate_motion_chain(
const EstimateMotionParams& r)
81 return VisionSequence::Builder {}
83 .optical_flow_dense(r.flow)
87 VisionSequence measure_appearance_chain(
const MeasureAppearanceParams&)
89 return VisionSequence::Builder {}
100 return [](
const VisionResult& r) {
return r.
gray; };
102 return [](
const VisionResult& r) {
return r.images.rgba_to_hsv; };
104 return [](
const VisionResult& r) {
return r.images.confine; };
106 return [](
const VisionResult& r) {
return r.images.harris_response; };
119 bool overwrites_shared_images(
VisionOp op)
133 bool preserves_shared_images(
const std::vector<VisionStep>& steps,
size_t from)
135 return std::none_of(steps.begin() +
static_cast<std::ptrdiff_t
>(std::min(from, steps.size())), steps.end(),
136 [](
const VisionStep& s) { return overwrites_shared_images(s.op); });
149 size_t shared_prefix_length(
150 const std::vector<VisionStep>& reference,
151 const std::vector<VisionStep>& candidate)
154 while (n < reference.size() && n < candidate.size()) {
155 if (!seed_accessor_for(candidate[n].op))
163 if (n > 0 && !(preserves_shared_images(reference, n) && preserves_shared_images(candidate, n)))
172 std::vector<VisionStep> flow_lane;
173 std::vector<std::vector<VisionStep>> other_chains;
176 auto steps = std::move(
chain.steps);
178 steps.erase(steps.begin());
179 flow_lane.insert(flow_lane.end(),
180 std::make_move_iterator(steps.begin()),
181 std::make_move_iterator(steps.end()));
185 append_to_flow_lane(track_objects_chain(*query.
track_objects));
191 other_chains.push_back(find_elements_chain(*query.
find_elements).steps);
194 other_chains.push_back(detect_features_chain(*query.
detect_features).steps);
200 other_chains.push_back(detect_edges_chain(*query.
detect_edges).steps);
202 std::vector<ResolvedSequence> sequences;
203 sequences.reserve(1 + other_chains.size());
204 std::optional<size_t> reference_index;
206 if (!flow_lane.empty()) {
211 std::vector<ResolvedSequence> seeded;
212 std::vector<ResolvedSequence> unseeded;
214 for (
auto& steps : other_chains) {
215 if (!reference_index) {
221 const auto& reference = sequences[*reference_index].sequence.steps;
223 const size_t shared = shared_prefix_length(reference, steps);
226 resolved.
seed_field = seed_accessor_for(reference[shared - 1].op);
227 steps.erase(steps.begin(), steps.begin() +
static_cast<std::ptrdiff_t
>(shared));
230 (resolved.
seed_field ? seeded : unseeded).push_back(std::move(resolved));
233 sequences.insert(sequences.end(), std::make_move_iterator(seeded.begin()), std::make_move_iterator(seeded.end()));
234 sequences.insert(sequences.end(), std::make_move_iterator(unseeded.begin()), std::make_move_iterator(unseeded.end()));
BufferProcessingChain * chain
Per-intent parameters and resolution into a set of VisionSequences.
@ DetectFeatures
Distinctive points with no persistence claim (HarrisResponse into ExtractPeaks alone).
@ EstimateMotion
Dense, whole-field motion with no identity claim (OpticalFlowDense).
@ DetectEdges
Boundary/gradient detection (Sobel, Scharr, Canny).
@ MeasureAppearance
Photometric/statistical characterization of the frame itself, independent of anything found in it.
@ TrackObjects
Maintain identity of specific points across frames (ExtractPeaks into TrackKeypoints).
@ FindElements
Localize discrete things in the frame (thresholding/morphology into ConnectedComponents/FindContours)...
size_t hash_vision_step(VisionOp op, const VisionParams ¶ms)
Hash a VisionStep's op and parameters together.
VisionOp
Named operations available in a VisionSequence.
std::vector< ResolvedSequence > resolve(const VisionQuery &query)
Resolve a VisionQuery into the ResolvedSequences needed to satisfy every active intent.
std::shared_ptr< Core::VKImage >(*)(const VisionResult &) SeedAccessor
Picks a VisionResult field to seed a later sequence's image argument with, instead of the query's own...
One VisionSequence to run, and where its image argument comes from.
std::optional< MeasureAppearanceParams > measure_appearance
std::optional< TrackObjectsParams > track_objects
std::optional< FindElementsParams > find_elements
std::optional< EstimateMotionParams > estimate_motion
std::optional< DetectEdgesParams > detect_edges
std::optional< DetectFeaturesParams > detect_features
Composed query: which VisionIntents are active, and each active one's parameters.
std::shared_ptr< Core::VKImage > gray
Output of a RgbaToGray step in this sequence, or null.
std::vector< VisionStep > steps
Ordered VisionSteps and the backend chosen to execute them.