test_optflow.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  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. #include "test_precomp.hpp"
  43. #ifdef HAVE_CUDA
  44. namespace opencv_test { namespace {
  45. //////////////////////////////////////////////////////
  46. // BroxOpticalFlow
  47. //#define BROX_DUMP
  48. struct BroxOpticalFlow : testing::TestWithParam<cv::cuda::DeviceInfo>
  49. {
  50. cv::cuda::DeviceInfo devInfo;
  51. virtual void SetUp()
  52. {
  53. devInfo = GetParam();
  54. cv::cuda::setDevice(devInfo.deviceID());
  55. }
  56. };
  57. CUDA_TEST_P(BroxOpticalFlow, Regression)
  58. {
  59. cv::Mat frame0 = readImageType("opticalflow/frame0.png", CV_32FC1);
  60. ASSERT_FALSE(frame0.empty());
  61. cv::Mat frame1 = readImageType("opticalflow/frame1.png", CV_32FC1);
  62. ASSERT_FALSE(frame1.empty());
  63. cv::Ptr<cv::cuda::BroxOpticalFlow> brox =
  64. cv::cuda::BroxOpticalFlow::create(0.197 /*alpha*/, 50.0 /*gamma*/, 0.8 /*scale_factor*/,
  65. 10 /*inner_iterations*/, 77 /*outer_iterations*/, 10 /*solver_iterations*/);
  66. cv::cuda::GpuMat flow;
  67. brox->calc(loadMat(frame0), loadMat(frame1), flow);
  68. cv::cuda::GpuMat flows[2];
  69. cv::cuda::split(flow, flows);
  70. cv::cuda::GpuMat u = flows[0];
  71. cv::cuda::GpuMat v = flows[1];
  72. std::string fname(cvtest::TS::ptr()->get_data_path());
  73. if (devInfo.majorVersion() >= 2)
  74. fname += "opticalflow/brox_optical_flow_cc20.bin";
  75. else
  76. fname += "opticalflow/brox_optical_flow.bin";
  77. #ifndef BROX_DUMP
  78. std::ifstream f(fname.c_str(), std::ios_base::binary);
  79. int rows, cols;
  80. f.read((char*) &rows, sizeof(rows));
  81. f.read((char*) &cols, sizeof(cols));
  82. cv::Mat u_gold(rows, cols, CV_32FC1);
  83. for (int i = 0; i < u_gold.rows; ++i)
  84. f.read(u_gold.ptr<char>(i), u_gold.cols * sizeof(float));
  85. cv::Mat v_gold(rows, cols, CV_32FC1);
  86. for (int i = 0; i < v_gold.rows; ++i)
  87. f.read(v_gold.ptr<char>(i), v_gold.cols * sizeof(float));
  88. EXPECT_MAT_SIMILAR(u_gold, u, 1e-3);
  89. EXPECT_MAT_SIMILAR(v_gold, v, 1e-3);
  90. #else
  91. std::ofstream f(fname.c_str(), std::ios_base::binary);
  92. f.write((char*) &u.rows, sizeof(u.rows));
  93. f.write((char*) &u.cols, sizeof(u.cols));
  94. cv::Mat h_u(u);
  95. cv::Mat h_v(v);
  96. for (int i = 0; i < u.rows; ++i)
  97. f.write(h_u.ptr<char>(i), u.cols * sizeof(float));
  98. for (int i = 0; i < v.rows; ++i)
  99. f.write(h_v.ptr<char>(i), v.cols * sizeof(float));
  100. #endif
  101. }
  102. CUDA_TEST_P(BroxOpticalFlow, OpticalFlowNan)
  103. {
  104. cv::Mat frame0 = readImageType("opticalflow/frame0.png", CV_32FC1);
  105. ASSERT_FALSE(frame0.empty());
  106. cv::Mat frame1 = readImageType("opticalflow/frame1.png", CV_32FC1);
  107. ASSERT_FALSE(frame1.empty());
  108. cv::Mat r_frame0, r_frame1;
  109. cv::resize(frame0, r_frame0, cv::Size(1380,1000));
  110. cv::resize(frame1, r_frame1, cv::Size(1380,1000));
  111. cv::Ptr<cv::cuda::BroxOpticalFlow> brox =
  112. cv::cuda::BroxOpticalFlow::create(0.197 /*alpha*/, 50.0 /*gamma*/, 0.8 /*scale_factor*/,
  113. 10 /*inner_iterations*/, 77 /*outer_iterations*/, 10 /*solver_iterations*/);
  114. cv::cuda::GpuMat flow;
  115. brox->calc(loadMat(frame0), loadMat(frame1), flow);
  116. cv::cuda::GpuMat flows[2];
  117. cv::cuda::split(flow, flows);
  118. cv::cuda::GpuMat u = flows[0];
  119. cv::cuda::GpuMat v = flows[1];
  120. cv::Mat h_u, h_v;
  121. u.download(h_u);
  122. v.download(h_v);
  123. EXPECT_TRUE(cv::checkRange(h_u));
  124. EXPECT_TRUE(cv::checkRange(h_v));
  125. };
  126. INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, BroxOpticalFlow, ALL_DEVICES);
  127. //////////////////////////////////////////////////////
  128. // PyrLKOpticalFlow
  129. namespace
  130. {
  131. IMPLEMENT_PARAM_CLASS(Chan, int)
  132. IMPLEMENT_PARAM_CLASS(DataType, int)
  133. }
  134. PARAM_TEST_CASE(PyrLKOpticalFlow, cv::cuda::DeviceInfo, Chan, DataType)
  135. {
  136. cv::cuda::DeviceInfo devInfo;
  137. int channels;
  138. int dataType;
  139. virtual void SetUp()
  140. {
  141. devInfo = GET_PARAM(0);
  142. channels = GET_PARAM(1);
  143. dataType = GET_PARAM(2);
  144. cv::cuda::setDevice(devInfo.deviceID());
  145. }
  146. };
  147. CUDA_TEST_P(PyrLKOpticalFlow, Sparse)
  148. {
  149. cv::Mat frame0 = readImage("opticalflow/frame0.png", channels == 1 ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
  150. ASSERT_FALSE(frame0.empty());
  151. cv::Mat frame1 = readImage("opticalflow/frame1.png", channels == 1 ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
  152. ASSERT_FALSE(frame1.empty());
  153. cv::Mat gray_frame;
  154. if (channels == 1)
  155. gray_frame = frame0;
  156. else
  157. cv::cvtColor(frame0, gray_frame, cv::COLOR_BGR2GRAY);
  158. std::vector<cv::Point2f> pts;
  159. cv::goodFeaturesToTrack(gray_frame, pts, 1000, 0.01, 0.0);
  160. cv::cuda::GpuMat d_pts;
  161. cv::Mat pts_mat(1, (int) pts.size(), CV_32FC2, (void*) &pts[0]);
  162. d_pts.upload(pts_mat);
  163. cv::Ptr<cv::cuda::SparsePyrLKOpticalFlow> pyrLK =
  164. cv::cuda::SparsePyrLKOpticalFlow::create();
  165. std::vector<cv::Point2f> nextPts_gold;
  166. std::vector<unsigned char> status_gold;
  167. cv::calcOpticalFlowPyrLK(frame0, frame1, pts, nextPts_gold, status_gold, cv::noArray());
  168. cv::cuda::GpuMat d_nextPts;
  169. cv::cuda::GpuMat d_status;
  170. cv::Mat converted0, converted1;
  171. if(channels == 4)
  172. {
  173. cv::cvtColor(frame0, frame0, cv::COLOR_BGR2BGRA);
  174. cv::cvtColor(frame1, frame1, cv::COLOR_BGR2BGRA);
  175. }
  176. frame0.convertTo(converted0, dataType);
  177. frame1.convertTo(converted1, dataType);
  178. pyrLK->calc(loadMat(converted0), loadMat(converted1), d_pts, d_nextPts, d_status);
  179. std::vector<cv::Point2f> nextPts(d_nextPts.cols);
  180. cv::Mat nextPts_mat(1, d_nextPts.cols, CV_32FC2, (void*)&nextPts[0]);
  181. d_nextPts.download(nextPts_mat);
  182. std::vector<unsigned char> status(d_status.cols);
  183. cv::Mat status_mat(1, d_status.cols, CV_8UC1, (void*)&status[0]);
  184. d_status.download(status_mat);
  185. ASSERT_EQ(nextPts_gold.size(), nextPts.size());
  186. ASSERT_EQ(status_gold.size(), status.size());
  187. size_t mistmatch = 0;
  188. for (size_t i = 0; i < nextPts.size(); ++i)
  189. {
  190. cv::Point2i a = nextPts[i];
  191. cv::Point2i b = nextPts_gold[i];
  192. if (status[i] != status_gold[i])
  193. {
  194. ++mistmatch;
  195. continue;
  196. }
  197. if (status[i])
  198. {
  199. bool eq = std::abs(a.x - b.x) <= 1 && std::abs(a.y - b.y) <= 1;
  200. if (!eq)
  201. ++mistmatch;
  202. }
  203. }
  204. double bad_ratio = static_cast<double>(mistmatch) / nextPts.size();
  205. ASSERT_LE(bad_ratio, 0.01);
  206. }
  207. INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, PyrLKOpticalFlow, testing::Combine(
  208. ALL_DEVICES,
  209. testing::Values(Chan(1), Chan(3), Chan(4)),
  210. testing::Values(DataType(CV_8U), DataType(CV_16U), DataType(CV_32S), DataType(CV_32F))));
  211. //////////////////////////////////////////////////////
  212. // FarnebackOpticalFlow
  213. namespace
  214. {
  215. IMPLEMENT_PARAM_CLASS(PyrScale, double)
  216. IMPLEMENT_PARAM_CLASS(PolyN, int)
  217. CV_FLAGS(FarnebackOptFlowFlags, 0, OPTFLOW_FARNEBACK_GAUSSIAN)
  218. IMPLEMENT_PARAM_CLASS(UseInitFlow, bool)
  219. }
  220. PARAM_TEST_CASE(FarnebackOpticalFlow, cv::cuda::DeviceInfo, PyrScale, PolyN, FarnebackOptFlowFlags, UseInitFlow)
  221. {
  222. cv::cuda::DeviceInfo devInfo;
  223. double pyrScale;
  224. int polyN;
  225. int flags;
  226. bool useInitFlow;
  227. virtual void SetUp()
  228. {
  229. devInfo = GET_PARAM(0);
  230. pyrScale = GET_PARAM(1);
  231. polyN = GET_PARAM(2);
  232. flags = GET_PARAM(3);
  233. useInitFlow = GET_PARAM(4);
  234. cv::cuda::setDevice(devInfo.deviceID());
  235. }
  236. };
  237. CUDA_TEST_P(FarnebackOpticalFlow, Accuracy)
  238. {
  239. cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
  240. ASSERT_FALSE(frame0.empty());
  241. cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
  242. ASSERT_FALSE(frame1.empty());
  243. double polySigma = polyN <= 5 ? 1.1 : 1.5;
  244. cv::Ptr<cv::cuda::FarnebackOpticalFlow> farn =
  245. cv::cuda::FarnebackOpticalFlow::create();
  246. farn->setPyrScale(pyrScale);
  247. farn->setPolyN(polyN);
  248. farn->setPolySigma(polySigma);
  249. farn->setFlags(flags);
  250. cv::cuda::GpuMat d_flow;
  251. farn->calc(loadMat(frame0), loadMat(frame1), d_flow);
  252. cv::Mat flow;
  253. if (useInitFlow)
  254. {
  255. d_flow.download(flow);
  256. farn->setFlags(farn->getFlags() | cv::OPTFLOW_USE_INITIAL_FLOW);
  257. farn->calc(loadMat(frame0), loadMat(frame1), d_flow);
  258. }
  259. cv::calcOpticalFlowFarneback(
  260. frame0, frame1, flow, farn->getPyrScale(), farn->getNumLevels(), farn->getWinSize(),
  261. farn->getNumIters(), farn->getPolyN(), farn->getPolySigma(), farn->getFlags());
  262. // Relax test limit when the flag is set
  263. if (farn->getFlags() & cv::OPTFLOW_FARNEBACK_GAUSSIAN)
  264. {
  265. EXPECT_MAT_SIMILAR(flow, d_flow, 2e-2);
  266. }
  267. else
  268. {
  269. EXPECT_MAT_SIMILAR(flow, d_flow, 1e-4);
  270. }
  271. }
  272. INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, FarnebackOpticalFlow, testing::Combine(
  273. ALL_DEVICES,
  274. testing::Values(PyrScale(0.3), PyrScale(0.5), PyrScale(0.8)),
  275. testing::Values(PolyN(5), PolyN(7)),
  276. testing::Values(FarnebackOptFlowFlags(0), FarnebackOptFlowFlags(cv::OPTFLOW_FARNEBACK_GAUSSIAN)),
  277. testing::Values(UseInitFlow(false), UseInitFlow(true))));
  278. //////////////////////////////////////////////////////
  279. // OpticalFlowDual_TVL1
  280. namespace
  281. {
  282. IMPLEMENT_PARAM_CLASS(Gamma, double)
  283. }
  284. PARAM_TEST_CASE(OpticalFlowDual_TVL1, cv::cuda::DeviceInfo, Gamma)
  285. {
  286. cv::cuda::DeviceInfo devInfo;
  287. double gamma;
  288. virtual void SetUp()
  289. {
  290. devInfo = GET_PARAM(0);
  291. gamma = GET_PARAM(1);
  292. cv::cuda::setDevice(devInfo.deviceID());
  293. }
  294. };
  295. CUDA_TEST_P(OpticalFlowDual_TVL1, Accuracy)
  296. {
  297. cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
  298. ASSERT_FALSE(frame0.empty());
  299. cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
  300. ASSERT_FALSE(frame1.empty());
  301. cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> d_alg =
  302. cv::cuda::OpticalFlowDual_TVL1::create();
  303. d_alg->setNumIterations(10);
  304. d_alg->setGamma(gamma);
  305. cv::cuda::GpuMat d_flow;
  306. d_alg->calc(loadMat(frame0), loadMat(frame1), d_flow);
  307. cv::Ptr<cv::optflow::DualTVL1OpticalFlow> alg = cv::optflow::createOptFlow_DualTVL1();
  308. alg->setMedianFiltering(1);
  309. alg->setInnerIterations(1);
  310. alg->setOuterIterations(d_alg->getNumIterations());
  311. alg->setGamma(gamma);
  312. cv::Mat flow;
  313. alg->calc(frame0, frame1, flow);
  314. EXPECT_MAT_SIMILAR(flow, d_flow, 4e-3);
  315. }
  316. class TVL1AsyncParallelLoopBody : public cv::ParallelLoopBody
  317. {
  318. public:
  319. TVL1AsyncParallelLoopBody(const cv::cuda::GpuMat& d_img1_, const cv::cuda::GpuMat& d_img2_, cv::cuda::GpuMat* d_flow_, int iterations_, double gamma_)
  320. : d_img1(d_img1_), d_img2(d_img2_), d_flow(d_flow_), iterations(iterations_), gamma(gamma_) {}
  321. ~TVL1AsyncParallelLoopBody() {}
  322. void operator()(const cv::Range& r) const
  323. {
  324. for (int i = r.start; i < r.end; i++) {
  325. cv::cuda::Stream stream;
  326. cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> d_alg = cv::cuda::OpticalFlowDual_TVL1::create();
  327. d_alg->setNumIterations(iterations);
  328. d_alg->setGamma(gamma);
  329. d_alg->calc(d_img1, d_img2, d_flow[i], stream);
  330. stream.waitForCompletion();
  331. }
  332. }
  333. protected:
  334. const cv::cuda::GpuMat& d_img1;
  335. const cv::cuda::GpuMat& d_img2;
  336. cv::cuda::GpuMat* d_flow;
  337. int iterations;
  338. double gamma;
  339. };
  340. #define NUM_STREAMS 16
  341. CUDA_TEST_P(OpticalFlowDual_TVL1, Async)
  342. {
  343. if (!supportFeature(devInfo, cv::cuda::FEATURE_SET_COMPUTE_30))
  344. {
  345. throw SkipTestException("CUDA device doesn't support texture objects");
  346. }
  347. else
  348. {
  349. cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
  350. ASSERT_FALSE(frame0.empty());
  351. cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
  352. ASSERT_FALSE(frame1.empty());
  353. const int iterations = 10;
  354. // Synchronous call
  355. cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> d_alg =
  356. cv::cuda::OpticalFlowDual_TVL1::create();
  357. d_alg->setNumIterations(iterations);
  358. d_alg->setGamma(gamma);
  359. cv::cuda::GpuMat d_flow_gold;
  360. d_alg->calc(loadMat(frame0), loadMat(frame1), d_flow_gold);
  361. // Asynchronous call
  362. cv::cuda::GpuMat d_flow[NUM_STREAMS];
  363. cv::parallel_for_(cv::Range(0, NUM_STREAMS), TVL1AsyncParallelLoopBody(loadMat(frame0), loadMat(frame1), d_flow, iterations, gamma));
  364. // Compare the results of synchronous call and asynchronous call
  365. for (int i = 0; i < NUM_STREAMS; i++)
  366. EXPECT_MAT_NEAR(d_flow_gold, d_flow[i], 0.0);
  367. }
  368. }
  369. INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, OpticalFlowDual_TVL1, testing::Combine(
  370. ALL_DEVICES,
  371. testing::Values(Gamma(0.0), Gamma(1.0))));
  372. //////////////////////////////////////////////////////
  373. // NvidiaOpticalFlow_1_0
  374. struct NvidiaOpticalFlow_1_0 : testing::TestWithParam<cv::cuda::DeviceInfo>
  375. {
  376. cv::cuda::DeviceInfo devInfo;
  377. virtual void SetUp()
  378. {
  379. devInfo = GetParam();
  380. cv::cuda::setDevice(devInfo.deviceID());
  381. }
  382. };
  383. CUDA_TEST_P(NvidiaOpticalFlow_1_0, Regression)
  384. {
  385. cv::Mat frame0 = readImage("opticalflow/frame0.png", cv::IMREAD_GRAYSCALE);
  386. ASSERT_FALSE(frame0.empty());
  387. cv::Mat frame1 = readImage("opticalflow/frame1.png", cv::IMREAD_GRAYSCALE);
  388. ASSERT_FALSE(frame1.empty());
  389. cv::Ptr<cv::cuda::NvidiaOpticalFlow_1_0> d_nvof;
  390. try
  391. {
  392. d_nvof = cv::cuda::NvidiaOpticalFlow_1_0::create(frame0.size(),
  393. cv::cuda::NvidiaOpticalFlow_1_0::NVIDIA_OF_PERF_LEVEL::NV_OF_PERF_LEVEL_SLOW);
  394. }
  395. catch (const cv::Exception& e)
  396. {
  397. if (e.code == Error::StsBadFunc || e.code == Error::StsBadArg || e.code == Error::StsNullPtr)
  398. throw SkipTestException("Current configuration is not supported");
  399. throw;
  400. }
  401. const int gridSize = d_nvof->getGridSize();
  402. Mat flow, upsampledFlow;
  403. d_nvof->calc(loadMat(frame0), loadMat(frame1), flow);
  404. d_nvof->upSampler(flow, frame0.size(), gridSize, upsampledFlow);
  405. std::string fname(cvtest::TS::ptr()->get_data_path());
  406. fname += "opticalflow/nvofGolden.flo";
  407. cv::Mat golden = cv::readOpticalFlow(fname.c_str());
  408. ASSERT_FALSE(golden.empty());
  409. EXPECT_MAT_SIMILAR(golden, upsampledFlow, 1e-10);
  410. d_nvof->collectGarbage();
  411. }
  412. CUDA_TEST_P(NvidiaOpticalFlow_1_0, OpticalFlowNan)
  413. {
  414. cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
  415. ASSERT_FALSE(frame0.empty());
  416. cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
  417. ASSERT_FALSE(frame1.empty());
  418. cv::Mat r_frame0, r_frame1;
  419. cv::Ptr<cv::cuda::NvidiaOpticalFlow_1_0> d_nvof;
  420. try
  421. {
  422. d_nvof = cv::cuda::NvidiaOpticalFlow_1_0::create(frame0.size(),
  423. cv::cuda::NvidiaOpticalFlow_1_0::NVIDIA_OF_PERF_LEVEL::NV_OF_PERF_LEVEL_SLOW);
  424. }
  425. catch (const cv::Exception& e)
  426. {
  427. if (e.code == Error::StsBadFunc || e.code == Error::StsBadArg || e.code == Error::StsNullPtr)
  428. throw SkipTestException("Current configuration is not supported");
  429. throw;
  430. }
  431. Mat flow, flowx, flowy;
  432. d_nvof->calc(loadMat(frame0), loadMat(frame1), flow);
  433. Mat planes[] = { flowx, flowy };
  434. split(flow, planes);
  435. flowx = planes[0]; flowy = planes[1];
  436. EXPECT_TRUE(cv::checkRange(flowx));
  437. EXPECT_TRUE(cv::checkRange(flowy));
  438. d_nvof->collectGarbage();
  439. };
  440. INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, NvidiaOpticalFlow_1_0, ALL_DEVICES);
  441. //////////////////////////////////////////////////////
  442. // NvidiaOpticalFlow_2_0
  443. struct NvidiaOpticalFlow_2_0 : testing::TestWithParam<cv::cuda::DeviceInfo>
  444. {
  445. cv::cuda::DeviceInfo devInfo;
  446. virtual void SetUp()
  447. {
  448. devInfo = GetParam();
  449. cv::cuda::setDevice(devInfo.deviceID());
  450. }
  451. };
  452. CUDA_TEST_P(NvidiaOpticalFlow_2_0, Regression)
  453. {
  454. cv::Mat frame0 = readImage("opticalflow/frame0.png", cv::IMREAD_GRAYSCALE);
  455. ASSERT_FALSE(frame0.empty());
  456. cv::Mat frame1 = readImage("opticalflow/frame1.png", cv::IMREAD_GRAYSCALE);
  457. ASSERT_FALSE(frame1.empty());
  458. cv::Ptr<cv::cuda::NvidiaOpticalFlow_2_0> d_nvof;
  459. try
  460. {
  461. d_nvof = cv::cuda::NvidiaOpticalFlow_2_0::create(frame0.size(),
  462. cv::cuda::NvidiaOpticalFlow_2_0::NVIDIA_OF_PERF_LEVEL::NV_OF_PERF_LEVEL_SLOW);
  463. }
  464. catch (const cv::Exception& e)
  465. {
  466. if (e.code == Error::StsBadFunc || e.code == Error::StsBadArg || e.code == Error::StsNullPtr)
  467. throw SkipTestException("Current configuration is not supported");
  468. throw;
  469. }
  470. Mat flow, upsampledFlow;
  471. d_nvof->calc(loadMat(frame0), loadMat(frame1), flow);
  472. d_nvof->convertToFloat(flow, upsampledFlow);
  473. std::string fname(cvtest::TS::ptr()->get_data_path());
  474. fname += "opticalflow/nvofGolden_2.flo";
  475. cv::Mat golden = cv::readOpticalFlow(fname.c_str());
  476. ASSERT_FALSE(golden.empty());
  477. EXPECT_MAT_SIMILAR(golden, upsampledFlow, 1e-10);
  478. }
  479. CUDA_TEST_P(NvidiaOpticalFlow_2_0, OpticalFlowNan)
  480. {
  481. cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
  482. ASSERT_FALSE(frame0.empty());
  483. cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
  484. ASSERT_FALSE(frame1.empty());
  485. cv::Mat r_frame0, r_frame1;
  486. cv::Ptr<cv::cuda::NvidiaOpticalFlow_2_0> d_nvof;
  487. try
  488. {
  489. d_nvof = cv::cuda::NvidiaOpticalFlow_2_0::create(frame0.size(),
  490. cv::cuda::NvidiaOpticalFlow_2_0::NVIDIA_OF_PERF_LEVEL::NV_OF_PERF_LEVEL_SLOW);
  491. }
  492. catch (const cv::Exception& e)
  493. {
  494. if (e.code == Error::StsBadFunc || e.code == Error::StsBadArg || e.code == Error::StsNullPtr)
  495. throw SkipTestException("Current configuration is not supported");
  496. throw;
  497. }
  498. Mat flow, flowx, flowy;
  499. d_nvof->calc(loadMat(frame0), loadMat(frame1), flow);
  500. Mat planes[] = { flowx, flowy };
  501. split(flow, planes);
  502. flowx = planes[0]; flowy = planes[1];
  503. EXPECT_TRUE(cv::checkRange(flowx));
  504. EXPECT_TRUE(cv::checkRange(flowy));
  505. };
  506. INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, NvidiaOpticalFlow_2_0, ALL_DEVICES);
  507. }} // namespace
  508. #endif // HAVE_CUDA