gapi: Full calcOpticalFlowPyrLK implementation (2 overloads) and tests
authorOrestChura <orest.chura@intel.com>
Wed, 8 Apr 2020 14:05:43 +0000 (17:05 +0300)
committerOrestChura <orest.chura@intel.com>
Wed, 8 Apr 2020 15:11:55 +0000 (18:11 +0300)
     - opencv_gapi module is linked with opencv_video module (optional dependency)
     - kernels added to a new cv::gapi::video namespace and a brand new files created to provide gapi_video environment
     - there are 2 different kernels as G-API should provide GMat AND GArray<GMat> implementation: cv::calcOptFlowPyrLK doesn't calculate pyramids if vector<Mat> is given so just the cast GMat -> GArray<GMat> wouldn't represent all the cv:: functionality
     - tests to check both kernels (based on cv::video tests for cv::calcOpticalFlowPyrLK())
     - tests for internal purposes added
     - vectors<T> comparison in tests implemented
     - new (and old too) common test structures refactored to avoid code copypasting
     - "modules/gapi/test/common/gapi_video_tests_common.hpp" created to share some code snippets between perf and acc tests and avoid code copypasting

22 files changed:
modules/gapi/CMakeLists.txt
modules/gapi/include/opencv2/gapi/cpu/video.hpp [new file with mode: 0644]
modules/gapi/include/opencv2/gapi/imgproc.hpp
modules/gapi/include/opencv2/gapi/video.hpp [new file with mode: 0644]
modules/gapi/perf/common/gapi_imgproc_perf_tests.hpp
modules/gapi/perf/common/gapi_video_perf_tests.cpp [new file with mode: 0644]
modules/gapi/perf/common/gapi_video_perf_tests.hpp [new file with mode: 0644]
modules/gapi/perf/common/gapi_video_perf_tests_inl.hpp [new file with mode: 0644]
modules/gapi/perf/cpu/gapi_imgproc_perf_tests_cpu.cpp
modules/gapi/perf/cpu/gapi_video_perf_tests_cpu.cpp [new file with mode: 0644]
modules/gapi/perf/perf_precomp.hpp
modules/gapi/src/api/kernels_video.cpp [new file with mode: 0644]
modules/gapi/src/backends/cpu/gcpuvideo.cpp [new file with mode: 0644]
modules/gapi/src/compiler/gcompiler.cpp
modules/gapi/test/common/gapi_imgproc_tests_inl.hpp
modules/gapi/test/common/gapi_tests_common.hpp
modules/gapi/test/common/gapi_video_tests.cpp [new file with mode: 0644]
modules/gapi/test/common/gapi_video_tests.hpp [new file with mode: 0644]
modules/gapi/test/common/gapi_video_tests_common.hpp [new file with mode: 0644]
modules/gapi/test/common/gapi_video_tests_inl.hpp [new file with mode: 0644]
modules/gapi/test/cpu/gapi_video_tests_cpu.cpp [new file with mode: 0644]
modules/gapi/test/test_precomp.hpp

index 519ebba..ff3cb0a 100644 (file)
@@ -15,7 +15,12 @@ endif()
 
 set(the_description "OpenCV G-API Core Module")
 
-ocv_add_module(gapi opencv_imgproc)
+ocv_add_module(gapi
+    REQUIRED
+      opencv_imgproc
+    OPTIONAL
+      opencv_video
+)
 
 if(MSVC)
   # Disable obsollete warning C4503 popping up on MSVC <<2017
@@ -55,6 +60,7 @@ set(gapi_srcs
     src/api/operators.cpp
     src/api/kernels_core.cpp
     src/api/kernels_imgproc.cpp
+    src/api/kernels_video.cpp
     src/api/render.cpp
     src/api/render_ocv.cpp
     src/api/ginfer.cpp
@@ -87,6 +93,7 @@ set(gapi_srcs
     src/backends/cpu/gcpubackend.cpp
     src/backends/cpu/gcpukernel.cpp
     src/backends/cpu/gcpuimgproc.cpp
+    src/backends/cpu/gcpuvideo.cpp
     src/backends/cpu/gcpucore.cpp
 
     # Fluid Backend (also built-in, FIXME:move away)
diff --git a/modules/gapi/include/opencv2/gapi/cpu/video.hpp b/modules/gapi/include/opencv2/gapi/cpu/video.hpp
new file mode 100644 (file)
index 0000000..d3c1f2e
--- /dev/null
@@ -0,0 +1,25 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#ifndef OPENCV_GAPI_CPU_VIDEO_API_HPP
+#define OPENCV_GAPI_CPU_VIDEO_API_HPP
+
+#include <opencv2/gapi/gkernel.hpp> // GKernelPackage
+
+namespace cv {
+namespace gapi {
+namespace video {
+namespace cpu {
+
+GAPI_EXPORTS GKernelPackage kernels();
+
+} // namespace cpu
+} // namespace video
+} // namespace gapi
+} // namespace cv
+
+
+#endif // OPENCV_GAPI_CPU_VIDEO_API_HPP
index 1485398..4faf5e1 100644 (file)
@@ -261,7 +261,6 @@ namespace imgproc {
 
 } //namespace imgproc
 
-
 //! @addtogroup gapi_filters
 //! @{
 /** @brief Applies a separable linear filter to a matrix(image).
diff --git a/modules/gapi/include/opencv2/gapi/video.hpp b/modules/gapi/include/opencv2/gapi/video.hpp
new file mode 100644 (file)
index 0000000..7602e1d
--- /dev/null
@@ -0,0 +1,135 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#ifndef OPENCV_GAPI_VIDEO_HPP
+#define OPENCV_GAPI_VIDEO_HPP
+
+#include <utility> // std::tuple
+
+#include <opencv2/gapi/gkernel.hpp>
+
+
+/** \defgroup gapi_video G-API Video processing functionality
+ */
+
+namespace cv { namespace gapi {
+namespace  video
+{
+    using GOptFlowLKOutput = std::tuple<cv::GArray<cv::Point2f>,
+                                        cv::GArray<uchar>,
+                                        cv::GArray<float>>;
+
+    G_TYPED_KERNEL(GCalcOptFlowLK,
+                   <GOptFlowLKOutput(GMat,GMat,cv::GArray<cv::Point2f>,cv::GArray<cv::Point2f>,Size,
+                                     int,TermCriteria,int,double)>,
+                   "org.opencv.video.calcOpticalFlowPyrLK")
+    {
+        static std::tuple<GArrayDesc,GArrayDesc,GArrayDesc> outMeta(GMatDesc,GMatDesc,GArrayDesc,
+                                                                    GArrayDesc,const Size&,int,
+                                                                    const TermCriteria&,int,double)
+        {
+            return std::make_tuple(empty_array_desc(), empty_array_desc(), empty_array_desc());
+        }
+
+    };
+
+    G_TYPED_KERNEL(GCalcOptFlowLKForPyr,
+                   <GOptFlowLKOutput(cv::GArray<cv::GMat>,cv::GArray<cv::GMat>,
+                                     cv::GArray<cv::Point2f>,cv::GArray<cv::Point2f>,Size,int,
+                                     TermCriteria,int,double)>,
+                   "org.opencv.video.calcOpticalFlowPyrLKForPyr")
+    {
+        static std::tuple<GArrayDesc,GArrayDesc,GArrayDesc> outMeta(GArrayDesc,GArrayDesc,
+                                                                    GArrayDesc,GArrayDesc,
+                                                                    const Size&,int,
+                                                                    const TermCriteria&,int,double)
+        {
+            return std::make_tuple(empty_array_desc(), empty_array_desc(), empty_array_desc());
+        }
+    };
+} //namespace video
+
+//! @addtogroup gapi_video
+//! @{
+/** @brief Calculates an optical flow for a sparse feature set using the iterative Lucas-Kanade
+method with pyramids.
+
+See @cite Bouguet00 .
+
+@note Function textual ID is "org.opencv.video.calcOpticalFlowPyrLK"
+
+@param prevImg first 8-bit input image (GMat) or pyramid (GArray<GMat>) constructed by
+buildOpticalFlowPyramid.
+@param nextImg second input image (GMat) or pyramid (GArray<GMat>) of the same size and the same
+type as prevImg.
+@param prevPts GArray of 2D points for which the flow needs to be found; point coordinates must be
+single-precision floating-point numbers.
+@param predPts GArray of 2D points initial for the flow search; make sense only when
+OPTFLOW_USE_INITIAL_FLOW flag is passed; in that case the vector must have the same size as in
+the input.
+@param winSize size of the search window at each pyramid level.
+@param maxLevel 0-based maximal pyramid level number; if set to 0, pyramids are not used (single
+level), if set to 1, two levels are used, and so on; if pyramids are passed to input then
+algorithm will use as many levels as pyramids have but no more than maxLevel.
+@param criteria parameter, specifying the termination criteria of the iterative search algorithm
+(after the specified maximum number of iterations criteria.maxCount or when the search window
+moves by less than criteria.epsilon).
+@param flags operation flags:
+ -   **OPTFLOW_USE_INITIAL_FLOW** uses initial estimations, stored in nextPts; if the flag is
+     not set, then prevPts is copied to nextPts and is considered the initial estimate.
+ -   **OPTFLOW_LK_GET_MIN_EIGENVALS** use minimum eigen values as an error measure (see
+     minEigThreshold description); if the flag is not set, then L1 distance between patches
+     around the original and a moved point, divided by number of pixels in a window, is used as a
+     error measure.
+@param minEigThresh the algorithm calculates the minimum eigen value of a 2x2 normal matrix of
+optical flow equations (this matrix is called a spatial gradient matrix in @cite Bouguet00), divided
+by number of pixels in a window; if this value is less than minEigThreshold, then a corresponding
+feature is filtered out and its flow is not processed, so it allows to remove bad points and get a
+performance boost.
+
+@return GArray of 2D points (with single-precision floating-point coordinates)
+containing the calculated new positions of input features in the second image.
+@return status GArray (of unsigned chars); each element of the vector is set to 1 if
+the flow for the corresponding features has been found, otherwise, it is set to 0.
+@return GArray of errors (doubles); each element of the vector is set to an error for the
+corresponding feature, type of the error measure can be set in flags parameter; if the flow wasn't
+found then the error is not defined (use the status parameter to find such cases).
+ */
+GAPI_EXPORTS std::tuple<GArray<Point2f>, GArray<uchar>, GArray<float>>
+calcOpticalFlowPyrLK(const GMat            &prevImg,
+                     const GMat            &nextImg,
+                     const GArray<Point2f> &prevPts,
+                     const GArray<Point2f> &predPts,
+                     const Size            &winSize      = Size(21, 21),
+                           int              maxLevel     = 3,
+                     const TermCriteria    &criteria     = TermCriteria(TermCriteria::COUNT |
+                                                                        TermCriteria::EPS,
+                                                                        30, 0.01),
+                           int              flags        = 0,
+                           double           minEigThresh = 1e-4);
+
+/**
+@overload
+@note Function textual ID is "org.opencv.video.calcOpticalFlowPyrLKForPyr"
+*/
+GAPI_EXPORTS std::tuple<GArray<Point2f>, GArray<uchar>, GArray<float>>
+calcOpticalFlowPyrLK(const GArray<GMat>    &prevPyr,
+                     const GArray<GMat>    &nextPyr,
+                     const GArray<Point2f> &prevPts,
+                     const GArray<Point2f> &predPts,
+                     const Size            &winSize      = Size(21, 21),
+                           int              maxLevel     = 3,
+                     const TermCriteria    &criteria     = TermCriteria(TermCriteria::COUNT |
+                                                                        TermCriteria::EPS,
+                                                                        30, 0.01),
+                           int              flags        = 0,
+                           double           minEigThresh = 1e-4);
+
+//! @} gapi_video
+} //namespace gapi
+} //namespace cv
+
+#endif // OPENCV_GAPI_VIDEO_HPP
index 9d3433d..659fc53 100644 (file)
@@ -49,5 +49,6 @@ class YUV2BGRPerfTest : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCo
 class RGB2HSVPerfTest : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCompileArgs>> {};
 class BayerGR2RGBPerfTest : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCompileArgs>> {};
 class RGB2YUV422PerfTest  : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCompileArgs>> {};
-}
+} // opencv_test
+
 #endif //OPENCV_GAPI_IMGPROC_PERF_TESTS_HPP
diff --git a/modules/gapi/perf/common/gapi_video_perf_tests.cpp b/modules/gapi/perf/common/gapi_video_perf_tests.cpp
new file mode 100644 (file)
index 0000000..efa1765
--- /dev/null
@@ -0,0 +1,9 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+
+#include "../perf_precomp.hpp"
+#include "gapi_video_perf_tests_inl.hpp"
diff --git a/modules/gapi/perf/common/gapi_video_perf_tests.hpp b/modules/gapi/perf/common/gapi_video_perf_tests.hpp
new file mode 100644 (file)
index 0000000..240014c
--- /dev/null
@@ -0,0 +1,26 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#ifndef OPENCV_GAPI_VIDEO_PERF_TESTS_HPP
+#define OPENCV_GAPI_VIDEO_PERF_TESTS_HPP
+
+#include "../../test/common/gapi_video_tests_common.hpp"
+
+namespace opencv_test
+{
+
+using namespace perf;
+
+//------------------------------------------------------------------------------
+
+class OptFlowLKPerfTest : public TestPerfParams<tuple<std::string,int,tuple<int,int>,int,
+                                                      cv::TermCriteria,cv::GCompileArgs>> {};
+class OptFlowLKForPyrPerfTest : public TestPerfParams<tuple<std::string,int,tuple<int,int>,int,
+                                                            cv::TermCriteria,bool,
+                                                            cv::GCompileArgs>> {};
+} // opencv_test
+
+#endif // OPENCV_GAPI_VIDEO_PERF_TESTS_HPP
diff --git a/modules/gapi/perf/common/gapi_video_perf_tests_inl.hpp b/modules/gapi/perf/common/gapi_video_perf_tests_inl.hpp
new file mode 100644 (file)
index 0000000..1095322
--- /dev/null
@@ -0,0 +1,90 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#ifndef OPENCV_GAPI_VIDEO_PERF_TESTS_INL_HPP
+#define OPENCV_GAPI_VIDEO_PERF_TESTS_INL_HPP
+
+#include <iostream>
+
+#include "gapi_video_perf_tests.hpp"
+
+namespace opencv_test
+{
+
+  using namespace perf;
+
+//------------------------------------------------------------------------------
+
+PERF_TEST_P_(OptFlowLKPerfTest, TestPerformance)
+{
+    std::vector<cv::Point2f> outPtsOCV,    outPtsGAPI,    inPts;
+    std::vector<uchar>       outStatusOCV, outStatusGAPI;
+    std::vector<float>       outErrOCV,    outErrGAPI;
+
+    OptFlowLKTestParams params;
+    std::tie(params.fileNamePattern, params.channels,
+             params.pointsNum, params.winSize, params.criteria,
+             params.compileArgs) = GetParam();
+
+    OptFlowLKTestOutput outOCV  { outPtsOCV,  outStatusOCV,  outErrOCV };
+    OptFlowLKTestOutput outGAPI { outPtsGAPI, outStatusGAPI, outErrGAPI };
+
+    cv::GComputation c = runOCVnGAPIOptFlowLK(*this, inPts, params, outOCV, outGAPI);
+
+    declare.in(in_mat1, in_mat2, inPts).out(outPtsGAPI, outStatusGAPI, outErrGAPI);
+
+    TEST_CYCLE()
+    {
+        c.apply(cv::gin(in_mat1, in_mat2, inPts, std::vector<cv::Point2f>{ }),
+                cv::gout(outPtsGAPI, outStatusGAPI, outErrGAPI));
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    compareOutputsOptFlow(outOCV, outGAPI);
+
+    SANITY_CHECK_NOTHING();
+}
+
+//------------------------------------------------------------------------------
+
+PERF_TEST_P_(OptFlowLKForPyrPerfTest, TestPerformance)
+{
+    std::vector<cv::Mat>     inPyr1, inPyr2;
+    std::vector<cv::Point2f> outPtsOCV,    outPtsGAPI,    inPts;
+    std::vector<uchar>       outStatusOCV, outStatusGAPI;
+    std::vector<float>       outErrOCV,    outErrGAPI;
+
+    bool withDeriv = false;
+    OptFlowLKTestParams params;
+    std::tie(params.fileNamePattern, params.channels,
+             params.pointsNum, params.winSize, params.criteria,
+             withDeriv, params.compileArgs) = GetParam();
+
+    OptFlowLKTestInput<std::vector<cv::Mat>> in { inPyr1, inPyr2, inPts };
+    OptFlowLKTestOutput outOCV  { outPtsOCV,  outStatusOCV,  outErrOCV };
+    OptFlowLKTestOutput outGAPI { outPtsGAPI, outStatusGAPI, outErrGAPI };
+
+    cv::GComputation c = runOCVnGAPIOptFlowLKForPyr(*this, in, params, withDeriv, outOCV, outGAPI);
+
+    declare.in(inPyr1, inPyr2, inPts).out(outPtsGAPI, outStatusGAPI, outErrGAPI);
+
+    TEST_CYCLE()
+    {
+        c.apply(cv::gin(inPyr1, inPyr2, inPts, std::vector<cv::Point2f>{ }),
+                cv::gout(outPtsGAPI, outStatusGAPI, outErrGAPI));
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    compareOutputsOptFlow(outOCV, outGAPI);
+
+    SANITY_CHECK_NOTHING();
+}
+
+//------------------------------------------------------------------------------
+
+} // opencv_test
+
+#endif // OPENCV_GAPI_VIDEO_PERF_TESTS_INL_HPP
index 3f22703..6b2efb7 100644 (file)
@@ -220,4 +220,4 @@ INSTANTIATE_TEST_CASE_P(RGB2YUV422PerfTestCPU, RGB2YUV422PerfTest,
         Combine(Values(ToleranceColor(1e-3).to_compare_f()),
             Values(szVGA, sz720p, sz1080p),
             Values(cv::compile_args(IMGPROC_CPU))));
-}
+} // opencv_test
diff --git a/modules/gapi/perf/cpu/gapi_video_perf_tests_cpu.cpp b/modules/gapi/perf/cpu/gapi_video_perf_tests_cpu.cpp
new file mode 100644 (file)
index 0000000..4b36dac
--- /dev/null
@@ -0,0 +1,64 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+
+#include "../perf_precomp.hpp"
+
+#include "../common/gapi_video_perf_tests.hpp"
+#include <opencv2/gapi/cpu/video.hpp>
+
+namespace
+{
+#define VIDEO_CPU cv::gapi::video::cpu::kernels()
+
+#ifdef HAVE_OPENCV_VIDEO
+#define WITH_VIDEO(X) X
+#else
+#define WITH_VIDEO(X) DISABLED_##X
+#endif // HAVE_OPENCV_VIDEO
+
+#define INSTANTIATE_TEST_CASE_MACRO_P(prefix, test_case_name, generator, ...) \
+    INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, __VA_ARGS__)
+} // namespace
+
+
+namespace opencv_test
+{
+INSTANTIATE_TEST_CASE_MACRO_P(WITH_VIDEO(OptFlowLKPerfTestCPU), OptFlowLKPerfTest,
+                              Combine(Values("cv/optflow/rock_%01d.bmp",
+                                             "cv/optflow/frames/1080p_%02d.png"),
+                                      Values(1, 3, 4),
+                                      Values(std::make_tuple(9, 9), std::make_tuple(15, 15)),
+                                      Values(7, 11),
+                                      Values(cv::TermCriteria(cv::TermCriteria::COUNT |
+                                                              cv::TermCriteria::EPS,
+                                                              30, 0.01)),
+                                      Values(cv::compile_args(VIDEO_CPU))));
+
+INSTANTIATE_TEST_CASE_MACRO_P(WITH_VIDEO(OptFlowLKForPyrPerfTestCPU), OptFlowLKForPyrPerfTest,
+                              Combine(Values("cv/optflow/rock_%01d.bmp",
+                                             "cv/optflow/frames/1080p_%02d.png"),
+                                      Values(1, 3, 4),
+                                      Values(std::make_tuple(9, 9), std::make_tuple(15, 15)),
+                                      Values(7, 11),
+                                      Values(cv::TermCriteria(cv::TermCriteria::COUNT |
+                                                              cv::TermCriteria::EPS,
+                                                              30, 0.01)),
+                                      Values(true, false),
+                                      Values(cv::compile_args(VIDEO_CPU))));
+
+INSTANTIATE_TEST_CASE_MACRO_P(WITH_VIDEO(OptFlowLKInternalPerfTestCPU),
+                              OptFlowLKForPyrPerfTest,
+                              Combine(Values("cv/optflow/rock_%01d.bmp"),
+                                      Values(1),
+                                      Values(std::make_tuple(10, 10)),
+                                      Values(15),
+                                      Values(cv::TermCriteria(cv::TermCriteria::COUNT |
+                                                              cv::TermCriteria::EPS,
+                                                              21, 0.05)),
+                                      Values(true),
+                                      Values(cv::compile_args(VIDEO_CPU))));
+} // opencv_test
index bf19532..44b9dc7 100644 (file)
@@ -2,7 +2,7 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef __OPENCV_GAPI_PERF_PRECOMP_HPP__
@@ -14,6 +14,7 @@
 #include <opencv2/ts.hpp>
 #include <opencv2/gapi.hpp>
 #include <opencv2/gapi/imgproc.hpp>
+#include <opencv2/gapi/video.hpp>
 #include <opencv2/gapi/core.hpp>
 #include <opencv2/gapi/cpu/gcpukernel.hpp>
 #include <opencv2/gapi/gpu/ggpukernel.hpp>
diff --git a/modules/gapi/src/api/kernels_video.cpp b/modules/gapi/src/api/kernels_video.cpp
new file mode 100644 (file)
index 0000000..68e9cdf
--- /dev/null
@@ -0,0 +1,45 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+
+#include "precomp.hpp"
+
+#include <opencv2/gapi/video.hpp>
+
+namespace cv { namespace gapi {
+using namespace video;
+
+
+GOptFlowLKOutput calcOpticalFlowPyrLK(const GMat                    &prevImg,
+                                      const GMat                    &nextImg,
+                                      const cv::GArray<cv::Point2f> &prevPts,
+                                      const cv::GArray<cv::Point2f> &predPts,
+                                      const Size                    &winSize,
+                                            int                      maxLevel,
+                                      const TermCriteria            &criteria,
+                                            int                      flags,
+                                            double                   minEigThresh)
+{
+    return GCalcOptFlowLK::on(prevImg, nextImg, prevPts, predPts, winSize, maxLevel,
+                              criteria, flags, minEigThresh);
+}
+
+GOptFlowLKOutput calcOpticalFlowPyrLK(const cv::GArray<cv::GMat>    &prevPyr,
+                                      const cv::GArray<cv::GMat>    &nextPyr,
+                                      const cv::GArray<cv::Point2f> &prevPts,
+                                      const cv::GArray<cv::Point2f> &predPts,
+                                      const Size                    &winSize,
+                                            int                      maxLevel,
+                                      const TermCriteria            &criteria,
+                                            int                      flags,
+                                            double                   minEigThresh)
+{
+    return GCalcOptFlowLKForPyr::on(prevPyr, nextPyr, prevPts, predPts, winSize, maxLevel,
+                                    criteria, flags, minEigThresh);
+}
+
+} //namespace gapi
+} //namespace cv
diff --git a/modules/gapi/src/backends/cpu/gcpuvideo.cpp b/modules/gapi/src/backends/cpu/gcpuvideo.cpp
new file mode 100644 (file)
index 0000000..829e662
--- /dev/null
@@ -0,0 +1,80 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+
+#include "precomp.hpp"
+
+#include <opencv2/gapi/video.hpp>
+#include <opencv2/gapi/cpu/video.hpp>
+#include <opencv2/gapi/cpu/gcpukernel.hpp>
+
+#ifdef HAVE_OPENCV_VIDEO
+#include <opencv2/video.hpp>
+#endif // HAVE_OPENCV_VIDEO
+
+#ifdef HAVE_OPENCV_VIDEO
+
+GAPI_OCV_KERNEL(GCPUCalcOptFlowLK, cv::gapi::video::GCalcOptFlowLK)
+{
+    static void run(const cv::Mat                  &prevImg,
+                    const cv::Mat                  &nextImg,
+                    const std::vector<cv::Point2f> &prevPts,
+                    const std::vector<cv::Point2f> &predPts,
+                    const cv::Size                 &winSize,
+                          int                       maxLevel,
+                    const cv::TermCriteria         &criteria,
+                          int                       flags,
+                          double                    minEigThresh,
+                          std::vector<cv::Point2f> &outPts,
+                          std::vector<uchar>       &status,
+                          std::vector<float>       &err)
+    {
+        if (flags & cv::OPTFLOW_USE_INITIAL_FLOW)
+            outPts = predPts;
+        cv::calcOpticalFlowPyrLK(prevImg, nextImg, prevPts, outPts, status, err, winSize, maxLevel,
+                                 criteria, flags, minEigThresh);
+    }
+};
+
+GAPI_OCV_KERNEL(GCPUCalcOptFlowLKForPyr, cv::gapi::video::GCalcOptFlowLKForPyr)
+{
+    static void run(const std::vector<cv::Mat>     &prevPyr,
+                    const std::vector<cv::Mat>     &nextPyr,
+                    const std::vector<cv::Point2f> &prevPts,
+                    const std::vector<cv::Point2f> &predPts,
+                    const cv::Size                 &winSize,
+                          int                       maxLevel,
+                    const cv::TermCriteria         &criteria,
+                          int                       flags,
+                          double                    minEigThresh,
+                          std::vector<cv::Point2f> &outPts,
+                          std::vector<uchar>       &status,
+                          std::vector<float>       &err)
+    {
+        if (flags & cv::OPTFLOW_USE_INITIAL_FLOW)
+            outPts = predPts;
+        cv::calcOpticalFlowPyrLK(prevPyr, nextPyr, prevPts, outPts, status, err, winSize, maxLevel,
+                                 criteria, flags, minEigThresh);
+    }
+};
+
+cv::gapi::GKernelPackage cv::gapi::video::cpu::kernels()
+{
+    static auto pkg = cv::gapi::kernels
+        < GCPUCalcOptFlowLK
+        , GCPUCalcOptFlowLKForPyr
+        >();
+    return pkg;
+}
+
+#else
+
+cv::gapi::GKernelPackage cv::gapi::video::cpu::kernels()
+{
+    return GKernelPackage();
+}
+
+#endif // HAVE_OPENCV_VIDEO
index 92db768..5262acd 100644 (file)
@@ -2,7 +2,7 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #include "precomp.hpp"
@@ -38,8 +38,9 @@
 
 // <FIXME:>
 #if !defined(GAPI_STANDALONE)
-#include <opencv2/gapi/cpu/core.hpp>    // Also directly refer to Core
-#include <opencv2/gapi/cpu/imgproc.hpp> // ...and Imgproc kernel implementations
+#include <opencv2/gapi/cpu/core.hpp>    // Also directly refer to Core,
+#include <opencv2/gapi/cpu/imgproc.hpp> // ...Imgproc
+#include <opencv2/gapi/cpu/video.hpp>   // ...and Video kernel implementations
 #include <opencv2/gapi/render/render.hpp>   // render::ocv::backend()
 #endif // !defined(GAPI_STANDALONE)
 // </FIXME:>
@@ -66,9 +67,9 @@ namespace
 
         static auto ocv_pkg =
 #if !defined(GAPI_STANDALONE)
-            // FIXME add N-arg version combine
-            combine(combine(cv::gapi::core::cpu::kernels(),
-                    cv::gapi::imgproc::cpu::kernels()),
+            combine(cv::gapi::core::cpu::kernels(),
+                    cv::gapi::imgproc::cpu::kernels(),
+                    cv::gapi::video::cpu::kernels(),
                     cv::gapi::render::ocv::kernels());
 #else
             cv::gapi::GKernelPackage();
index ecc7195..a7aca78 100644 (file)
@@ -784,7 +784,6 @@ TEST_P(RGB2YUV422Test, AccuracyTest)
         EXPECT_EQ(out_mat_gapi.size(), sz);
     }
 }
-
 } // opencv_test
 
 #endif //OPENCV_GAPI_IMGPROC_TESTS_INL_HPP
index 938a7f7..a21cae4 100644 (file)
@@ -196,25 +196,32 @@ public:
         }
     }
 
+    void initMatsFromImages(int channels, const std::string& pattern, int imgNum)
+    {
+        initTestDataPath();
+        GAPI_Assert(channels == 1 || channels == 3 || channels == 4);
+        const int flags = (channels == 1) ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR;
+
+        cv::Mat m1 = cv::imread(findDataFile(cv::format(pattern.c_str(), imgNum)), flags);
+        cv::Mat m2 = cv::imread(findDataFile(cv::format(pattern.c_str(), imgNum + 1)), flags);
+        if (channels == 4)
+        {
+            cvtColor(m1, in_mat1, cv::COLOR_BGR2BGRA);
+            cvtColor(m2, in_mat2, cv::COLOR_BGR2BGRA);
+        }
+        else
+        {
+            std::tie(in_mat1, in_mat2) = std::make_tuple(m1, m2);
+        }
+    }
+
     // empty function intended to show that nothing is to be initialized via TestFunctional methods
     void initNothing(int, cv::Size, int, bool = true) {}
 };
 
 template<class T>
-class TestParams: public TestFunctional, public TestWithParam<T>{};
-
-template<class T>
 class TestPerfParams: public TestFunctional, public perf::TestBaseWithParam<T>{};
 
-using compare_f = std::function<bool(const cv::Mat &a, const cv::Mat &b)>;
-
-using compare_scalar_f = std::function<bool(const cv::Scalar &a, const cv::Scalar &b)>;
-
-template<typename Elem>
-using compare_vector_f = std::function<bool(const std::vector<Elem> &a,
-                                            const std::vector<Elem> &b)>;
-
-
 // FIXME: re-use MatType. current problem: "special values" interpreted incorrectly (-1 is printed
 //        as 16FC512)
 struct MatType2
@@ -368,6 +375,14 @@ struct TestWithParamsSpecific : public TestWithParamsBase<ParamsSpecific<Specifi
 // Example: FIXTURE_API(int, bool) expands to <int, bool>
 #define FIXTURE_API(...) <__VA_ARGS__>
 
+
+using compare_f = std::function<bool(const cv::Mat &a, const cv::Mat &b)>;
+using compare_scalar_f = std::function<bool(const cv::Scalar &a, const cv::Scalar &b)>;
+
+template<typename Elem>
+using compare_vector_f = std::function<bool(const std::vector<Elem> &a,
+                                            const std::vector<Elem> &b)>;
+
 template<typename T1, typename T2>
 struct CompareF
 {
diff --git a/modules/gapi/test/common/gapi_video_tests.cpp b/modules/gapi/test/common/gapi_video_tests.cpp
new file mode 100644 (file)
index 0000000..3501b05
--- /dev/null
@@ -0,0 +1,9 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+
+#include "../test_precomp.hpp"
+#include "gapi_video_tests_inl.hpp"
diff --git a/modules/gapi/test/common/gapi_video_tests.hpp b/modules/gapi/test/common/gapi_video_tests.hpp
new file mode 100644 (file)
index 0000000..c5dafac
--- /dev/null
@@ -0,0 +1,24 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#ifndef OPENCV_GAPI_VIDEO_TESTS_HPP
+#define OPENCV_GAPI_VIDEO_TESTS_HPP
+
+#include "gapi_video_tests_common.hpp"
+
+namespace opencv_test
+{
+GAPI_TEST_FIXTURE_SPEC_PARAMS(OptFlowLKTest, FIXTURE_API(std::string,int,tuple<int,int>,int,
+                                                         cv::TermCriteria),
+                              5, fileNamePattern, channels, pointsNum, winSize, criteria)
+
+GAPI_TEST_FIXTURE_SPEC_PARAMS(OptFlowLKTestForPyr, FIXTURE_API(std::string,int,tuple<int,int>,int,
+                                                               cv::TermCriteria,bool),
+                              6, fileNamePattern, channels, pointsNum, winSize, criteria,withDeriv)
+} // opencv_test
+
+
+#endif // OPENCV_GAPI_VIDEO_TESTS_HPP
diff --git a/modules/gapi/test/common/gapi_video_tests_common.hpp b/modules/gapi/test/common/gapi_video_tests_common.hpp
new file mode 100644 (file)
index 0000000..c056d50
--- /dev/null
@@ -0,0 +1,249 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#ifndef OPENCV_GAPI_VIDEO_TESTS_COMMON_HPP
+#define OPENCV_GAPI_VIDEO_TESTS_COMMON_HPP
+
+#include "gapi_tests_common.hpp"
+#include "../../include/opencv2/gapi/video.hpp"
+
+#ifdef HAVE_OPENCV_VIDEO
+#include <opencv2/video.hpp>
+#endif // HAVE_OPENCV_VIDEO
+
+
+
+namespace opencv_test
+{
+namespace
+{
+inline void initTrackingPointsArray(std::vector<cv::Point2f>& points, int width, int height,
+                                    int nPointsX, int nPointsY)
+{
+    if (nPointsX > width || nPointsY > height)
+    {
+        FAIL() << "Specified points number is too big";
+    }
+
+    int stepX = width  / nPointsX;
+    int stepY = height / nPointsY;
+
+
+    points.clear();
+    GAPI_Assert((nPointsX >= 0) && (nPointsY) >= 0);
+    points.reserve(static_cast<size_t>(nPointsX * nPointsY));
+
+    for (int x = stepX / 2; x < width; x += stepX)
+    {
+        for (int y = stepY / 2; y < height; y += stepY)
+        {
+            Point2f pt(static_cast<float>(x), static_cast<float>(y));
+            points.push_back(pt);
+        }
+    }
+}
+
+template<typename Type>
+struct OptFlowLKTestInput
+{
+    Type& prevData;
+    Type& nextData;
+    std::vector<cv::Point2f>& prevPoints;
+};
+
+struct OptFlowLKTestOutput
+{
+    std::vector<cv::Point2f> &nextPoints;
+    std::vector<uchar>       &statuses;
+    std::vector<float>       &errors;
+};
+
+struct OptFlowLKTestParams
+{
+    OptFlowLKTestParams(): fileNamePattern(""), format(1), channels(0), pointsNum{0, 0},
+                           winSize(0), maxLevel(3), minEigThreshold(1e-4), flags(0) { }
+
+    OptFlowLKTestParams(const std::string& namePat, int chans,
+                        const std::tuple<int,int>& ptsNum, int winSz,
+                        const cv::TermCriteria& crit, const cv::GCompileArgs& compArgs,
+                        int flgs = 0, int fmt = 1, int maxLvl = 3, double minEigThresh = 1e-4):
+
+                        fileNamePattern(namePat), format(fmt), channels(chans),
+                        pointsNum(ptsNum), winSize(winSz), maxLevel(maxLvl),
+                        criteria(crit), minEigThreshold(minEigThresh), compileArgs(compArgs),
+                        flags(flgs) { }
+
+    std::string fileNamePattern   = "";
+    int format                    = 1;
+    int channels                  = 0;
+    std::tuple<int,int> pointsNum = std::make_tuple(0, 0);
+    int winSize                   = 0;
+    int maxLevel                  = 3;
+    cv::TermCriteria criteria;
+    double minEigThreshold        = 1e-4;
+    cv::GCompileArgs compileArgs;
+    int flags                     = 0;
+};
+
+#ifdef HAVE_OPENCV_VIDEO
+
+template<typename GType, typename Type>
+cv::GComputation runOCVnGAPIOptFlowLK(OptFlowLKTestInput<Type>& in,
+                                      int width, int height,
+                                      const OptFlowLKTestParams& params,
+                                      OptFlowLKTestOutput& ocvOut,
+                                      OptFlowLKTestOutput& gapiOut)
+{
+
+    int nPointsX = 0, nPointsY = 0;
+    std::tie(nPointsX, nPointsY) = params.pointsNum;
+
+    initTrackingPointsArray(in.prevPoints, width, height, nPointsX, nPointsY);
+
+    cv::Size winSize(params.winSize, params.winSize);
+
+    // OpenCV code /////////////////////////////////////////////////////////////
+    {
+        cv::calcOpticalFlowPyrLK(in.prevData, in.nextData, in.prevPoints,
+                                 ocvOut.nextPoints, ocvOut.statuses, ocvOut.errors,
+                                 winSize, params.maxLevel, params.criteria,
+                                 params.flags, params.minEigThreshold);
+    }
+
+    // G-API code //////////////////////////////////////////////////////////////
+    {
+        GType               inPrev,  inNext;
+        GArray<cv::Point2f> prevPts, predPts, nextPts;
+        GArray<uchar>       statuses;
+        GArray<float>       errors;
+        std::tie(nextPts, statuses, errors) = cv::gapi::calcOpticalFlowPyrLK(
+                                                    inPrev, inNext,
+                                                    prevPts, predPts, winSize,
+                                                    params.maxLevel, params.criteria,
+                                                    params.flags, params.minEigThreshold);
+
+        cv::GComputation c(cv::GIn(inPrev, inNext, prevPts, predPts),
+                           cv::GOut(nextPts, statuses, errors));
+
+        c.apply(cv::gin(in.prevData, in.nextData, in.prevPoints, std::vector<cv::Point2f>{ }),
+                cv::gout(gapiOut.nextPoints, gapiOut.statuses, gapiOut.errors),
+                std::move(const_cast<cv::GCompileArgs&>(params.compileArgs)));
+
+        return c;
+    }
+}
+
+inline cv::GComputation runOCVnGAPIOptFlowLK(TestFunctional& testInst,
+                                             std::vector<cv::Point2f>& inPts,
+                                             const OptFlowLKTestParams& params,
+                                             OptFlowLKTestOutput& ocvOut,
+                                             OptFlowLKTestOutput& gapiOut)
+{
+    testInst.initMatsFromImages(params.channels,
+                                params.fileNamePattern,
+                                params.format);
+
+    OptFlowLKTestInput<cv::Mat> in{ testInst.in_mat1, testInst.in_mat2, inPts };
+
+    return runOCVnGAPIOptFlowLK<cv::GMat>(in,
+                                          testInst.in_mat1.cols,
+                                          testInst.in_mat1.rows,
+                                          params,
+                                          ocvOut,
+                                          gapiOut);
+}
+
+inline cv::GComputation runOCVnGAPIOptFlowLKForPyr(TestFunctional& testInst,
+                                                   OptFlowLKTestInput<std::vector<cv::Mat>>& in,
+                                                   const OptFlowLKTestParams& params,
+                                                   bool withDeriv,
+                                                   OptFlowLKTestOutput& ocvOut,
+                                                   OptFlowLKTestOutput& gapiOut)
+{
+    testInst.initMatsFromImages(params.channels,
+                                params.fileNamePattern,
+                                params.format);
+
+    cv::Size winSize(params.winSize, params.winSize);
+
+    OptFlowLKTestParams updatedParams(params);
+    updatedParams.maxLevel = cv::buildOpticalFlowPyramid(testInst.in_mat1, in.prevData,
+                                                         winSize, params.maxLevel, withDeriv);
+    updatedParams.maxLevel = cv::buildOpticalFlowPyramid(testInst.in_mat2, in.nextData,
+                                                         winSize, params.maxLevel, withDeriv);
+
+
+    return runOCVnGAPIOptFlowLK<cv::GArray<cv::GMat>>(in,
+                                                      testInst.in_mat1.cols,
+                                                      testInst.in_mat1.rows,
+                                                      updatedParams,
+                                                      ocvOut,
+                                                      gapiOut);
+}
+
+#else // !HAVE_OPENCV_VIDEO
+
+inline cv::GComputation runOCVnGAPIOptFlowLK(TestFunctional&,
+                                             std::vector<cv::Point2f>&,
+                                             const OptFlowLKTestParams&,
+                                             OptFlowLKTestOutput&,
+                                             OptFlowLKTestOutput&)
+{
+    GAPI_Assert(0 && "This function shouldn't be called without opencv_video");
+}
+
+inline cv::GComputation runOCVnGAPIOptFlowLKForPyr(TestFunctional&,
+                                                   OptFlowLKTestInput<std::vector<cv::Mat>>&,
+                                                   const OptFlowLKTestParams&,
+                                                   bool,
+                                                   OptFlowLKTestOutput&,
+                                                   OptFlowLKTestOutput&)
+{
+    GAPI_Assert(0 && "This function shouldn't be called without opencv_video");
+}
+
+#endif // HAVE_OPENCV_VIDEO
+
+template <typename Elem>
+inline bool compareVectorsAbsExactForOptFlow(std::vector<Elem> outOCV, std::vector<Elem> outGAPI)
+{
+    return AbsExactVector<Elem>().to_compare_f()(outOCV, outGAPI);
+}
+
+inline void compareOutputsOptFlow(const OptFlowLKTestOutput& outOCV,
+                                  const OptFlowLKTestOutput& outGAPI)
+{
+    EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.nextPoints, outOCV.nextPoints));
+    EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.statuses,   outOCV.statuses));
+    EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.errors,     outOCV.errors));
+}
+
+
+inline std::ostream& operator<<(std::ostream& os, const cv::TermCriteria& criteria)
+{
+    os << "{";
+    switch (criteria.type) {
+    case cv::TermCriteria::COUNT:
+        os << "COUNT; ";
+        break;
+    case cv::TermCriteria::EPS:
+        os << "EPS; ";
+        break;
+    case cv::TermCriteria::COUNT | cv::TermCriteria::EPS:
+        os << "COUNT | EPS; ";
+        break;
+    default:
+        os << "TypeUndifined; ";
+        break;
+    };
+
+    return os << criteria.maxCount << "; " << criteria.epsilon <<"}";
+}
+} // namespace
+} // namespace opencv_test
+
+
+#endif // OPENCV_GAPI_VIDEO_TESTS_COMMON_HPP
diff --git a/modules/gapi/test/common/gapi_video_tests_inl.hpp b/modules/gapi/test/common/gapi_video_tests_inl.hpp
new file mode 100644 (file)
index 0000000..a5059a8
--- /dev/null
@@ -0,0 +1,53 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#ifndef OPENCV_GAPI_VIDEO_TESTS_INL_HPP
+#define OPENCV_GAPI_VIDEO_TESTS_INL_HPP
+
+#include "gapi_video_tests.hpp"
+
+namespace opencv_test
+{
+
+TEST_P(OptFlowLKTest, AccuracyTest)
+{
+    std::vector<cv::Point2f> outPtsOCV,    outPtsGAPI,    inPts;
+    std::vector<uchar>       outStatusOCV, outStatusGAPI;
+    std::vector<float>       outErrOCV,    outErrGAPI;
+
+    OptFlowLKTestParams params { fileNamePattern, channels, pointsNum,
+                                 winSize, criteria, getCompileArgs() };
+
+    OptFlowLKTestOutput outOCV  { outPtsOCV,  outStatusOCV,  outErrOCV };
+    OptFlowLKTestOutput outGAPI { outPtsGAPI, outStatusGAPI, outErrGAPI };
+
+    runOCVnGAPIOptFlowLK(*this, inPts, params, outOCV, outGAPI);
+
+    compareOutputsOptFlow(outOCV, outGAPI);
+}
+
+TEST_P(OptFlowLKTestForPyr, AccuracyTest)
+{
+    std::vector<cv::Mat>     inPyr1, inPyr2;
+    std::vector<cv::Point2f> outPtsOCV,    outPtsGAPI,    inPts;
+    std::vector<uchar>       outStatusOCV, outStatusGAPI;
+    std::vector<float>       outErrOCV,    outErrGAPI;
+
+    OptFlowLKTestParams params { fileNamePattern, channels, pointsNum,
+                                 winSize, criteria, getCompileArgs() };
+
+    OptFlowLKTestInput<std::vector<cv::Mat>> in { inPyr1, inPyr2, inPts };
+    OptFlowLKTestOutput outOCV  { outPtsOCV,  outStatusOCV,  outErrOCV };
+    OptFlowLKTestOutput outGAPI { outPtsGAPI, outStatusGAPI, outErrGAPI };
+
+    runOCVnGAPIOptFlowLKForPyr(*this, in, params, withDeriv, outOCV, outGAPI);
+
+    compareOutputsOptFlow(outOCV, outGAPI);
+}
+
+} // opencv_test
+
+#endif // OPENCV_GAPI_VIDEO_TESTS_INL_HPP
diff --git a/modules/gapi/test/cpu/gapi_video_tests_cpu.cpp b/modules/gapi/test/cpu/gapi_video_tests_cpu.cpp
new file mode 100644 (file)
index 0000000..c3e0f7e
--- /dev/null
@@ -0,0 +1,62 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+
+#include "../test_precomp.hpp"
+
+#include "../common/gapi_video_tests.hpp"
+#include <opencv2/gapi/cpu/video.hpp>
+
+namespace
+{
+#define VIDEO_CPU [] () { return cv::compile_args(cv::gapi::video::cpu::kernels()); }
+
+#ifdef HAVE_OPENCV_VIDEO
+#define WITH_VIDEO(X) X
+#else
+#define WITH_VIDEO(X) DISABLED_##X
+#endif // HAVE_OPENCV_VIDEO
+
+#define INSTANTIATE_TEST_CASE_MACRO_P(prefix, test_case_name, generator, ...) \
+    INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, __VA_ARGS__)
+}  // anonymous namespace
+
+namespace opencv_test
+{
+INSTANTIATE_TEST_CASE_MACRO_P(WITH_VIDEO(OptFlowLKTestCPU), OptFlowLKTest,
+                              Combine(Values(VIDEO_CPU),
+                                      Values("cv/optflow/rock_%01d.bmp",
+                                             "cv/optflow/frames/1080p_%02d.png"),
+                                      Values(1, 3, 4),
+                                      Values(std::make_tuple(9, 9), std::make_tuple(15, 15)),
+                                      Values(7, 11),
+                                      Values(cv::TermCriteria(cv::TermCriteria::COUNT |
+                                                              cv::TermCriteria::EPS,
+                                                              30, 0.01))));
+
+INSTANTIATE_TEST_CASE_MACRO_P(WITH_VIDEO(OptFlowLKTestForPyrCPU), OptFlowLKTestForPyr,
+                              Combine(Values(VIDEO_CPU),
+                                      Values("cv/optflow/rock_%01d.bmp",
+                                             "cv/optflow/frames/1080p_%02d.png"),
+                                      Values(1, 3, 4),
+                                      Values(std::make_tuple(9, 9), std::make_tuple(15, 15)),
+                                      Values(7, 11),
+                                      Values(cv::TermCriteria(cv::TermCriteria::COUNT |
+                                                              cv::TermCriteria::EPS,
+                                                              30, 0.01)),
+                                      testing::Bool()));
+
+INSTANTIATE_TEST_CASE_MACRO_P(WITH_VIDEO(OptFlowLKInternalTestCPU), OptFlowLKTestForPyr,
+                              Combine(Values(VIDEO_CPU),
+                                      Values("cv/optflow/rock_%01d.bmp"),
+                                      Values(1),
+                                      Values(std::make_tuple(10, 10)),
+                                      Values(15),
+                                      Values(cv::TermCriteria(cv::TermCriteria::COUNT |
+                                                              cv::TermCriteria::EPS,
+                                                              21, 0.05)),
+                                      Values(true)));
+} // opencv_test
index 03f0be2..6253acf 100644 (file)
@@ -2,7 +2,7 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 // FIXME: OpenCV header
@@ -16,8 +16,9 @@
 #include <opencv2/ts.hpp>
 
 #include <opencv2/gapi.hpp>
-#include <opencv2/gapi/imgproc.hpp>
 #include <opencv2/gapi/core.hpp>
+#include <opencv2/gapi/imgproc.hpp>
+#include <opencv2/gapi/video.hpp>
 #include <opencv2/gapi/cpu/gcpukernel.hpp>
 #include <opencv2/gapi/gpu/ggpukernel.hpp>
 #include <opencv2/gapi/gpu/imgproc.hpp>