Merge pull request #1263 from abidrahmank:pyCLAHE_24
[profile/ivi/opencv.git] / modules / ocl / test / test_optflow.cpp
1 ///////////////////////////////////////////////////////////////////////////////////////
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 // Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
13 // Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
14 // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // @Authors
18 //
19 //
20 // Redistribution and use in source and binary forms, with or without modification,
21 // are permitted provided that the following conditions are met:
22 //
23 //   * Redistribution's of source code must retain the above copyright notice,
24 //     this list of conditions and the following disclaimer.
25 //
26 //   * Redistribution's in binary form must reproduce the above copyright notice,
27 //     this list of conditions and the following disclaimer in the documentation
28 //     and/or other oclMaterials provided with the distribution.
29 //
30 //   * The name of the copyright holders may not be used to endorse or promote products
31 //     derived from this software without specific prior written permission.
32 //
33 // This software is provided by the copyright holders and contributors "as is" and
34 // any express or implied warranties, including, but not limited to, the implied
35 // warranties of merchantability and fitness for a particular purpose are disclaimed.
36 // In no event shall the Intel Corporation or contributors be liable for any direct,
37 // indirect, incidental, special, exemplary, or consequential damages
38 // (including, but not limited to, procurement of substitute goods or services;
39 // loss of use, data, or profits; or business interruption) however caused
40 // and on any theory of liability, whether in contract, strict liability,
41 // or tort (including negligence or otherwise) arising in any way out of
42 // the use of this software, even if advised of the possibility of such damage.
43 //
44 //M*/
45
46 #include "test_precomp.hpp"
47 #include <iomanip>
48
49 #ifdef HAVE_OPENCL
50
51 using namespace cv;
52 using namespace cv::ocl;
53 using namespace cvtest;
54 using namespace testing;
55 using namespace std;
56
57 extern string workdir;
58
59
60 //////////////////////////////////////////////////////
61 // GoodFeaturesToTrack
62 namespace
63 {
64     IMPLEMENT_PARAM_CLASS(MinDistance, double)
65 }
66 PARAM_TEST_CASE(GoodFeaturesToTrack, MinDistance)
67 {
68     double minDistance;
69
70     virtual void SetUp()
71     {
72         minDistance = GET_PARAM(0);
73     }
74 };
75
76 TEST_P(GoodFeaturesToTrack, Accuracy)
77 {
78     cv::Mat frame = readImage("gpu/opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
79     ASSERT_FALSE(frame.empty());
80
81     int maxCorners = 1000;
82     double qualityLevel = 0.01;
83
84     cv::ocl::GoodFeaturesToTrackDetector_OCL detector(maxCorners, qualityLevel, minDistance);
85
86     cv::ocl::oclMat d_pts;
87     detector(oclMat(frame), d_pts);
88
89     ASSERT_FALSE(d_pts.empty());
90
91     std::vector<cv::Point2f> pts(d_pts.cols);
92     
93     detector.downloadPoints(d_pts, pts);
94
95     std::vector<cv::Point2f> pts_gold;
96     cv::goodFeaturesToTrack(frame, pts_gold, maxCorners, qualityLevel, minDistance);
97
98     ASSERT_EQ(pts_gold.size(), pts.size());
99
100     size_t mistmatch = 0;
101     for (size_t i = 0; i < pts.size(); ++i)
102     {
103         cv::Point2i a = pts_gold[i];
104         cv::Point2i b = pts[i];
105
106         bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1;
107
108         if (!eq)
109             ++mistmatch;
110     }
111
112     double bad_ratio = static_cast<double>(mistmatch) / pts.size();
113
114     ASSERT_LE(bad_ratio, 0.01);
115 }
116
117 TEST_P(GoodFeaturesToTrack, EmptyCorners)
118 {
119     int maxCorners = 1000;
120     double qualityLevel = 0.01;
121
122     cv::ocl::GoodFeaturesToTrackDetector_OCL detector(maxCorners, qualityLevel, minDistance);
123
124     cv::ocl::oclMat src(100, 100, CV_8UC1, cv::Scalar::all(0));
125     cv::ocl::oclMat corners(1, maxCorners, CV_32FC2);
126
127     detector(src, corners);
128
129     ASSERT_TRUE(corners.empty());
130 }
131
132 INSTANTIATE_TEST_CASE_P(OCL_Video, GoodFeaturesToTrack, 
133     testing::Values(MinDistance(0.0), MinDistance(3.0)));
134
135 //////////////////////////////////////////////////////////////////////////
136 PARAM_TEST_CASE(TVL1, bool)
137 {
138     bool useRoi;
139
140     virtual void SetUp()
141     {
142         useRoi = GET_PARAM(0);
143     }
144
145 };
146
147 TEST_P(TVL1, Accuracy)
148 {
149     cv::Mat frame0 = readImage("gpu/opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
150     ASSERT_FALSE(frame0.empty());
151
152     cv::Mat frame1 = readImage("gpu/opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
153     ASSERT_FALSE(frame1.empty());
154
155     cv::ocl::OpticalFlowDual_TVL1_OCL d_alg;
156     cv::RNG &rng = TS::ptr()->get_rng();
157     cv::Mat flowx = randomMat(rng, frame0.size(), CV_32FC1, 0, 0, useRoi);
158     cv::Mat flowy = randomMat(rng, frame0.size(), CV_32FC1, 0, 0, useRoi);
159     cv::ocl::oclMat d_flowx(flowx), d_flowy(flowy);
160     d_alg(oclMat(frame0), oclMat(frame1), d_flowx, d_flowy);
161
162     cv::Ptr<cv::DenseOpticalFlow> alg = cv::createOptFlow_DualTVL1();
163     cv::Mat flow;
164     alg->calc(frame0, frame1, flow);
165     cv::Mat gold[2];
166     cv::split(flow, gold);
167
168     EXPECT_MAT_SIMILAR(gold[0], d_flowx, 3e-3);
169     EXPECT_MAT_SIMILAR(gold[1], d_flowy, 3e-3);
170 }
171 INSTANTIATE_TEST_CASE_P(OCL_Video, TVL1, Values(true, false));
172
173
174 /////////////////////////////////////////////////////////////////////////////////////////////////
175 // PyrLKOpticalFlow
176
177 PARAM_TEST_CASE(Sparse, bool, bool)
178 {
179     bool useGray;
180     bool UseSmart;
181
182     virtual void SetUp()
183     {
184         UseSmart = GET_PARAM(0);
185         useGray = GET_PARAM(1);
186     }
187 };
188
189 TEST_P(Sparse, Mat)
190 {
191     cv::Mat frame0 = readImage("gpu/opticalflow/rubberwhale1.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
192     ASSERT_FALSE(frame0.empty());
193
194     cv::Mat frame1 = readImage("gpu/opticalflow/rubberwhale2.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
195     ASSERT_FALSE(frame1.empty());
196
197     cv::Mat gray_frame;
198     if (useGray)
199         gray_frame = frame0;
200     else
201         cv::cvtColor(frame0, gray_frame, cv::COLOR_BGR2GRAY);
202
203     std::vector<cv::Point2f> pts;
204     cv::goodFeaturesToTrack(gray_frame, pts, 1000, 0.01, 0.0);
205
206     cv::ocl::oclMat d_pts;
207     cv::Mat pts_mat(1, (int)pts.size(), CV_32FC2, (void *)&pts[0]);
208     d_pts.upload(pts_mat);
209
210     cv::ocl::PyrLKOpticalFlow pyrLK;
211
212     cv::ocl::oclMat oclFrame0;
213     cv::ocl::oclMat oclFrame1;
214     cv::ocl::oclMat d_nextPts;
215     cv::ocl::oclMat d_status;
216     cv::ocl::oclMat d_err;
217
218     oclFrame0 = frame0;
219     oclFrame1 = frame1;
220
221     pyrLK.sparse(oclFrame0, oclFrame1, d_pts, d_nextPts, d_status, &d_err);
222
223     std::vector<cv::Point2f> nextPts(d_nextPts.cols);
224     cv::Mat nextPts_mat(1, d_nextPts.cols, CV_32FC2, (void *)&nextPts[0]);
225     d_nextPts.download(nextPts_mat);
226
227     std::vector<unsigned char> status(d_status.cols);
228     cv::Mat status_mat(1, d_status.cols, CV_8UC1, (void *)&status[0]);
229     d_status.download(status_mat);
230
231     std::vector<float> err(d_err.cols);
232     cv::Mat err_mat(1, d_err.cols, CV_32FC1, (void*)&err[0]);
233     d_err.download(err_mat);
234
235     std::vector<cv::Point2f> nextPts_gold;
236     std::vector<unsigned char> status_gold;
237     std::vector<float> err_gold;
238     cv::calcOpticalFlowPyrLK(frame0, frame1, pts, nextPts_gold, status_gold, err_gold);
239
240     ASSERT_EQ(nextPts_gold.size(), nextPts.size());
241     ASSERT_EQ(status_gold.size(), status.size());
242
243     size_t mistmatch = 0;
244     for (size_t i = 0; i < nextPts.size(); ++i)
245     {
246         if (status[i] != status_gold[i])
247         {
248             ++mistmatch;
249             continue;
250         }
251
252         if (status[i])
253         {
254             cv::Point2i a = nextPts[i];
255             cv::Point2i b = nextPts_gold[i];
256
257             bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1;
258             //float errdiff = std::abs(err[i] - err_gold[i]);
259             float errdiff = 0.0f;
260
261             if (!eq || errdiff > 1e-1)
262                 ++mistmatch;
263         }
264     }
265
266     double bad_ratio = static_cast<double>(mistmatch) / (nextPts.size());
267
268     ASSERT_LE(bad_ratio, 0.02f);
269
270 }
271
272 INSTANTIATE_TEST_CASE_P(OCL_Video, Sparse, Combine(
273     Values(false, true),
274     Values(false, true)));
275 //////////////////////////////////////////////////////
276 // FarnebackOpticalFlow
277
278 namespace
279 {
280     IMPLEMENT_PARAM_CLASS(PyrScale, double)
281         IMPLEMENT_PARAM_CLASS(PolyN, int)
282         CV_FLAGS(FarnebackOptFlowFlags, 0, OPTFLOW_FARNEBACK_GAUSSIAN)
283         IMPLEMENT_PARAM_CLASS(UseInitFlow, bool)
284 }
285
286 PARAM_TEST_CASE(Farneback, PyrScale, PolyN, FarnebackOptFlowFlags, UseInitFlow)
287 {
288     double pyrScale;
289     int polyN;
290     int flags;
291     bool useInitFlow;
292
293     virtual void SetUp()
294     {
295         pyrScale = GET_PARAM(0);
296         polyN = GET_PARAM(1);
297         flags = GET_PARAM(2);
298         useInitFlow = GET_PARAM(3);
299     }
300 };
301
302 TEST_P(Farneback, Accuracy)
303 {
304     cv::Mat frame0 = readImage("gpu/opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
305     ASSERT_FALSE(frame0.empty());
306
307     cv::Mat frame1 = readImage("gpu/opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
308     ASSERT_FALSE(frame1.empty());
309
310     double polySigma = polyN <= 5 ? 1.1 : 1.5;
311
312     cv::ocl::FarnebackOpticalFlow farn;
313     farn.pyrScale = pyrScale;
314     farn.polyN = polyN;
315     farn.polySigma = polySigma;
316     farn.flags = flags;
317
318     cv::ocl::oclMat d_flowx, d_flowy;
319     farn(oclMat(frame0), oclMat(frame1), d_flowx, d_flowy);
320
321     cv::Mat flow;
322     if (useInitFlow)
323     {
324         cv::Mat flowxy[] = {cv::Mat(d_flowx), cv::Mat(d_flowy)};
325         cv::merge(flowxy, 2, flow);
326
327         farn.flags |= cv::OPTFLOW_USE_INITIAL_FLOW;
328         farn(oclMat(frame0), oclMat(frame1), d_flowx, d_flowy);
329     }
330
331     cv::calcOpticalFlowFarneback(
332         frame0, frame1, flow, farn.pyrScale, farn.numLevels, farn.winSize,
333         farn.numIters, farn.polyN, farn.polySigma, farn.flags);
334
335     std::vector<cv::Mat> flowxy;
336     cv::split(flow, flowxy);
337
338     EXPECT_MAT_SIMILAR(flowxy[0], d_flowx, 0.1);
339     EXPECT_MAT_SIMILAR(flowxy[1], d_flowy, 0.1);
340 }
341
342 INSTANTIATE_TEST_CASE_P(OCL_Video, Farneback, testing::Combine(
343     testing::Values(PyrScale(0.3), PyrScale(0.5), PyrScale(0.8)),
344     testing::Values(PolyN(5), PolyN(7)),
345     testing::Values(FarnebackOptFlowFlags(0), FarnebackOptFlowFlags(cv::OPTFLOW_FARNEBACK_GAUSSIAN)),
346     testing::Values(UseInitFlow(false), UseInitFlow(true))));
347
348 #endif // HAVE_OPENCL
349