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

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/modules/cudaoptflow/test/test_optflow.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
/*M///////////////////////////////////////////////////////////////////////////////////////
 
2
//
 
3
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
 
4
//
 
5
//  By downloading, copying, installing or using the software you agree to this license.
 
6
//  If you do not agree to this license, do not download, install,
 
7
//  copy or use the software.
 
8
//
 
9
//
 
10
//                           License Agreement
 
11
//                For Open Source Computer Vision Library
 
12
//
 
13
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
 
14
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
 
15
// Third party copyrights are property of their respective owners.
 
16
//
 
17
// Redistribution and use in source and binary forms, with or without modification,
 
18
// are permitted provided that the following conditions are met:
 
19
//
 
20
//   * Redistribution's of source code must retain the above copyright notice,
 
21
//     this list of conditions and the following disclaimer.
 
22
//
 
23
//   * Redistribution's in binary form must reproduce the above copyright notice,
 
24
//     this list of conditions and the following disclaimer in the documentation
 
25
//     and/or other materials provided with the distribution.
 
26
//
 
27
//   * The name of the copyright holders may not be used to endorse or promote products
 
28
//     derived from this software without specific prior written permission.
 
29
//
 
30
// This software is provided by the copyright holders and contributors "as is" and
 
31
// any express or implied warranties, including, but not limited to, the implied
 
32
// warranties of merchantability and fitness for a particular purpose are disclaimed.
 
33
// In no event shall the Intel Corporation or contributors be liable for any direct,
 
34
// indirect, incidental, special, exemplary, or consequential damages
 
35
// (including, but not limited to, procurement of substitute goods or services;
 
36
// loss of use, data, or profits; or business interruption) however caused
 
37
// and on any theory of liability, whether in contract, strict liability,
 
38
// or tort (including negligence or otherwise) arising in any way out of
 
39
// the use of this software, even if advised of the possibility of such damage.
 
40
//
 
41
//M*/
 
42
 
 
43
#include "test_precomp.hpp"
 
44
 
 
45
#ifdef HAVE_CUDA
 
46
 
 
47
using namespace cvtest;
 
48
 
 
49
//////////////////////////////////////////////////////
 
50
// BroxOpticalFlow
 
51
 
 
52
//#define BROX_DUMP
 
53
 
 
54
struct BroxOpticalFlow : testing::TestWithParam<cv::cuda::DeviceInfo>
 
55
{
 
56
    cv::cuda::DeviceInfo devInfo;
 
57
 
 
58
    virtual void SetUp()
 
59
    {
 
60
        devInfo = GetParam();
 
61
 
 
62
        cv::cuda::setDevice(devInfo.deviceID());
 
63
    }
 
64
};
 
65
 
 
66
CUDA_TEST_P(BroxOpticalFlow, Regression)
 
67
{
 
68
    cv::Mat frame0 = readImageType("opticalflow/frame0.png", CV_32FC1);
 
69
    ASSERT_FALSE(frame0.empty());
 
70
 
 
71
    cv::Mat frame1 = readImageType("opticalflow/frame1.png", CV_32FC1);
 
72
    ASSERT_FALSE(frame1.empty());
 
73
 
 
74
    cv::Ptr<cv::cuda::BroxOpticalFlow> brox =
 
75
            cv::cuda::BroxOpticalFlow::create(0.197 /*alpha*/, 50.0 /*gamma*/, 0.8 /*scale_factor*/,
 
76
                                              10 /*inner_iterations*/, 77 /*outer_iterations*/, 10 /*solver_iterations*/);
 
77
 
 
78
    cv::cuda::GpuMat flow;
 
79
    brox->calc(loadMat(frame0), loadMat(frame1), flow);
 
80
 
 
81
    cv::cuda::GpuMat flows[2];
 
82
    cv::cuda::split(flow, flows);
 
83
 
 
84
    cv::cuda::GpuMat u = flows[0];
 
85
    cv::cuda::GpuMat v = flows[1];
 
86
 
 
87
    std::string fname(cvtest::TS::ptr()->get_data_path());
 
88
    if (devInfo.majorVersion() >= 2)
 
89
        fname += "opticalflow/brox_optical_flow_cc20.bin";
 
90
    else
 
91
        fname += "opticalflow/brox_optical_flow.bin";
 
92
 
 
93
#ifndef BROX_DUMP
 
94
    std::ifstream f(fname.c_str(), std::ios_base::binary);
 
95
 
 
96
    int rows, cols;
 
97
 
 
98
    f.read((char*) &rows, sizeof(rows));
 
99
    f.read((char*) &cols, sizeof(cols));
 
100
 
 
101
    cv::Mat u_gold(rows, cols, CV_32FC1);
 
102
 
 
103
    for (int i = 0; i < u_gold.rows; ++i)
 
104
        f.read(u_gold.ptr<char>(i), u_gold.cols * sizeof(float));
 
105
 
 
106
    cv::Mat v_gold(rows, cols, CV_32FC1);
 
107
 
 
108
    for (int i = 0; i < v_gold.rows; ++i)
 
109
        f.read(v_gold.ptr<char>(i), v_gold.cols * sizeof(float));
 
110
 
 
111
    EXPECT_MAT_SIMILAR(u_gold, u, 1e-3);
 
112
    EXPECT_MAT_SIMILAR(v_gold, v, 1e-3);
 
113
#else
 
114
    std::ofstream f(fname.c_str(), std::ios_base::binary);
 
115
 
 
116
    f.write((char*) &u.rows, sizeof(u.rows));
 
117
    f.write((char*) &u.cols, sizeof(u.cols));
 
118
 
 
119
    cv::Mat h_u(u);
 
120
    cv::Mat h_v(v);
 
121
 
 
122
    for (int i = 0; i < u.rows; ++i)
 
123
        f.write(h_u.ptr<char>(i), u.cols * sizeof(float));
 
124
 
 
125
    for (int i = 0; i < v.rows; ++i)
 
126
        f.write(h_v.ptr<char>(i), v.cols * sizeof(float));
 
127
#endif
 
128
}
 
129
 
 
130
CUDA_TEST_P(BroxOpticalFlow, OpticalFlowNan)
 
131
{
 
132
    cv::Mat frame0 = readImageType("opticalflow/frame0.png", CV_32FC1);
 
133
    ASSERT_FALSE(frame0.empty());
 
134
 
 
135
    cv::Mat frame1 = readImageType("opticalflow/frame1.png", CV_32FC1);
 
136
    ASSERT_FALSE(frame1.empty());
 
137
 
 
138
    cv::Mat r_frame0, r_frame1;
 
139
    cv::resize(frame0, r_frame0, cv::Size(1380,1000));
 
140
    cv::resize(frame1, r_frame1, cv::Size(1380,1000));
 
141
 
 
142
    cv::Ptr<cv::cuda::BroxOpticalFlow> brox =
 
143
            cv::cuda::BroxOpticalFlow::create(0.197 /*alpha*/, 50.0 /*gamma*/, 0.8 /*scale_factor*/,
 
144
                                              10 /*inner_iterations*/, 77 /*outer_iterations*/, 10 /*solver_iterations*/);
 
145
 
 
146
    cv::cuda::GpuMat flow;
 
147
    brox->calc(loadMat(frame0), loadMat(frame1), flow);
 
148
 
 
149
    cv::cuda::GpuMat flows[2];
 
150
    cv::cuda::split(flow, flows);
 
151
 
 
152
    cv::cuda::GpuMat u = flows[0];
 
153
    cv::cuda::GpuMat v = flows[1];
 
154
 
 
155
    cv::Mat h_u, h_v;
 
156
    u.download(h_u);
 
157
    v.download(h_v);
 
158
 
 
159
    EXPECT_TRUE(cv::checkRange(h_u));
 
160
    EXPECT_TRUE(cv::checkRange(h_v));
 
161
};
 
162
 
 
163
INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, BroxOpticalFlow, ALL_DEVICES);
 
164
 
 
165
//////////////////////////////////////////////////////
 
166
// PyrLKOpticalFlow
 
167
 
 
168
namespace
 
169
{
 
170
    IMPLEMENT_PARAM_CLASS(UseGray, bool)
 
171
}
 
172
 
 
173
PARAM_TEST_CASE(PyrLKOpticalFlow, cv::cuda::DeviceInfo, UseGray)
 
174
{
 
175
    cv::cuda::DeviceInfo devInfo;
 
176
    bool useGray;
 
177
 
 
178
    virtual void SetUp()
 
179
    {
 
180
        devInfo = GET_PARAM(0);
 
181
        useGray = GET_PARAM(1);
 
182
 
 
183
        cv::cuda::setDevice(devInfo.deviceID());
 
184
    }
 
185
};
 
186
 
 
187
CUDA_TEST_P(PyrLKOpticalFlow, Sparse)
 
188
{
 
189
    cv::Mat frame0 = readImage("opticalflow/frame0.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
 
190
    ASSERT_FALSE(frame0.empty());
 
191
 
 
192
    cv::Mat frame1 = readImage("opticalflow/frame1.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
 
193
    ASSERT_FALSE(frame1.empty());
 
194
 
 
195
    cv::Mat gray_frame;
 
196
    if (useGray)
 
197
        gray_frame = frame0;
 
198
    else
 
199
        cv::cvtColor(frame0, gray_frame, cv::COLOR_BGR2GRAY);
 
200
 
 
201
    std::vector<cv::Point2f> pts;
 
202
    cv::goodFeaturesToTrack(gray_frame, pts, 1000, 0.01, 0.0);
 
203
 
 
204
    cv::cuda::GpuMat d_pts;
 
205
    cv::Mat pts_mat(1, (int) pts.size(), CV_32FC2, (void*) &pts[0]);
 
206
    d_pts.upload(pts_mat);
 
207
 
 
208
    cv::Ptr<cv::cuda::SparsePyrLKOpticalFlow> pyrLK =
 
209
            cv::cuda::SparsePyrLKOpticalFlow::create();
 
210
 
 
211
    cv::cuda::GpuMat d_nextPts;
 
212
    cv::cuda::GpuMat d_status;
 
213
    pyrLK->calc(loadMat(frame0), loadMat(frame1), d_pts, d_nextPts, d_status);
 
214
 
 
215
    std::vector<cv::Point2f> nextPts(d_nextPts.cols);
 
216
    cv::Mat nextPts_mat(1, d_nextPts.cols, CV_32FC2, (void*) &nextPts[0]);
 
217
    d_nextPts.download(nextPts_mat);
 
218
 
 
219
    std::vector<unsigned char> status(d_status.cols);
 
220
    cv::Mat status_mat(1, d_status.cols, CV_8UC1, (void*) &status[0]);
 
221
    d_status.download(status_mat);
 
222
 
 
223
    std::vector<cv::Point2f> nextPts_gold;
 
224
    std::vector<unsigned char> status_gold;
 
225
    cv::calcOpticalFlowPyrLK(frame0, frame1, pts, nextPts_gold, status_gold, cv::noArray());
 
226
 
 
227
    ASSERT_EQ(nextPts_gold.size(), nextPts.size());
 
228
    ASSERT_EQ(status_gold.size(), status.size());
 
229
 
 
230
    size_t mistmatch = 0;
 
231
    for (size_t i = 0; i < nextPts.size(); ++i)
 
232
    {
 
233
        cv::Point2i a = nextPts[i];
 
234
        cv::Point2i b = nextPts_gold[i];
 
235
 
 
236
        if (status[i] != status_gold[i])
 
237
        {
 
238
            ++mistmatch;
 
239
            continue;
 
240
        }
 
241
 
 
242
        if (status[i])
 
243
        {
 
244
            bool eq = std::abs(a.x - b.x) <= 1 && std::abs(a.y - b.y) <= 1;
 
245
 
 
246
            if (!eq)
 
247
                ++mistmatch;
 
248
        }
 
249
    }
 
250
 
 
251
    double bad_ratio = static_cast<double>(mistmatch) / nextPts.size();
 
252
 
 
253
    ASSERT_LE(bad_ratio, 0.01);
 
254
}
 
255
 
 
256
INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, PyrLKOpticalFlow, testing::Combine(
 
257
    ALL_DEVICES,
 
258
    testing::Values(UseGray(true), UseGray(false))));
 
259
 
 
260
//////////////////////////////////////////////////////
 
261
// FarnebackOpticalFlow
 
262
 
 
263
namespace
 
264
{
 
265
    IMPLEMENT_PARAM_CLASS(PyrScale, double)
 
266
    IMPLEMENT_PARAM_CLASS(PolyN, int)
 
267
    CV_FLAGS(FarnebackOptFlowFlags, 0, OPTFLOW_FARNEBACK_GAUSSIAN)
 
268
    IMPLEMENT_PARAM_CLASS(UseInitFlow, bool)
 
269
}
 
270
 
 
271
PARAM_TEST_CASE(FarnebackOpticalFlow, cv::cuda::DeviceInfo, PyrScale, PolyN, FarnebackOptFlowFlags, UseInitFlow)
 
272
{
 
273
    cv::cuda::DeviceInfo devInfo;
 
274
    double pyrScale;
 
275
    int polyN;
 
276
    int flags;
 
277
    bool useInitFlow;
 
278
 
 
279
    virtual void SetUp()
 
280
    {
 
281
        devInfo = GET_PARAM(0);
 
282
        pyrScale = GET_PARAM(1);
 
283
        polyN = GET_PARAM(2);
 
284
        flags = GET_PARAM(3);
 
285
        useInitFlow = GET_PARAM(4);
 
286
 
 
287
        cv::cuda::setDevice(devInfo.deviceID());
 
288
    }
 
289
};
 
290
 
 
291
CUDA_TEST_P(FarnebackOpticalFlow, Accuracy)
 
292
{
 
293
    cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
 
294
    ASSERT_FALSE(frame0.empty());
 
295
 
 
296
    cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
 
297
    ASSERT_FALSE(frame1.empty());
 
298
 
 
299
    double polySigma = polyN <= 5 ? 1.1 : 1.5;
 
300
 
 
301
    cv::Ptr<cv::cuda::FarnebackOpticalFlow> farn =
 
302
            cv::cuda::FarnebackOpticalFlow::create();
 
303
    farn->setPyrScale(pyrScale);
 
304
    farn->setPolyN(polyN);
 
305
    farn->setPolySigma(polySigma);
 
306
    farn->setFlags(flags);
 
307
 
 
308
    cv::cuda::GpuMat d_flow;
 
309
    farn->calc(loadMat(frame0), loadMat(frame1), d_flow);
 
310
 
 
311
    cv::Mat flow;
 
312
    if (useInitFlow)
 
313
    {
 
314
        d_flow.download(flow);
 
315
 
 
316
        farn->setFlags(farn->getFlags() | cv::OPTFLOW_USE_INITIAL_FLOW);
 
317
        farn->calc(loadMat(frame0), loadMat(frame1), d_flow);
 
318
    }
 
319
 
 
320
    cv::calcOpticalFlowFarneback(
 
321
        frame0, frame1, flow, farn->getPyrScale(), farn->getNumLevels(), farn->getWinSize(),
 
322
        farn->getNumIters(), farn->getPolyN(), farn->getPolySigma(), farn->getFlags());
 
323
 
 
324
    EXPECT_MAT_SIMILAR(flow, d_flow, 0.1);
 
325
}
 
326
 
 
327
INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, FarnebackOpticalFlow, testing::Combine(
 
328
    ALL_DEVICES,
 
329
    testing::Values(PyrScale(0.3), PyrScale(0.5), PyrScale(0.8)),
 
330
    testing::Values(PolyN(5), PolyN(7)),
 
331
    testing::Values(FarnebackOptFlowFlags(0), FarnebackOptFlowFlags(cv::OPTFLOW_FARNEBACK_GAUSSIAN)),
 
332
    testing::Values(UseInitFlow(false), UseInitFlow(true))));
 
333
 
 
334
//////////////////////////////////////////////////////
 
335
// OpticalFlowDual_TVL1
 
336
 
 
337
namespace
 
338
{
 
339
    IMPLEMENT_PARAM_CLASS(Gamma, double)
 
340
}
 
341
 
 
342
PARAM_TEST_CASE(OpticalFlowDual_TVL1, cv::cuda::DeviceInfo, Gamma)
 
343
{
 
344
    cv::cuda::DeviceInfo devInfo;
 
345
    double gamma;
 
346
 
 
347
    virtual void SetUp()
 
348
    {
 
349
        devInfo = GET_PARAM(0);
 
350
        gamma = GET_PARAM(1);
 
351
 
 
352
        cv::cuda::setDevice(devInfo.deviceID());
 
353
    }
 
354
};
 
355
 
 
356
CUDA_TEST_P(OpticalFlowDual_TVL1, Accuracy)
 
357
{
 
358
    cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
 
359
    ASSERT_FALSE(frame0.empty());
 
360
 
 
361
    cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
 
362
    ASSERT_FALSE(frame1.empty());
 
363
 
 
364
    cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> d_alg =
 
365
            cv::cuda::OpticalFlowDual_TVL1::create();
 
366
    d_alg->setNumIterations(10);
 
367
    d_alg->setGamma(gamma);
 
368
 
 
369
    cv::cuda::GpuMat d_flow;
 
370
    d_alg->calc(loadMat(frame0), loadMat(frame1), d_flow);
 
371
 
 
372
    cv::Ptr<cv::DualTVL1OpticalFlow> alg = cv::createOptFlow_DualTVL1();
 
373
    alg->setMedianFiltering(1);
 
374
    alg->setInnerIterations(1);
 
375
    alg->setOuterIterations(d_alg->getNumIterations());
 
376
    alg->setGamma(gamma);
 
377
 
 
378
    cv::Mat flow;
 
379
    alg->calc(frame0, frame1, flow);
 
380
 
 
381
    EXPECT_MAT_SIMILAR(flow, d_flow, 4e-3);
 
382
}
 
383
 
 
384
INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, OpticalFlowDual_TVL1, testing::Combine(
 
385
    ALL_DEVICES,
 
386
    testing::Values(Gamma(0.0), Gamma(1.0))));
 
387
 
 
388
#endif // HAVE_CUDA