~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/samples/cpp/videostab.cpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <string>
 
2
#include <iostream>
 
3
#include <fstream>
 
4
#include <sstream>
 
5
#include <stdexcept>
 
6
#include "opencv2/core.hpp"
 
7
#include <opencv2/core/utility.hpp>
 
8
#include "opencv2/video.hpp"
 
9
#include "opencv2/imgproc.hpp"
 
10
#include "opencv2/videoio.hpp"
 
11
#include "opencv2/highgui.hpp"
 
12
#include "opencv2/videostab.hpp"
 
13
#include "opencv2/opencv_modules.hpp"
 
14
 
 
15
#define arg(name) cmd.get<string>(name)
 
16
#define argb(name) cmd.get<bool>(name)
 
17
#define argi(name) cmd.get<int>(name)
 
18
#define argf(name) cmd.get<float>(name)
 
19
#define argd(name) cmd.get<double>(name)
 
20
 
 
21
using namespace std;
 
22
using namespace cv;
 
23
using namespace cv::videostab;
 
24
 
 
25
Ptr<IFrameSource> stabilizedFrames;
 
26
string saveMotionsPath;
 
27
double outputFps;
 
28
string outputPath;
 
29
bool quietMode;
 
30
 
 
31
void run();
 
32
void saveMotionsIfNecessary();
 
33
void printHelp();
 
34
MotionModel motionModel(const string &str);
 
35
 
 
36
 
 
37
void run()
 
38
{
 
39
    VideoWriter writer;
 
40
    Mat stabilizedFrame;
 
41
    int nframes = 0;
 
42
 
 
43
    // for each stabilized frame
 
44
    while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
 
45
    {
 
46
        nframes++;
 
47
 
 
48
        // init writer (once) and save stabilized frame
 
49
        if (!outputPath.empty())
 
50
        {
 
51
            if (!writer.isOpened())
 
52
                writer.open(outputPath, VideoWriter::fourcc('X','V','I','D'),
 
53
                            outputFps, stabilizedFrame.size());
 
54
            writer << stabilizedFrame;
 
55
        }
 
56
 
 
57
        // show stabilized frame
 
58
        if (!quietMode)
 
59
        {
 
60
            imshow("stabilizedFrame", stabilizedFrame);
 
61
            char key = static_cast<char>(waitKey(3));
 
62
            if (key == 27) { cout << endl; break; }
 
63
        }
 
64
    }
 
65
 
 
66
    cout << "processed frames: " << nframes << endl
 
67
         << "finished\n";
 
68
}
 
69
 
 
70
 
 
71
void printHelp()
 
72
{
 
73
    cout << "OpenCV video stabilizer.\n"
 
74
            "Usage: videostab <file_path> [arguments]\n\n"
 
75
            "Arguments:\n"
 
76
            "  -m=, --model=(transl|transl_and_scale|rigid|similarity|affine|homography)\n"
 
77
            "      Set motion model. The default is affine.\n"
 
78
            "  -lp=, --lin-prog-motion-est=(yes|no)\n"
 
79
            "      Turn on/off LP based motion estimation. The default is no.\n"
 
80
            "  --subset=(<int_number>|auto)\n"
 
81
            "      Number of random samples per one motion hypothesis. The default is auto.\n"
 
82
            "  --thresh=(<float_number>|auto)\n"
 
83
            "      Maximum error to classify match as inlier. The default is auto.\n"
 
84
            "  --outlier-ratio=<float_number>\n"
 
85
            "      Motion estimation outlier ratio hypothesis. The default is 0.5.\n"
 
86
            "  --min-inlier-ratio=<float_number>\n"
 
87
            "      Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1.\n"
 
88
            "  --nkps=<int_number>\n"
 
89
            "      Number of keypoints to find in each frame. The default is 1000.\n"
 
90
            "  --local-outlier-rejection=(yes|no)\n"
 
91
            "      Perform local outlier rejection. The default is no.\n\n"
 
92
            "  -sm=, --save-motions=(<file_path>|no)\n"
 
93
            "      Save estimated motions into file. The default is no.\n"
 
94
            "  -lm=, --load-motions=(<file_path>|no)\n"
 
95
            "      Load motions from file. The default is no.\n\n"
 
96
            "  -r=, --radius=<int_number>\n"
 
97
            "      Set sliding window radius. The default is 15.\n"
 
98
            "  --stdev=(<float_number>|auto)\n"
 
99
            "      Set smoothing weights standard deviation. The default is auto\n"
 
100
            "      (i.e. sqrt(radius)).\n"
 
101
            "  -lps=, --lin-prog-stab=(yes|no)\n"
 
102
            "      Turn on/off linear programming based stabilization method.\n"
 
103
            "  --lps-trim-ratio=(<float_number>|auto)\n"
 
104
            "      Trimming ratio used in linear programming based method.\n"
 
105
            "  --lps-w1=(<float_number>|1)\n"
 
106
            "      1st derivative weight. The default is 1.\n"
 
107
            "  --lps-w2=(<float_number>|10)\n"
 
108
            "      2nd derivative weight. The default is 10.\n"
 
109
            "  --lps-w3=(<float_number>|100)\n"
 
110
            "      3rd derivative weight. The default is 100.\n"
 
111
            "  --lps-w4=(<float_number>|100)\n"
 
112
            "      Non-translation motion components weight. The default is 100.\n\n"
 
113
            "  --deblur=(yes|no)\n"
 
114
            "      Do deblurring.\n"
 
115
            "  --deblur-sens=<float_number>\n"
 
116
            "      Set deblurring sensitivity (from 0 to +inf). The default is 0.1.\n\n"
 
117
            "  -t=, --trim-ratio=<float_number>\n"
 
118
            "      Set trimming ratio (from 0 to 0.5). The default is 0.1.\n"
 
119
            "  -et=, --est-trim=(yes|no)\n"
 
120
            "      Estimate trim ratio automatically. The default is yes.\n"
 
121
            "  -ic=, --incl-constr=(yes|no)\n"
 
122
            "      Ensure the inclusion constraint is always satisfied. The default is no.\n\n"
 
123
            "  -bm=, --border-mode=(replicate|reflect|const)\n"
 
124
            "      Set border extrapolation mode. The default is replicate.\n\n"
 
125
            "  --mosaic=(yes|no)\n"
 
126
            "      Do consistent mosaicing. The default is no.\n"
 
127
            "  --mosaic-stdev=<float_number>\n"
 
128
            "      Consistent mosaicing stdev threshold. The default is 10.0.\n\n"
 
129
            "  -mi=, --motion-inpaint=(yes|no)\n"
 
130
            "      Do motion inpainting (requires CUDA support). The default is no.\n"
 
131
            "  --mi-dist-thresh=<float_number>\n"
 
132
            "      Estimated flow distance threshold for motion inpainting. The default is 5.0.\n\n"
 
133
            "  -ci=, --color-inpaint=(no|average|ns|telea)\n"
 
134
            "      Do color inpainting. The defailt is no.\n"
 
135
            "  --ci-radius=<float_number>\n"
 
136
            "      Set color inpainting radius (for ns and telea options only).\n"
 
137
            "      The default is 2.0\n\n"
 
138
            "  -ws=, --wobble-suppress=(yes|no)\n"
 
139
            "      Perform wobble suppression. The default is no.\n"
 
140
            "  --ws-lp=(yes|no)\n"
 
141
            "      Turn on/off LP based motion estimation. The default is no.\n"
 
142
            "  --ws-period=<int_number>\n"
 
143
            "      Set wobble suppression period. The default is 30.\n"
 
144
            "  --ws-model=(transl|transl_and_scale|rigid|similarity|affine|homography)\n"
 
145
            "      Set wobble suppression motion model (must have more DOF than motion \n"
 
146
            "      estimation model). The default is homography.\n"
 
147
            "  --ws-subset=(<int_number>|auto)\n"
 
148
            "      Number of random samples per one motion hypothesis. The default is auto.\n"
 
149
            "  --ws-thresh=(<float_number>|auto)\n"
 
150
            "      Maximum error to classify match as inlier. The default is auto.\n"
 
151
            "  --ws-outlier-ratio=<float_number>\n"
 
152
            "      Motion estimation outlier ratio hypothesis. The default is 0.5.\n"
 
153
            "  --ws-min-inlier-ratio=<float_number>\n"
 
154
            "      Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1.\n"
 
155
            "  --ws-nkps=<int_number>\n"
 
156
            "      Number of keypoints to find in each frame. The default is 1000.\n"
 
157
            "  --ws-local-outlier-rejection=(yes|no)\n"
 
158
            "      Perform local outlier rejection. The default is no.\n\n"
 
159
            "  -sm2=, --save-motions2=(<file_path>|no)\n"
 
160
            "      Save motions estimated for wobble suppression. The default is no.\n"
 
161
            "  -lm2=, --load-motions2=(<file_path>|no)\n"
 
162
            "      Load motions for wobble suppression from file. The default is no.\n\n"
 
163
            "  -gpu=(yes|no)\n"
 
164
            "      Use CUDA optimization whenever possible. The default is no.\n\n"
 
165
            "  -o=, --output=(no|<file_path>)\n"
 
166
            "      Set output file path explicitely. The default is stabilized.avi.\n"
 
167
            "  --fps=(<float_number>|auto)\n"
 
168
            "      Set output video FPS explicitely. By default the source FPS is used (auto).\n"
 
169
            "  -q, --quiet\n"
 
170
            "      Don't show output video frames.\n\n"
 
171
            "  -h, --help\n"
 
172
            "      Print help.\n\n"
 
173
            "Note: some argument configurations lead to two passes, some to single pass.\n\n";
 
174
}
 
175
 
 
176
// motion estimator builders are for concise creation of motion estimators
 
177
 
 
178
class IMotionEstimatorBuilder
 
179
{
 
180
public:
 
181
    virtual ~IMotionEstimatorBuilder() {}
 
182
    virtual Ptr<ImageMotionEstimatorBase> build() = 0;
 
183
protected:
 
184
    IMotionEstimatorBuilder(CommandLineParser &command) : cmd(command) {}
 
185
    CommandLineParser cmd;
 
186
};
 
187
 
 
188
 
 
189
class MotionEstimatorRansacL2Builder : public IMotionEstimatorBuilder
 
190
{
 
191
public:
 
192
    MotionEstimatorRansacL2Builder(CommandLineParser &command, bool use_gpu, const string &_prefix = "")
 
193
        : IMotionEstimatorBuilder(command), gpu(use_gpu), prefix(_prefix) {}
 
194
 
 
195
    virtual Ptr<ImageMotionEstimatorBase> build()
 
196
    {
 
197
        Ptr<MotionEstimatorRansacL2> est = makePtr<MotionEstimatorRansacL2>(motionModel(arg(prefix + "model")));
 
198
 
 
199
        RansacParams ransac = est->ransacParams();
 
200
        if (arg(prefix + "subset") != "auto")
 
201
            ransac.size = argi(prefix + "subset");
 
202
        if (arg(prefix + "thresh") != "auto")
 
203
            ransac.thresh = argf(prefix + "thresh");
 
204
        ransac.eps = argf(prefix + "outlier-ratio");
 
205
        est->setRansacParams(ransac);
 
206
 
 
207
        est->setMinInlierRatio(argf(prefix + "min-inlier-ratio"));
 
208
 
 
209
        Ptr<IOutlierRejector> outlierRejector = makePtr<NullOutlierRejector>();
 
210
        if (arg(prefix + "local-outlier-rejection") == "yes")
 
211
        {
 
212
            Ptr<TranslationBasedLocalOutlierRejector> tblor = makePtr<TranslationBasedLocalOutlierRejector>();
 
213
            RansacParams ransacParams = tblor->ransacParams();
 
214
            if (arg(prefix + "thresh") != "auto")
 
215
                ransacParams.thresh = argf(prefix + "thresh");
 
216
            tblor->setRansacParams(ransacParams);
 
217
            outlierRejector = tblor;
 
218
        }
 
219
 
 
220
#if defined(HAVE_OPENCV_CUDAIMGPROC) && defined(HAVE_OPENCV_CUDAOPTFLOW)
 
221
        if (gpu)
 
222
        {
 
223
            Ptr<KeypointBasedMotionEstimatorGpu> kbest = makePtr<KeypointBasedMotionEstimatorGpu>(est);
 
224
            kbest->setOutlierRejector(outlierRejector);
 
225
            return kbest;
 
226
        }
 
227
#endif
 
228
 
 
229
        Ptr<KeypointBasedMotionEstimator> kbest = makePtr<KeypointBasedMotionEstimator>(est);
 
230
        kbest->setDetector(GFTTDetector::create(argi(prefix + "nkps")));
 
231
        kbest->setOutlierRejector(outlierRejector);
 
232
        return kbest;
 
233
    }
 
234
private:
 
235
    bool gpu;
 
236
    string prefix;
 
237
};
 
238
 
 
239
 
 
240
class MotionEstimatorL1Builder : public IMotionEstimatorBuilder
 
241
{
 
242
public:
 
243
    MotionEstimatorL1Builder(CommandLineParser &command, bool use_gpu, const string &_prefix = "")
 
244
        : IMotionEstimatorBuilder(command), gpu(use_gpu), prefix(_prefix) {}
 
245
 
 
246
    virtual Ptr<ImageMotionEstimatorBase> build()
 
247
    {
 
248
        Ptr<MotionEstimatorL1> est = makePtr<MotionEstimatorL1>(motionModel(arg(prefix + "model")));
 
249
 
 
250
        Ptr<IOutlierRejector> outlierRejector = makePtr<NullOutlierRejector>();
 
251
        if (arg(prefix + "local-outlier-rejection") == "yes")
 
252
        {
 
253
            Ptr<TranslationBasedLocalOutlierRejector> tblor = makePtr<TranslationBasedLocalOutlierRejector>();
 
254
            RansacParams ransacParams = tblor->ransacParams();
 
255
            if (arg(prefix + "thresh") != "auto")
 
256
                ransacParams.thresh = argf(prefix + "thresh");
 
257
            tblor->setRansacParams(ransacParams);
 
258
            outlierRejector = tblor;
 
259
        }
 
260
 
 
261
#if defined(HAVE_OPENCV_CUDAIMGPROC) && defined(HAVE_OPENCV_CUDAOPTFLOW)
 
262
        if (gpu)
 
263
        {
 
264
            Ptr<KeypointBasedMotionEstimatorGpu> kbest = makePtr<KeypointBasedMotionEstimatorGpu>(est);
 
265
            kbest->setOutlierRejector(outlierRejector);
 
266
            return kbest;
 
267
        }
 
268
#endif
 
269
 
 
270
        Ptr<KeypointBasedMotionEstimator> kbest = makePtr<KeypointBasedMotionEstimator>(est);
 
271
        kbest->setDetector(GFTTDetector::create(argi(prefix + "nkps")));
 
272
        kbest->setOutlierRejector(outlierRejector);
 
273
        return kbest;
 
274
    }
 
275
private:
 
276
    bool gpu;
 
277
    string prefix;
 
278
};
 
279
 
 
280
 
 
281
int main(int argc, const char **argv)
 
282
{
 
283
    try
 
284
    {
 
285
        const char *keys =
 
286
                "{ @1                       |           | }"
 
287
                "{ m  model                 | affine    | }"
 
288
                "{ lp lin-prog-motion-est   | no        | }"
 
289
                "{  subset                  | auto      | }"
 
290
                "{  thresh                  | auto | }"
 
291
                "{  outlier-ratio           | 0.5 | }"
 
292
                "{  min-inlier-ratio        | 0.1 | }"
 
293
                "{  nkps                    | 1000 | }"
 
294
                "{  extra-kps               | 0 | }"
 
295
                "{  local-outlier-rejection | no | }"
 
296
                "{ sm  save-motions         | no | }"
 
297
                "{ lm  load-motions         | no | }"
 
298
                "{ r  radius                | 15 | }"
 
299
                "{  stdev                   | auto | }"
 
300
                "{ lps  lin-prog-stab       | no | }"
 
301
                "{  lps-trim-ratio          | auto | }"
 
302
                "{  lps-w1                  | 1 | }"
 
303
                "{  lps-w2                  | 10 | }"
 
304
                "{  lps-w3                  | 100 | }"
 
305
                "{  lps-w4                  | 100 | }"
 
306
                "{  deblur                  | no | }"
 
307
                "{  deblur-sens             | 0.1 | }"
 
308
                "{ et  est-trim             | yes | }"
 
309
                "{ t  trim-ratio            | 0.1 | }"
 
310
                "{ ic  incl-constr          | no | }"
 
311
                "{ bm  border-mode          | replicate | }"
 
312
                "{  mosaic                  | no | }"
 
313
                "{ ms  mosaic-stdev         | 10.0 | }"
 
314
                "{ mi  motion-inpaint       | no | }"
 
315
                "{  mi-dist-thresh          | 5.0 | }"
 
316
                "{ ci color-inpaint         | no | }"
 
317
                "{  ci-radius               | 2 | }"
 
318
                "{ ws  wobble-suppress      | no | }"
 
319
                "{  ws-period               | 30 | }"
 
320
                "{  ws-model                | homography | }"
 
321
                "{  ws-subset               | auto | }"
 
322
                "{  ws-thresh               | auto | }"
 
323
                "{  ws-outlier-ratio        | 0.5 | }"
 
324
                "{  ws-min-inlier-ratio     | 0.1 | }"
 
325
                "{  ws-nkps                 | 1000 | }"
 
326
                "{  ws-extra-kps            | 0 | }"
 
327
                "{  ws-local-outlier-rejection | no | }"
 
328
                "{  ws-lp                   | no | }"
 
329
                "{ sm2 save-motions2        | no | }"
 
330
                "{ lm2 load-motions2        | no | }"
 
331
                "{ gpu                      | no | }"
 
332
                "{ o  output                | stabilized.avi | }"
 
333
                "{ fps                      | auto | }"
 
334
                "{ q quiet                  |  | }"
 
335
                "{ h help                   |  | }";
 
336
        CommandLineParser cmd(argc, argv, keys);
 
337
 
 
338
        // parse command arguments
 
339
 
 
340
        if (argb("help"))
 
341
        {
 
342
            printHelp();
 
343
            return 0;
 
344
        }
 
345
 
 
346
        if (arg("gpu") == "yes")
 
347
        {
 
348
            cout << "initializing GPU..."; cout.flush();
 
349
            Mat hostTmp = Mat::zeros(1, 1, CV_32F);
 
350
            cuda::GpuMat deviceTmp;
 
351
            deviceTmp.upload(hostTmp);
 
352
            cout << endl;
 
353
        }
 
354
 
 
355
        StabilizerBase *stabilizer = 0;
 
356
 
 
357
        // check if source video is specified
 
358
 
 
359
        string inputPath = arg(0);
 
360
        if (inputPath.empty())
 
361
            throw runtime_error("specify video file path");
 
362
 
 
363
        // get source video parameters
 
364
 
 
365
        Ptr<VideoFileSource> source = makePtr<VideoFileSource>(inputPath);
 
366
        cout << "frame count (rough): " << source->count() << endl;
 
367
        if (arg("fps") == "auto")
 
368
            outputFps = source->fps();
 
369
        else
 
370
            outputFps = argd("fps");
 
371
 
 
372
        // prepare motion estimation builders
 
373
 
 
374
        Ptr<IMotionEstimatorBuilder> motionEstBuilder;
 
375
        if (arg("lin-prog-motion-est") == "yes")
 
376
            motionEstBuilder.reset(new MotionEstimatorL1Builder(cmd, arg("gpu") == "yes"));
 
377
        else
 
378
            motionEstBuilder.reset(new MotionEstimatorRansacL2Builder(cmd, arg("gpu") == "yes"));
 
379
 
 
380
        Ptr<IMotionEstimatorBuilder> wsMotionEstBuilder;
 
381
        if (arg("ws-lp") == "yes")
 
382
            wsMotionEstBuilder.reset(new MotionEstimatorL1Builder(cmd, arg("gpu") == "yes", "ws-"));
 
383
        else
 
384
            wsMotionEstBuilder.reset(new MotionEstimatorRansacL2Builder(cmd, arg("gpu") == "yes", "ws-"));
 
385
 
 
386
        // determine whether we must use one pass or two pass stabilizer
 
387
        bool isTwoPass =
 
388
                arg("est-trim") == "yes" || arg("wobble-suppress") == "yes" || arg("lin-prog-stab") == "yes";
 
389
 
 
390
        if (isTwoPass)
 
391
        {
 
392
            // we must use two pass stabilizer
 
393
 
 
394
            TwoPassStabilizer *twoPassStabilizer = new TwoPassStabilizer();
 
395
            stabilizer = twoPassStabilizer;
 
396
            twoPassStabilizer->setEstimateTrimRatio(arg("est-trim") == "yes");
 
397
 
 
398
            // determine stabilization technique
 
399
 
 
400
            if (arg("lin-prog-stab") == "yes")
 
401
            {
 
402
                Ptr<LpMotionStabilizer> stab = makePtr<LpMotionStabilizer>();
 
403
                stab->setFrameSize(Size(source->width(), source->height()));
 
404
                stab->setTrimRatio(arg("lps-trim-ratio") == "auto" ? argf("trim-ratio") : argf("lps-trim-ratio"));
 
405
                stab->setWeight1(argf("lps-w1"));
 
406
                stab->setWeight2(argf("lps-w2"));
 
407
                stab->setWeight3(argf("lps-w3"));
 
408
                stab->setWeight4(argf("lps-w4"));
 
409
                twoPassStabilizer->setMotionStabilizer(stab);
 
410
            }
 
411
            else if (arg("stdev") == "auto")
 
412
                twoPassStabilizer->setMotionStabilizer(makePtr<GaussianMotionFilter>(argi("radius")));
 
413
            else
 
414
                twoPassStabilizer->setMotionStabilizer(makePtr<GaussianMotionFilter>(argi("radius"), argf("stdev")));
 
415
 
 
416
            // init wobble suppressor if necessary
 
417
 
 
418
            if (arg("wobble-suppress") == "yes")
 
419
            {
 
420
                Ptr<MoreAccurateMotionWobbleSuppressorBase> ws = makePtr<MoreAccurateMotionWobbleSuppressor>();
 
421
                if (arg("gpu") == "yes")
 
422
#ifdef HAVE_OPENCV_CUDAWARPING
 
423
                    ws = makePtr<MoreAccurateMotionWobbleSuppressorGpu>();
 
424
#else
 
425
                    throw runtime_error("OpenCV is built without CUDA support");
 
426
#endif
 
427
 
 
428
                ws->setMotionEstimator(wsMotionEstBuilder->build());
 
429
                ws->setPeriod(argi("ws-period"));
 
430
                twoPassStabilizer->setWobbleSuppressor(ws);
 
431
 
 
432
                MotionModel model = ws->motionEstimator()->motionModel();
 
433
                if (arg("load-motions2") != "no")
 
434
                {
 
435
                    ws->setMotionEstimator(makePtr<FromFileMotionReader>(arg("load-motions2")));
 
436
                    ws->motionEstimator()->setMotionModel(model);
 
437
                }
 
438
                if (arg("save-motions2") != "no")
 
439
                {
 
440
                    ws->setMotionEstimator(makePtr<ToFileMotionWriter>(arg("save-motions2"), ws->motionEstimator()));
 
441
                    ws->motionEstimator()->setMotionModel(model);
 
442
                }
 
443
            }
 
444
        }
 
445
        else
 
446
        {
 
447
            // we must use one pass stabilizer
 
448
 
 
449
            OnePassStabilizer *onePassStabilizer = new OnePassStabilizer();
 
450
            stabilizer = onePassStabilizer;
 
451
            if (arg("stdev") == "auto")
 
452
                onePassStabilizer->setMotionFilter(makePtr<GaussianMotionFilter>(argi("radius")));
 
453
            else
 
454
                onePassStabilizer->setMotionFilter(makePtr<GaussianMotionFilter>(argi("radius"), argf("stdev")));
 
455
        }
 
456
 
 
457
        stabilizer->setFrameSource(source);
 
458
        stabilizer->setMotionEstimator(motionEstBuilder->build());
 
459
 
 
460
        // cast stabilizer to simple frame source interface to read stabilized frames
 
461
        stabilizedFrames.reset(dynamic_cast<IFrameSource*>(stabilizer));
 
462
 
 
463
        MotionModel model = stabilizer->motionEstimator()->motionModel();
 
464
        if (arg("load-motions") != "no")
 
465
        {
 
466
            stabilizer->setMotionEstimator(makePtr<FromFileMotionReader>(arg("load-motions")));
 
467
            stabilizer->motionEstimator()->setMotionModel(model);
 
468
        }
 
469
        if (arg("save-motions") != "no")
 
470
        {
 
471
            stabilizer->setMotionEstimator(makePtr<ToFileMotionWriter>(arg("save-motions"), stabilizer->motionEstimator()));
 
472
            stabilizer->motionEstimator()->setMotionModel(model);
 
473
        }
 
474
 
 
475
        stabilizer->setRadius(argi("radius"));
 
476
 
 
477
        // init deblurer
 
478
        if (arg("deblur") == "yes")
 
479
        {
 
480
            Ptr<WeightingDeblurer> deblurer = makePtr<WeightingDeblurer>();
 
481
            deblurer->setRadius(argi("radius"));
 
482
            deblurer->setSensitivity(argf("deblur-sens"));
 
483
            stabilizer->setDeblurer(deblurer);
 
484
        }
 
485
 
 
486
        // set up trimming paramters
 
487
        stabilizer->setTrimRatio(argf("trim-ratio"));
 
488
        stabilizer->setCorrectionForInclusion(arg("incl-constr") == "yes");
 
489
 
 
490
        if (arg("border-mode") == "reflect")
 
491
            stabilizer->setBorderMode(BORDER_REFLECT);
 
492
        else if (arg("border-mode") == "replicate")
 
493
            stabilizer->setBorderMode(BORDER_REPLICATE);
 
494
        else if (arg("border-mode") == "const")
 
495
            stabilizer->setBorderMode(BORDER_CONSTANT);
 
496
        else
 
497
            throw runtime_error("unknown border extrapolation mode: "
 
498
                                 + cmd.get<string>("border-mode"));
 
499
 
 
500
        // init inpainter
 
501
        InpaintingPipeline *inpainters = new InpaintingPipeline();
 
502
        Ptr<InpainterBase> inpainters_(inpainters);
 
503
        if (arg("mosaic") == "yes")
 
504
        {
 
505
            Ptr<ConsistentMosaicInpainter> inp = makePtr<ConsistentMosaicInpainter>();
 
506
            inp->setStdevThresh(argf("mosaic-stdev"));
 
507
            inpainters->pushBack(inp);
 
508
        }
 
509
        if (arg("motion-inpaint") == "yes")
 
510
        {
 
511
            Ptr<MotionInpainter> inp = makePtr<MotionInpainter>();
 
512
            inp->setDistThreshold(argf("mi-dist-thresh"));
 
513
            inpainters->pushBack(inp);
 
514
        }
 
515
        if (arg("color-inpaint") == "average")
 
516
            inpainters->pushBack(makePtr<ColorAverageInpainter>());
 
517
        else if (arg("color-inpaint") == "ns")
 
518
            inpainters->pushBack(makePtr<ColorInpainter>(int(INPAINT_NS), argd("ci-radius")));
 
519
        else if (arg("color-inpaint") == "telea")
 
520
            inpainters->pushBack(makePtr<ColorInpainter>(int(INPAINT_TELEA), argd("ci-radius")));
 
521
        else if (arg("color-inpaint") != "no")
 
522
            throw runtime_error("unknown color inpainting method: " + arg("color-inpaint"));
 
523
        if (!inpainters->empty())
 
524
        {
 
525
            inpainters->setRadius(argi("radius"));
 
526
            stabilizer->setInpainter(inpainters_);
 
527
        }
 
528
 
 
529
        if (arg("output") != "no")
 
530
            outputPath = arg("output");
 
531
 
 
532
        quietMode = argb("quiet");
 
533
 
 
534
        run();
 
535
    }
 
536
    catch (const exception &e)
 
537
    {
 
538
        cout << "error: " << e.what() << endl;
 
539
        stabilizedFrames.release();
 
540
        return -1;
 
541
    }
 
542
    stabilizedFrames.release();
 
543
    return 0;
 
544
}
 
545
 
 
546
 
 
547
MotionModel motionModel(const string &str)
 
548
{
 
549
    if (str == "transl")
 
550
        return MM_TRANSLATION;
 
551
    if (str == "transl_and_scale")
 
552
        return MM_TRANSLATION_AND_SCALE;
 
553
    if (str == "rigid")
 
554
        return MM_RIGID;
 
555
    if (str == "similarity")
 
556
        return MM_SIMILARITY;
 
557
    if (str == "affine")
 
558
        return MM_AFFINE;
 
559
    if (str == "homography")
 
560
        return MM_HOMOGRAPHY;
 
561
    throw runtime_error("unknown motion model: " + str);
 
562
}