1 module dcv.example.opticalflow;
2 
3 /** 
4  * Dense optical flow example, by using 
5  * pyramidal Horn-Schunck implementation in dcv.
6  */
7 
8 import std.stdio;
9 import std.conv : to;
10 import mir.ndslice;
11 
12 import dcv.core;
13 import dcv.io;
14 
15 import dcv.imgproc.imgmanip : warp;
16 import dcv.tracking.opticalflow : HornSchunckFlow, HornSchunckProperties, DensePyramidFlow;
17 import dcv.plot.opticalflow : colorCode;
18 
19 void printHelp()
20 {
21     writeln(`
22 DCV Optical DenseFlow example.
23 
24 If only one parameter is given it is considered to be
25 the name of the subfolder of the data/optflow directory.
26 These directories represent the benchmark dataset from the
27 Middlebury University website: http://vision.middlebury.edu/flow/data/
28 
29 Example:
30 ./hornschunck Army
31 
32 Note:
33 This mode will use default parameters (described in the following section).
34 
35 If multiple parameters are given, then parameters are considered to be:
36 
37 1 - path to current frame image; [../data/optflow/Army/frame10.png]
38 2 - path to next frame image; [../data/optflow/Army/frame11.png]
39 3 - optical flow iteration count; [100]
40 4 - Horn-Schunck flow smoothness strength parameter; [10.0]
41 5 - Gaussian image smoothing theta parameter; [1.0]
42 6 - Gaussian kernel size; [3]
43 7 - optical flow pyramid level count; [3]
44 
45 Example:
46 ./hornschunck ../../data/optflow/Evergreen/frame10.png ../../data/optflow/Evergreen/frame11.png 300 25 3 5 4
47 
48 ... which will compute the optical flow for given two images, 
49 by 300 iteration at each pyramid level, by using value of 25.0 
50 as smoothness strenght, in 4 pyramid levels. Images are smoothed
51 with gaussian filter with sigma value 3.0, sized 5x5.
52         `);
53 }
54 
55 void main(string[] args)
56 {
57 
58     if (args.length == 2 && args[1] == "-h")
59     {
60         printHelp();
61         return;
62     }
63 
64     // Read source images.
65     auto rparams = ReadParams(ImageFormat.IF_MONO, BitDepth.BD_8);
66 
67     string currentPath, nextPath;
68 
69     if (args.length == 2)
70     {
71         currentPath = "../../data/optflow/" ~ args[1] ~ "/frame10.png";
72         nextPath = "../../data/optflow/" ~ args[1] ~ "/frame11.png";
73     }
74     else
75     {
76         currentPath = args.length >= 2 ? args[1] : "../../data/optflow/Army/frame10.png";
77         nextPath = args.length >= 3 ? args[2] : "../../data/optflow/Army/frame11.png";
78     }
79 
80     auto current = imread(currentPath, rparams);
81     auto next = imread(nextPath, rparams);
82 
83     // Setup algorithm parameters.
84     HornSchunckProperties props = HornSchunckProperties();
85     props.iterationCount = args.length >= 4 ? args[3].to!int : 100;
86     props.alpha = args.length >= 5 ? args[4].to!float : 10.0f;
87     props.gaussSigma = args.length >= 6 ? args[5].to!float : 1.0f;
88     props.gaussKernelSize = args.length >= 7 ? args[6].to!uint : 3;
89 
90     uint pyramidLevels = args.length >= 8 ? args[7].to!int : 3;
91 
92     HornSchunckFlow hsFlow = new HornSchunckFlow(props);
93     DensePyramidFlow densePyramid = new DensePyramidFlow(hsFlow, pyramidLevels);
94 
95     auto flow = densePyramid.evaluate(current, next);
96 
97     auto flowColor = flow.colorCode;
98     auto flowWarp = current.sliced.warp(flow);
99 
100     current.imwrite("./result/1_current.png");
101     flowColor.imwrite(ImageFormat.IF_RGB, "./result/2_flowColor.png");
102     flowWarp.imwrite(ImageFormat.IF_MONO, "./result/3_flowWarp.png");
103     next.imwrite("./result/4_next.png");
104 }