Scroll Top

Videoflow (default)

C++ (Windows, Linux, MacOS / CUDA and Metal accelerated) port of VideoFlow. This is a bidirectional optical flow model making better use of temporal cues.

Example Input & Outputs

Inputs Outputs
Input
Frame 0
Input
Frame 1
Input
Frame 2
Input
Optical Flow Frame 1 to 0
Input
Optical Flow Frame 1 to 2

Demo Code

 1#include "blace_ai.h"
 2#include "videoflow_v1_default_v1_ALL_export_version_v17.h"
 3#include <opencv2/opencv.hpp>
 4
 5int main() {
 6  // register model at server
 7  blace::util::registerModel(videoflow_v1_default_v1_ALL_export_version_v17,
 8                             blace::util::getPathToExe());
 9
10  auto exe_path = blace::util::getPathToExe();
11  auto frame_0_op = CONSTRUCT_OP_GET(blace::ops::FromImageFileOp(
12      (exe_path / "videoflow_frame_0.png").string()));
13  auto frame_1_op = CONSTRUCT_OP_GET(blace::ops::FromImageFileOp(
14      (exe_path / "videoflow_frame_1.png").string()));
15  auto frame_2_op = CONSTRUCT_OP_GET(blace::ops::FromImageFileOp(
16      (exe_path / "videoflow_frame_2.png").string()));
17
18  // interpolate to half size to save memory
19  frame_0_op = CONSTRUCT_OP_GET(blace::ops::Interpolate2DOp(
20      frame_0_op, 540, 960, blace::ml_core::BILINEAR, false, true));
21  frame_1_op = CONSTRUCT_OP_GET(blace::ops::Interpolate2DOp(
22      frame_1_op, 540, 960, blace::ml_core::BILINEAR, false, true));
23  frame_2_op = CONSTRUCT_OP_GET(blace::ops::Interpolate2DOp(
24      frame_2_op, 540, 960, blace::ml_core::BILINEAR, false, true));
25
26  // construct model inference arguments
27  blace::ml_core::InferenceArgsCollection infer_args;
28  infer_args.inference_args.device = blace::util::get_accelerator().value();
29  infer_args.inference_args.use_half = false;
30
31  // construct inference operation. the model returns two values, flow 1->0 and
32  // flow 1->2
33  auto flow_1_to_0 = CONSTRUCT_OP_GET(blace::ops::InferenceOp(
34      videoflow_v1_default_v1_ALL_export_version_v17_IDENT,
35      {frame_0_op, frame_1_op, frame_2_op}, infer_args, 0));
36  auto flow_1_to_2 = CONSTRUCT_OP_GET(blace::ops::InferenceOp(
37      videoflow_v1_default_v1_ALL_export_version_v17_IDENT,
38      {frame_0_op, frame_1_op, frame_2_op}, infer_args, 1));
39
40  // normalize optical flow to zero-one range for plotting. The model returns
41  // relative offsets in -1 to 1 pixel space, so the raw values are to small to
42  // plot
43  flow_1_to_0 = CONSTRUCT_OP_GET(blace::ops::NormalizeToZeroOneOP(flow_1_to_0));
44  flow_1_to_0 =
45      CONSTRUCT_OP_GET(blace::ops::ToColorOp(flow_1_to_0, blace::ml_core::RGB));
46
47  flow_1_to_2 = CONSTRUCT_OP_GET(blace::ops::NormalizeToZeroOneOP(flow_1_to_2));
48  flow_1_to_2 =
49      CONSTRUCT_OP_GET(blace::ops::ToColorOp(flow_1_to_2, blace::ml_core::RGB));
50
51  // construct evaluator and evaluate to opencv mat
52  blace::computation_graph::GraphEvaluator evaluator_0(flow_1_to_0);
53  auto flow_1_to_0_cv = evaluator_0.evaluateToCVMat().value();
54  blace::computation_graph::GraphEvaluator evaluator_1(flow_1_to_2);
55  auto flow_1_to_2_cv = evaluator_1.evaluateToCVMat().value();
56
57  // multipy for for plotting
58  flow_1_to_0_cv *= 255;
59  flow_1_to_2_cv *= 255;
60
61  cv::imwrite((exe_path / "optical_flow_1_to_0.png").string(), flow_1_to_0_cv);
62  cv::imwrite((exe_path / "optical_flow_1_to_2.png").string(), flow_1_to_2_cv);
63
64  // unload all models before program exits
65  blace::util::unloadModels();
66
67  return 0;
68}

Follow the 5 minute instructions to build and run the demo.

Tested on version v0.9.28 of blace.ai sdk.

Artifacts

Payload Demo Project Header

License