mirror of
https://github.com/opencv/opencv.git
synced 2024-11-28 05:06:29 +08:00
gapi: Full calcOpticalFlowPyrLK implementation (2 overloads) and tests
- 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
This commit is contained in:
parent
acede976e4
commit
d50c21e571
@ -15,7 +15,12 @@ endif()
|
|||||||
|
|
||||||
set(the_description "OpenCV G-API Core Module")
|
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)
|
if(MSVC)
|
||||||
# Disable obsollete warning C4503 popping up on MSVC <<2017
|
# Disable obsollete warning C4503 popping up on MSVC <<2017
|
||||||
@ -55,6 +60,7 @@ set(gapi_srcs
|
|||||||
src/api/operators.cpp
|
src/api/operators.cpp
|
||||||
src/api/kernels_core.cpp
|
src/api/kernels_core.cpp
|
||||||
src/api/kernels_imgproc.cpp
|
src/api/kernels_imgproc.cpp
|
||||||
|
src/api/kernels_video.cpp
|
||||||
src/api/render.cpp
|
src/api/render.cpp
|
||||||
src/api/render_ocv.cpp
|
src/api/render_ocv.cpp
|
||||||
src/api/ginfer.cpp
|
src/api/ginfer.cpp
|
||||||
@ -87,6 +93,7 @@ set(gapi_srcs
|
|||||||
src/backends/cpu/gcpubackend.cpp
|
src/backends/cpu/gcpubackend.cpp
|
||||||
src/backends/cpu/gcpukernel.cpp
|
src/backends/cpu/gcpukernel.cpp
|
||||||
src/backends/cpu/gcpuimgproc.cpp
|
src/backends/cpu/gcpuimgproc.cpp
|
||||||
|
src/backends/cpu/gcpuvideo.cpp
|
||||||
src/backends/cpu/gcpucore.cpp
|
src/backends/cpu/gcpucore.cpp
|
||||||
|
|
||||||
# Fluid Backend (also built-in, FIXME:move away)
|
# Fluid Backend (also built-in, FIXME:move away)
|
||||||
|
25
modules/gapi/include/opencv2/gapi/cpu/video.hpp
Normal file
25
modules/gapi/include/opencv2/gapi/cpu/video.hpp
Normal file
@ -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
|
@ -261,7 +261,6 @@ namespace imgproc {
|
|||||||
|
|
||||||
} //namespace imgproc
|
} //namespace imgproc
|
||||||
|
|
||||||
|
|
||||||
//! @addtogroup gapi_filters
|
//! @addtogroup gapi_filters
|
||||||
//! @{
|
//! @{
|
||||||
/** @brief Applies a separable linear filter to a matrix(image).
|
/** @brief Applies a separable linear filter to a matrix(image).
|
||||||
|
135
modules/gapi/include/opencv2/gapi/video.hpp
Normal file
135
modules/gapi/include/opencv2/gapi/video.hpp
Normal file
@ -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
|
@ -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 RGB2HSVPerfTest : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCompileArgs>> {};
|
||||||
class BayerGR2RGBPerfTest : 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>> {};
|
class RGB2YUV422PerfTest : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCompileArgs>> {};
|
||||||
}
|
} // opencv_test
|
||||||
|
|
||||||
#endif //OPENCV_GAPI_IMGPROC_PERF_TESTS_HPP
|
#endif //OPENCV_GAPI_IMGPROC_PERF_TESTS_HPP
|
||||||
|
9
modules/gapi/perf/common/gapi_video_perf_tests.cpp
Normal file
9
modules/gapi/perf/common/gapi_video_perf_tests.cpp
Normal file
@ -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"
|
26
modules/gapi/perf/common/gapi_video_perf_tests.hpp
Normal file
26
modules/gapi/perf/common/gapi_video_perf_tests.hpp
Normal file
@ -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
|
90
modules/gapi/perf/common/gapi_video_perf_tests_inl.hpp
Normal file
90
modules/gapi/perf/common/gapi_video_perf_tests_inl.hpp
Normal file
@ -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
|
@ -220,4 +220,4 @@ INSTANTIATE_TEST_CASE_P(RGB2YUV422PerfTestCPU, RGB2YUV422PerfTest,
|
|||||||
Combine(Values(ToleranceColor(1e-3).to_compare_f()),
|
Combine(Values(ToleranceColor(1e-3).to_compare_f()),
|
||||||
Values(szVGA, sz720p, sz1080p),
|
Values(szVGA, sz720p, sz1080p),
|
||||||
Values(cv::compile_args(IMGPROC_CPU))));
|
Values(cv::compile_args(IMGPROC_CPU))));
|
||||||
}
|
} // opencv_test
|
||||||
|
64
modules/gapi/perf/cpu/gapi_video_perf_tests_cpu.cpp
Normal file
64
modules/gapi/perf/cpu/gapi_video_perf_tests_cpu.cpp
Normal file
@ -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
|
@ -2,7 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// 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.
|
// 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__
|
#ifndef __OPENCV_GAPI_PERF_PRECOMP_HPP__
|
||||||
@ -14,6 +14,7 @@
|
|||||||
#include <opencv2/ts.hpp>
|
#include <opencv2/ts.hpp>
|
||||||
#include <opencv2/gapi.hpp>
|
#include <opencv2/gapi.hpp>
|
||||||
#include <opencv2/gapi/imgproc.hpp>
|
#include <opencv2/gapi/imgproc.hpp>
|
||||||
|
#include <opencv2/gapi/video.hpp>
|
||||||
#include <opencv2/gapi/core.hpp>
|
#include <opencv2/gapi/core.hpp>
|
||||||
#include <opencv2/gapi/cpu/gcpukernel.hpp>
|
#include <opencv2/gapi/cpu/gcpukernel.hpp>
|
||||||
#include <opencv2/gapi/gpu/ggpukernel.hpp>
|
#include <opencv2/gapi/gpu/ggpukernel.hpp>
|
||||||
|
45
modules/gapi/src/api/kernels_video.cpp
Normal file
45
modules/gapi/src/api/kernels_video.cpp
Normal file
@ -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
|
80
modules/gapi/src/backends/cpu/gcpuvideo.cpp
Normal file
80
modules/gapi/src/backends/cpu/gcpuvideo.cpp
Normal file
@ -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
|
@ -2,7 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// 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.
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2018 Intel Corporation
|
// Copyright (C) 2018-2020 Intel Corporation
|
||||||
|
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
@ -38,8 +38,9 @@
|
|||||||
|
|
||||||
// <FIXME:>
|
// <FIXME:>
|
||||||
#if !defined(GAPI_STANDALONE)
|
#if !defined(GAPI_STANDALONE)
|
||||||
#include <opencv2/gapi/cpu/core.hpp> // Also directly refer to Core
|
#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/imgproc.hpp> // ...Imgproc
|
||||||
|
#include <opencv2/gapi/cpu/video.hpp> // ...and Video kernel implementations
|
||||||
#include <opencv2/gapi/render/render.hpp> // render::ocv::backend()
|
#include <opencv2/gapi/render/render.hpp> // render::ocv::backend()
|
||||||
#endif // !defined(GAPI_STANDALONE)
|
#endif // !defined(GAPI_STANDALONE)
|
||||||
// </FIXME:>
|
// </FIXME:>
|
||||||
@ -66,9 +67,9 @@ namespace
|
|||||||
|
|
||||||
static auto ocv_pkg =
|
static auto ocv_pkg =
|
||||||
#if !defined(GAPI_STANDALONE)
|
#if !defined(GAPI_STANDALONE)
|
||||||
// FIXME add N-arg version combine
|
combine(cv::gapi::core::cpu::kernels(),
|
||||||
combine(combine(cv::gapi::core::cpu::kernels(),
|
cv::gapi::imgproc::cpu::kernels(),
|
||||||
cv::gapi::imgproc::cpu::kernels()),
|
cv::gapi::video::cpu::kernels(),
|
||||||
cv::gapi::render::ocv::kernels());
|
cv::gapi::render::ocv::kernels());
|
||||||
#else
|
#else
|
||||||
cv::gapi::GKernelPackage();
|
cv::gapi::GKernelPackage();
|
||||||
|
@ -784,7 +784,6 @@ TEST_P(RGB2YUV422Test, AccuracyTest)
|
|||||||
EXPECT_EQ(out_mat_gapi.size(), sz);
|
EXPECT_EQ(out_mat_gapi.size(), sz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // opencv_test
|
} // opencv_test
|
||||||
|
|
||||||
#endif //OPENCV_GAPI_IMGPROC_TESTS_INL_HPP
|
#endif //OPENCV_GAPI_IMGPROC_TESTS_INL_HPP
|
||||||
|
@ -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
|
// empty function intended to show that nothing is to be initialized via TestFunctional methods
|
||||||
void initNothing(int, cv::Size, int, bool = true) {}
|
void initNothing(int, cv::Size, int, bool = true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
|
||||||
class TestParams: public TestFunctional, public TestWithParam<T>{};
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class TestPerfParams: public TestFunctional, public perf::TestBaseWithParam<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
|
// FIXME: re-use MatType. current problem: "special values" interpreted incorrectly (-1 is printed
|
||||||
// as 16FC512)
|
// as 16FC512)
|
||||||
struct MatType2
|
struct MatType2
|
||||||
@ -368,6 +375,14 @@ struct TestWithParamsSpecific : public TestWithParamsBase<ParamsSpecific<Specifi
|
|||||||
// Example: FIXTURE_API(int, bool) expands to <int, bool>
|
// Example: FIXTURE_API(int, bool) expands to <int, bool>
|
||||||
#define FIXTURE_API(...) <__VA_ARGS__>
|
#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>
|
template<typename T1, typename T2>
|
||||||
struct CompareF
|
struct CompareF
|
||||||
{
|
{
|
||||||
|
9
modules/gapi/test/common/gapi_video_tests.cpp
Normal file
9
modules/gapi/test/common/gapi_video_tests.cpp
Normal file
@ -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"
|
24
modules/gapi/test/common/gapi_video_tests.hpp
Normal file
24
modules/gapi/test/common/gapi_video_tests.hpp
Normal file
@ -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
|
249
modules/gapi/test/common/gapi_video_tests_common.hpp
Normal file
249
modules/gapi/test/common/gapi_video_tests_common.hpp
Normal file
@ -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
|
53
modules/gapi/test/common/gapi_video_tests_inl.hpp
Normal file
53
modules/gapi/test/common/gapi_video_tests_inl.hpp
Normal file
@ -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
|
62
modules/gapi/test/cpu/gapi_video_tests_cpu.cpp
Normal file
62
modules/gapi/test/cpu/gapi_video_tests_cpu.cpp
Normal file
@ -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
|
@ -2,7 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// 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.
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2018 Intel Corporation
|
// Copyright (C) 2018-2020 Intel Corporation
|
||||||
|
|
||||||
|
|
||||||
// FIXME: OpenCV header
|
// FIXME: OpenCV header
|
||||||
@ -16,8 +16,9 @@
|
|||||||
#include <opencv2/ts.hpp>
|
#include <opencv2/ts.hpp>
|
||||||
|
|
||||||
#include <opencv2/gapi.hpp>
|
#include <opencv2/gapi.hpp>
|
||||||
#include <opencv2/gapi/imgproc.hpp>
|
|
||||||
#include <opencv2/gapi/core.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/cpu/gcpukernel.hpp>
|
||||||
#include <opencv2/gapi/gpu/ggpukernel.hpp>
|
#include <opencv2/gapi/gpu/ggpukernel.hpp>
|
||||||
#include <opencv2/gapi/gpu/imgproc.hpp>
|
#include <opencv2/gapi/gpu/imgproc.hpp>
|
||||||
|
Loading…
Reference in New Issue
Block a user