gapi_video_tests_inl.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. //
  5. // Copyright (C) 2020 Intel Corporation
  6. #ifndef OPENCV_GAPI_VIDEO_TESTS_INL_HPP
  7. #define OPENCV_GAPI_VIDEO_TESTS_INL_HPP
  8. #include "gapi_video_tests.hpp"
  9. #include <opencv2/gapi/streaming/cap.hpp>
  10. namespace opencv_test
  11. {
  12. TEST_P(BuildOptFlowPyramidTest, AccuracyTest)
  13. {
  14. std::vector<Mat> outPyrOCV, outPyrGAPI;
  15. int outMaxLevelOCV = 0, outMaxLevelGAPI = 0;
  16. BuildOpticalFlowPyramidTestParams params { fileName, winSize, maxLevel,
  17. withDerivatives, pyrBorder, derivBorder,
  18. tryReuseInputImage, getCompileArgs() };
  19. BuildOpticalFlowPyramidTestOutput outOCV { outPyrOCV, outMaxLevelOCV };
  20. BuildOpticalFlowPyramidTestOutput outGAPI { outPyrGAPI, outMaxLevelGAPI };
  21. runOCVnGAPIBuildOptFlowPyramid(*this, params, outOCV, outGAPI);
  22. compareOutputPyramids(outGAPI, outOCV);
  23. }
  24. TEST_P(OptFlowLKTest, AccuracyTest)
  25. {
  26. std::vector<cv::Point2f> outPtsOCV, outPtsGAPI, inPts;
  27. std::vector<uchar> outStatusOCV, outStatusGAPI;
  28. std::vector<float> outErrOCV, outErrGAPI;
  29. OptFlowLKTestParams params { fileNamePattern, channels, pointsNum,
  30. winSize, criteria, getCompileArgs() };
  31. OptFlowLKTestOutput outOCV { outPtsOCV, outStatusOCV, outErrOCV };
  32. OptFlowLKTestOutput outGAPI { outPtsGAPI, outStatusGAPI, outErrGAPI };
  33. runOCVnGAPIOptFlowLK(*this, inPts, params, outOCV, outGAPI);
  34. compareOutputsOptFlow(outGAPI, outOCV);
  35. }
  36. TEST_P(OptFlowLKTestForPyr, AccuracyTest)
  37. {
  38. std::vector<cv::Mat> inPyr1, inPyr2;
  39. std::vector<cv::Point2f> outPtsOCV, outPtsGAPI, inPts;
  40. std::vector<uchar> outStatusOCV, outStatusGAPI;
  41. std::vector<float> outErrOCV, outErrGAPI;
  42. OptFlowLKTestParams params { fileNamePattern, channels, pointsNum,
  43. winSize, criteria, getCompileArgs() };
  44. OptFlowLKTestInput<std::vector<cv::Mat>> in { inPyr1, inPyr2, inPts };
  45. OptFlowLKTestOutput outOCV { outPtsOCV, outStatusOCV, outErrOCV };
  46. OptFlowLKTestOutput outGAPI { outPtsGAPI, outStatusGAPI, outErrGAPI };
  47. runOCVnGAPIOptFlowLKForPyr(*this, in, params, withDeriv, outOCV, outGAPI);
  48. compareOutputsOptFlow(outGAPI, outOCV);
  49. }
  50. TEST_P(BuildPyr_CalcOptFlow_PipelineTest, AccuracyTest)
  51. {
  52. std::vector<Point2f> outPtsOCV, outPtsGAPI, inPts;
  53. std::vector<uchar> outStatusOCV, outStatusGAPI;
  54. std::vector<float> outErrOCV, outErrGAPI;
  55. BuildOpticalFlowPyramidTestParams params { fileNamePattern, winSize, maxLevel,
  56. withDerivatives, BORDER_DEFAULT, BORDER_DEFAULT,
  57. true, getCompileArgs() };
  58. auto customKernel = gapi::kernels<GCPUMinScalar>();
  59. auto kernels = gapi::combine(customKernel,
  60. params.compileArgs[0].get<GKernelPackage>());
  61. params.compileArgs = compile_args(kernels);
  62. OptFlowLKTestOutput outOCV { outPtsOCV, outStatusOCV, outErrOCV };
  63. OptFlowLKTestOutput outGAPI { outPtsGAPI, outStatusGAPI, outErrGAPI };
  64. runOCVnGAPIOptFlowPipeline(*this, params, outOCV, outGAPI, inPts);
  65. compareOutputsOptFlow(outGAPI, outOCV);
  66. }
  67. #ifdef HAVE_OPENCV_VIDEO
  68. TEST_P(BackgroundSubtractorTest, AccuracyTest)
  69. {
  70. cv::gapi::video::BackgroundSubtractorType opType;
  71. double thr = -1;
  72. std::tie(opType, thr) = typeAndThreshold;
  73. cv::gapi::video::BackgroundSubtractorParams bsp(opType, histLength, thr,
  74. detectShadows, learningRate);
  75. // G-API graph declaration
  76. cv::GMat in;
  77. cv::GMat out = cv::gapi::BackgroundSubtractor(in, bsp);
  78. // Preserving 'in' in output to have possibility to compare with OpenCV reference
  79. cv::GComputation c(cv::GIn(in), cv::GOut(cv::gapi::copy(in), out));
  80. // G-API compilation of graph for streaming mode
  81. auto gapiBackSub = c.compileStreaming(getCompileArgs());
  82. // Testing G-API Background Substractor in streaming mode
  83. const auto path = findDataFile(filePath);
  84. try
  85. {
  86. gapiBackSub.setSource(gapi::wip::make_src<cv::gapi::wip::GCaptureSource>(path));
  87. }
  88. catch (...)
  89. { throw SkipTestException("Video file can't be opened."); }
  90. cv::Ptr<cv::BackgroundSubtractor> pOCVBackSub;
  91. if (opType == cv::gapi::video::TYPE_BS_MOG2)
  92. pOCVBackSub = cv::createBackgroundSubtractorMOG2(histLength, thr,
  93. detectShadows);
  94. else if (opType == cv::gapi::video::TYPE_BS_KNN)
  95. pOCVBackSub = cv::createBackgroundSubtractorKNN(histLength, thr,
  96. detectShadows);
  97. // Allowing 1% difference of all pixels between G-API and reference OpenCV results
  98. testBackgroundSubtractorStreaming(gapiBackSub, pOCVBackSub, 1, 1, learningRate, testNumFrames);
  99. }
  100. TEST_P(KalmanFilterTest, AccuracyTest)
  101. {
  102. cv::gapi::KalmanParams kp;
  103. initKalmanParams(type, dDim, mDim, cDim, kp);
  104. // OpenCV reference KalmanFilter initialization
  105. cv::KalmanFilter ocvKalman(dDim, mDim, cDim, type);
  106. initKalmanFilter(kp, true, ocvKalman);
  107. // measurement vector
  108. cv::Mat measure_vec(mDim, 1, type);
  109. // control vector
  110. cv::Mat ctrl_vec = Mat::zeros(cDim > 0 ? cDim : 2, 1, type);
  111. // G-API Kalman's output state
  112. cv::Mat gapiKState(dDim, 1, type);
  113. // OCV Kalman's output state
  114. cv::Mat ocvKState(dDim, 1, type);
  115. // G-API graph initialization
  116. cv::GMat m, ctrl;
  117. cv::GOpaque<bool> have_m;
  118. cv::GMat out = cv::gapi::KalmanFilter(m, have_m, ctrl, kp);
  119. cv::GComputation comp(cv::GIn(m, have_m, ctrl), cv::GOut(out));
  120. cv::RNG& rng = cv::theRNG();
  121. bool haveMeasure;
  122. for (int i = 0; i < numIter; i++)
  123. {
  124. haveMeasure = (rng(2u) == 1); // returns 0 or 1 - whether we have measurement at this iteration or not
  125. if (haveMeasure)
  126. cv::randu(measure_vec, Scalar::all(-1), Scalar::all(1));
  127. if (cDim > 0)
  128. cv::randu(ctrl_vec, Scalar::all(-1), Scalar::all(1));
  129. // G-API KalmanFilter call
  130. comp.apply(cv::gin(measure_vec, haveMeasure, ctrl_vec), cv::gout(gapiKState));
  131. // OpenCV KalmanFilter call
  132. ocvKState = cDim > 0 ? ocvKalman.predict(ctrl_vec) : ocvKalman.predict();
  133. if (haveMeasure)
  134. ocvKState = ocvKalman.correct(measure_vec);
  135. }
  136. // Comparison //////////////////////////////////////////////////////////////
  137. {
  138. EXPECT_TRUE(AbsExact().to_compare_f()(gapiKState, ocvKState));
  139. }
  140. }
  141. TEST_P(KalmanFilterNoControlTest, AccuracyTest)
  142. {
  143. cv::gapi::KalmanParams kp;
  144. initKalmanParams(type, dDim, mDim, 0, kp);
  145. // OpenCV reference KalmanFilter initialization
  146. cv::KalmanFilter ocvKalman(dDim, mDim, 0, type);
  147. initKalmanFilter(kp, false, ocvKalman);
  148. // measurement vector
  149. cv::Mat measure_vec(mDim, 1, type);
  150. // G-API Kalman's output state
  151. cv::Mat gapiKState(dDim, 1, type);
  152. // OCV Kalman's output state
  153. cv::Mat ocvKState(dDim, 1, type);
  154. // G-API graph initialization
  155. cv::GMat m;
  156. cv::GOpaque<bool> have_m;
  157. cv::GMat out = cv::gapi::KalmanFilter(m, have_m, kp);
  158. cv::GComputation comp(cv::GIn(m, have_m), cv::GOut(out));
  159. cv::RNG& rng = cv::theRNG();
  160. bool haveMeasure;
  161. for (int i = 0; i < numIter; i++)
  162. {
  163. haveMeasure = (rng(2u) == 1); // returns 0 or 1 - whether we have measurement at this iteration or not
  164. if (haveMeasure)
  165. cv::randu(measure_vec, Scalar::all(-1), Scalar::all(1));
  166. // G-API
  167. comp.apply(cv::gin(measure_vec, haveMeasure), cv::gout(gapiKState));
  168. // OpenCV
  169. ocvKState = ocvKalman.predict();
  170. if (haveMeasure)
  171. ocvKState = ocvKalman.correct(measure_vec);
  172. }
  173. // Comparison //////////////////////////////////////////////////////////////
  174. {
  175. EXPECT_TRUE(AbsExact().to_compare_f()(gapiKState, ocvKState));
  176. }
  177. }
  178. TEST_P(KalmanFilterCircleSampleTest, AccuracyTest)
  179. {
  180. // auxiliary variables
  181. cv::Mat processNoise(2, 1, type);
  182. // Input measurement
  183. cv::Mat measurement = Mat::zeros(1, 1, type);
  184. // Angle and it's delta(phi, delta_phi)
  185. cv::Mat state(2, 1, type);
  186. // G-API graph initialization
  187. cv::gapi::KalmanParams kp;
  188. kp.state = Mat::zeros(2, 1, type);
  189. cv::randn(kp.state, Scalar::all(0), Scalar::all(0.1));
  190. kp.errorCov = Mat::eye(2, 2, type);
  191. if (type == CV_32F)
  192. kp.transitionMatrix = (Mat_<float>(2, 2) << 1, 1, 0, 1);
  193. else
  194. kp.transitionMatrix = (Mat_<double>(2, 2) << 1, 1, 0, 1);
  195. kp.processNoiseCov = Mat::eye(2, 2, type) * (1e-5);
  196. kp.measurementMatrix = Mat::eye(1, 2, type);
  197. kp.measurementNoiseCov = Mat::eye(1, 1, type) * (1e-1);
  198. cv::GMat m;
  199. cv::GOpaque<bool> have_measure;
  200. cv::GMat out = cv::gapi::KalmanFilter(m, have_measure, kp);
  201. cv::GComputation comp(cv::GIn(m, have_measure), cv::GOut(out));
  202. // OCV Kalman initialization
  203. cv::KalmanFilter KF(2, 1, 0);
  204. initKalmanFilter(kp, false, KF);
  205. cv::randn(state, Scalar::all(0), Scalar::all(0.1));
  206. // GAPI Corrected state
  207. cv::Mat gapiState(2, 1, type);
  208. // OCV Corrected state
  209. cv::Mat ocvCorrState(2, 1, type);
  210. // OCV Predicted state
  211. cv::Mat ocvPreState(2, 1, type);
  212. bool haveMeasure;
  213. for (int i = 0; i < numIter; ++i)
  214. {
  215. // Get OCV Prediction
  216. ocvPreState = KF.predict();
  217. GAPI_DbgAssert(cv::norm(kp.measurementNoiseCov, KF.measurementNoiseCov, cv::NORM_INF) == 0);
  218. // generation measurement
  219. cv::randn(measurement, Scalar::all(0), Scalar::all((type == CV_32FC1) ?
  220. kp.measurementNoiseCov.at<float>(0) : kp.measurementNoiseCov.at<double>(0)));
  221. GAPI_DbgAssert(cv::norm(kp.measurementMatrix, KF.measurementMatrix, cv::NORM_INF) == 0);
  222. measurement += kp.measurementMatrix*state;
  223. if (cv::theRNG().uniform(0, 4) != 0)
  224. {
  225. haveMeasure = true;
  226. ocvCorrState = KF.correct(measurement);
  227. comp.apply(cv::gin(measurement, haveMeasure), cv::gout(gapiState));
  228. EXPECT_TRUE(AbsExact().to_compare_f()(gapiState, ocvCorrState));
  229. }
  230. else
  231. {
  232. // Get GAPI Prediction
  233. haveMeasure = false;
  234. comp.apply(cv::gin(measurement, haveMeasure), cv::gout(gapiState));
  235. EXPECT_TRUE(AbsExact().to_compare_f()(gapiState, ocvPreState));
  236. }
  237. GAPI_DbgAssert(cv::norm(kp.processNoiseCov, KF.processNoiseCov, cv::NORM_INF) == 0);
  238. cv::randn(processNoise, Scalar(0), Scalar::all(sqrt(type == CV_32FC1 ?
  239. kp.processNoiseCov.at<float>(0, 0):
  240. kp.processNoiseCov.at<double>(0, 0))));
  241. GAPI_DbgAssert(cv::norm(kp.transitionMatrix, KF.transitionMatrix, cv::NORM_INF) == 0);
  242. state = kp.transitionMatrix*state + processNoise;
  243. }
  244. }
  245. #endif
  246. } // opencv_test
  247. #endif // OPENCV_GAPI_VIDEO_TESTS_INL_HPP