Merge pull request #16717 from OrestChura:oc/goodFeatures

- cv::gapi::goodFeaturesToTrack() kernel is implemented
- tests (for exact check with cv::goodFeaturesToTrack() and for internal cases) are implemented
- a custom comparison function for vectors and a custom test fixture implemented
  - some posiible issues as wrong/inexact sorting of two compared vectors are
 not taken into account
- initializations of an input Mat using a picture from opencv_extra implemented (function from gapi_streaming_test used)
pull/16512/head
Orest Chura 5 years ago committed by GitHub
parent ab4dbff150
commit 2fe9c87433
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 65
      modules/gapi/include/opencv2/gapi/imgproc.hpp
  2. 5
      modules/gapi/perf/common/gapi_imgproc_perf_tests.hpp
  3. 49
      modules/gapi/perf/common/gapi_imgproc_perf_tests_inl.hpp
  4. 24
      modules/gapi/perf/cpu/gapi_imgproc_perf_tests_cpu.cpp
  5. 10
      modules/gapi/src/api/kernels_imgproc.cpp
  6. 14
      modules/gapi/src/backends/cpu/gcpuimgproc.cpp
  7. 4
      modules/gapi/test/common/gapi_core_tests.hpp
  8. 8
      modules/gapi/test/common/gapi_imgproc_tests.hpp
  9. 30
      modules/gapi/test/common/gapi_imgproc_tests_inl.hpp
  10. 186
      modules/gapi/test/common/gapi_tests_common.hpp
  11. 25
      modules/gapi/test/cpu/gapi_imgproc_tests_cpu.cpp

@ -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_IMGPROC_HPP
@ -102,6 +102,14 @@ namespace imgproc {
}
};
G_TYPED_KERNEL(GGoodFeatures,
<cv::GArray<cv::Point2f>(GMat,int,double,double,Mat,int,bool,double)>,
"org.opencv.imgproc.goodFeaturesToTrack") {
static GArrayDesc outMeta(GMatDesc, int, double, double, const Mat&, int, bool, double) {
return empty_array_desc();
}
};
G_TYPED_KERNEL(GRGB2YUV, <GMat(GMat)>, "org.opencv.imgproc.colorconvert.rgb2yuv") {
static GMatDesc outMeta(GMatDesc in) {
return in; // type still remains CV_8UC3;
@ -251,7 +259,7 @@ namespace imgproc {
}
};
}
} //namespace imgproc
//! @addtogroup gapi_filters
@ -657,6 +665,59 @@ L2gradient=false ).
GAPI_EXPORTS GMat Canny(const GMat& image, double threshold1, double threshold2,
int apertureSize = 3, bool L2gradient = false);
/** @brief Determines strong corners on an image.
The function finds the most prominent corners in the image or in the specified image region, as
described in @cite Shi94
- Function calculates the corner quality measure at every source image pixel using the
#cornerMinEigenVal or #cornerHarris .
- Function performs a non-maximum suppression (the local maximums in *3 x 3* neighborhood are
retained).
- The corners with the minimal eigenvalue less than
\f$\texttt{qualityLevel} \cdot \max_{x,y} qualityMeasureMap(x,y)\f$ are rejected.
- The remaining corners are sorted by the quality measure in the descending order.
- Function throws away each corner for which there is a stronger corner at a distance less than
maxDistance.
The function can be used to initialize a point-based tracker of an object.
@note If the function is called with different values A and B of the parameter qualityLevel , and
A \> B, the vector of returned corners with qualityLevel=A will be the prefix of the output vector
with qualityLevel=B .
@note Function textual ID is "org.opencv.imgproc.goodFeaturesToTrack"
@param image Input 8-bit or floating-point 32-bit, single-channel image.
@param maxCorners Maximum number of corners to return. If there are more corners than are found,
the strongest of them is returned. `maxCorners <= 0` implies that no limit on the maximum is set
and all detected corners are returned.
@param qualityLevel Parameter characterizing the minimal accepted quality of image corners. The
parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue
(see #cornerMinEigenVal ) or the Harris function response (see #cornerHarris ). The corners with the
quality measure less than the product are rejected. For example, if the best corner has the
quality measure = 1500, and the qualityLevel=0.01 , then all the corners with the quality measure
less than 15 are rejected.
@param minDistance Minimum possible Euclidean distance between the returned corners.
@param mask Optional region of interest. If the image is not empty (it needs to have the type
CV_8UC1 and the same size as image ), it specifies the region in which the corners are detected.
@param blockSize Size of an average block for computing a derivative covariation matrix over each
pixel neighborhood. See cornerEigenValsAndVecs .
@param useHarrisDetector Parameter indicating whether to use a Harris detector (see #cornerHarris)
or #cornerMinEigenVal.
@param k Free parameter of the Harris detector.
@return vector of detected corners.
*/
GAPI_EXPORTS GArray<Point2f> goodFeaturesToTrack(const GMat &image,
int maxCorners,
double qualityLevel,
double minDistance,
const Mat &mask = Mat(),
int blockSize = 3,
bool useHarrisDetector = false,
double k = 0.04);
/** @brief Equalizes the histogram of a grayscale image.
The function equalizes the histogram of the input image using the following algorithm:

@ -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_IMGPROC_PERF_TESTS_HPP
@ -33,6 +33,9 @@ class Dilate3x3PerfTest : public TestPerfParams<tuple<compare_f, MatType,cv::Siz
class SobelPerfTest : public TestPerfParams<tuple<compare_f, MatType,int,cv::Size,int,int,int, cv::GCompileArgs>> {};
class SobelXYPerfTest : public TestPerfParams<tuple<compare_f, MatType,int,cv::Size,int,int, cv::GCompileArgs>> {};
class CannyPerfTest : public TestPerfParams<tuple<compare_f, MatType,cv::Size,double,double,int,bool, cv::GCompileArgs>> {};
class GoodFeaturesPerfTest : public TestPerfParams<tuple<compare_vector_f<cv::Point2f>, std::string,
int,int,double,double,int,bool,
cv::GCompileArgs>> {};
class EqHistPerfTest : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCompileArgs >> {};
class RGB2GrayPerfTest : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCompileArgs >> {};
class BGR2GrayPerfTest : public TestPerfParams<tuple<compare_f, cv::Size, cv::GCompileArgs >> {};

@ -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-2019 Intel Corporation
// Copyright (C) 2018-2020 Intel Corporation
#ifndef OPENCV_GAPI_IMGPROC_PERF_TESTS_INL_HPP
@ -622,6 +622,53 @@ PERF_TEST_P_(CannyPerfTest, TestPerformance)
//------------------------------------------------------------------------------
PERF_TEST_P_(GoodFeaturesPerfTest, TestPerformance)
{
double k = 0.04;
compare_vector_f<cv::Point2f> cmpF;
std::string fileName = "";
int type = -1, maxCorners = -1, blockSize = -1;
double qualityLevel = 0.0, minDistance = 0.0;
bool useHarrisDetector = false;
cv::GCompileArgs compileArgs;
std::tie(cmpF, fileName, type, maxCorners, qualityLevel,
minDistance, blockSize, useHarrisDetector, compileArgs) = GetParam();
initMatFromImage(type, fileName);
std::vector<cv::Point2f> outVecOCV, outVecGAPI;
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::goodFeaturesToTrack(in_mat1, outVecOCV, maxCorners, qualityLevel, minDistance,
cv::noArray(), blockSize, useHarrisDetector, k);
}
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto out = cv::gapi::goodFeaturesToTrack(in, maxCorners, qualityLevel, minDistance, cv::Mat(),
blockSize, useHarrisDetector, k);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
// Warm-up graph engine:
c.apply(cv::gin(in_mat1), cv::gout(outVecGAPI), std::move(compileArgs));
TEST_CYCLE()
{
c.apply(cv::gin(in_mat1), cv::gout(outVecGAPI));
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(outVecGAPI, outVecOCV));
}
SANITY_CHECK_NOTHING();
}
//------------------------------------------------------------------------------
PERF_TEST_P_(EqHistPerfTest, TestPerformance)
{
compare_f cmpF = get<0>(GetParam());

@ -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 "../perf_precomp.hpp"
@ -134,6 +134,28 @@ INSTANTIATE_TEST_CASE_P(CannyPerfTestCPU, CannyPerfTest,
Values(true, false),
Values(cv::compile_args(IMGPROC_CPU))));
INSTANTIATE_TEST_CASE_P(GoodFeaturesPerfTestCPU, GoodFeaturesPerfTest,
Combine(Values(AbsExactVector<cv::Point2f>().to_compare_f()),
Values("cv/shared/pic5.png", "stitching/a1.png"),
Values(CV_32FC1, CV_8UC1),
Values(100, 500),
Values(0.1, 0.01),
Values(1.0),
Values(3, 5),
Values(true, false),
Values(cv::compile_args(IMGPROC_CPU))));
INSTANTIATE_TEST_CASE_P(GoodFeaturesInternalPerfTestCPU, GoodFeaturesPerfTest,
Combine(Values(AbsExactVector<cv::Point2f>().to_compare_f()),
Values("cv/cascadeandhog/images/audrybt1.png"),
Values(CV_32FC1, CV_8UC1),
Values(100),
Values(0.0000001),
Values(5.0),
Values(3),
Values(true),
Values(cv::compile_args(IMGPROC_CPU))));
INSTANTIATE_TEST_CASE_P(EqHistPerfTestCPU, EqHistPerfTest,
Combine(Values(AbsExact().to_compare_f()),
Values(szVGA, sz720p, sz1080p),

@ -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"
@ -97,6 +97,14 @@ GMat Canny(const GMat& src, double thr1, double thr2, int apertureSize, bool l2g
return imgproc::GCanny::on(src, thr1, thr2, apertureSize, l2gradient);
}
cv::GArray<cv::Point2f> goodFeaturesToTrack(const GMat& image, int maxCorners, double qualityLevel,
double minDistance, const Mat& mask, int blockSize,
bool useHarrisDetector, double k)
{
return imgproc::GGoodFeatures::on(image, maxCorners, qualityLevel, minDistance, mask, blockSize,
useHarrisDetector, k);
}
GMat RGB2Gray(const GMat& src)
{
return imgproc::GRGB2Gray::on(src);

@ -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"
@ -182,6 +182,17 @@ GAPI_OCV_KERNEL(GCPUCanny, cv::gapi::imgproc::GCanny)
}
};
GAPI_OCV_KERNEL(GCPUGoodFeatures, cv::gapi::imgproc::GGoodFeatures)
{
static void run(const cv::Mat& image, int maxCorners, double qualityLevel, double minDistance,
const cv::Mat& mask, int blockSize, bool useHarrisDetector, double k,
std::vector<cv::Point2f> &out)
{
cv::goodFeaturesToTrack(image, out, maxCorners, qualityLevel, minDistance,
mask, blockSize, useHarrisDetector, k);
}
};
GAPI_OCV_KERNEL(GCPURGB2YUV, cv::gapi::imgproc::GRGB2YUV)
{
static void run(const cv::Mat& in, cv::Mat &out)
@ -412,6 +423,7 @@ cv::gapi::GKernelPackage cv::gapi::imgproc::cpu::kernels()
, GCPUSobel
, GCPUSobelXY
, GCPUCanny
, GCPUGoodFeatures
, GCPUEqualizeHist
, GCPURGB2YUV
, GCPUYUV2RGB

@ -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-2019 Intel Corporation
// Copyright (C) 2018-2020 Intel Corporation
#ifndef OPENCV_GAPI_CORE_TESTS_HPP
@ -128,7 +128,7 @@ GAPI_TEST_FIXTURE(PhaseTest, initMatsRandU, FIXTURE_API(bool), 1, angle_in_degre
GAPI_TEST_FIXTURE(SqrtTest, initMatrixRandU, <>, 0)
GAPI_TEST_FIXTURE(NormalizeTest, initNothing, FIXTURE_API(CompareMats,double,double,int,MatType2), 5,
cmpF, a, b, norm_type, ddepth)
struct BackendOutputAllocationTest : TestWithParamBase<>
struct BackendOutputAllocationTest : TestWithParams<>
{
BackendOutputAllocationTest()
{

@ -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-2019 Intel Corporation
// Copyright (C) 2018-2020 Intel Corporation
#ifndef OPENCV_GAPI_IMGPROC_TESTS_HPP
@ -14,6 +14,7 @@
namespace opencv_test
{
// Create new value-parameterized test fixture:
// Filter2DTest - fixture name
// initMatrixRandN - function that is used to initialize input/output data
@ -52,6 +53,11 @@ GAPI_TEST_FIXTURE(SobelXYTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int,
GAPI_TEST_FIXTURE(EqHistTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(CannyTest, initMatrixRandN, FIXTURE_API(CompareMats,double,double,int,bool), 5,
cmpF, thrLow, thrUp, apSize, l2gr)
GAPI_TEST_FIXTURE_SPEC_PARAMS(GoodFeaturesTest,
FIXTURE_API(CompareVectors<cv::Point2f>,std::string,int,int,double,
double,int,bool),
8, cmpF, fileName, type, maxCorners, qualityLevel, minDistance,
blockSize, useHarrisDetector)
GAPI_TEST_FIXTURE(RGB2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(BGR2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(RGB2YUVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)

@ -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-2019 Intel Corporation
// Copyright (C) 2018-2020 Intel Corporation
#ifndef OPENCV_GAPI_IMGPROC_TESTS_INL_HPP
@ -380,6 +380,34 @@ TEST_P(CannyTest, AccuracyTest)
}
}
TEST_P(GoodFeaturesTest, AccuracyTest)
{
double k = 0.04;
initMatFromImage(type, fileName);
std::vector<cv::Point2f> outVecOCV, outVecGAPI;
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto out = cv::gapi::goodFeaturesToTrack(in, maxCorners, qualityLevel, minDistance, cv::Mat(),
blockSize, useHarrisDetector, k);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_mat1), cv::gout(outVecGAPI), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::goodFeaturesToTrack(in_mat1, outVecOCV, maxCorners, qualityLevel, minDistance,
cv::noArray(), blockSize, useHarrisDetector, k);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(outVecGAPI, outVecOCV));
}
}
TEST_P(RGB2GrayTest, AccuracyTest)
{
// G-API code //////////////////////////////////////////////////////////////

@ -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-2019 Intel Corporation
// Copyright (C) 2018-2020 Intel Corporation
#ifndef OPENCV_GAPI_TESTS_COMMON_HPP
#define OPENCV_GAPI_TESTS_COMMON_HPP
@ -56,7 +56,24 @@ namespace
return o;
}
}
inline void initTestDataPath()
{
#ifndef WINRT
static bool initialized = false;
if (!initialized)
{
// Since G-API has no own test data (yet), it is taken from the common space
const char* testDataPath = getenv("OPENCV_TEST_DATA_PATH");
GAPI_Assert(testDataPath != nullptr &&
"OPENCV_TEST_DATA_PATH environment variable is either not set or set incorrectly.");
cvtest::addDataSearchPath(testDataPath);
initialized = true;
}
#endif // WINRT
}
} // namespace
namespace opencv_test
{
@ -155,6 +172,30 @@ public:
}
}
void initMatFromImage(int type, const std::string& fileName)
{
initTestDataPath();
int channels = (type >> CV_CN_SHIFT) + 1;
GAPI_Assert(channels == 1 || channels == 3 || channels == 4);
const int readFlags = (channels == 1) ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR;
cv::Mat mat = cv::imread(findDataFile(fileName), readFlags);
if (channels == 4)
{
cv::cvtColor(mat, in_mat1, cv::COLOR_BGR2BGRA);
}
else
{
in_mat1 = mat;
}
int depth = CV_MAT_DEPTH(type);
if (in_mat1.depth() != depth)
{
in_mat1.convertTo(in_mat1, depth);
}
}
// empty function intended to show that nothing is to be initialized via TestFunctional methods
void initNothing(int, cv::Size, int, bool = true) {}
};
@ -169,6 +210,11 @@ 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
@ -189,14 +235,16 @@ private:
};
// Universal parameter wrapper for common (pre-defined) and specific (user-defined) parameters
template<typename ...SpecificParams>
struct Params
template<typename CommonParams, typename SpecificParams>
struct ParamsBase;
template<typename... CommonParams, typename... SpecificParams>
struct ParamsBase<std::tuple<CommonParams...>, std::tuple<SpecificParams...>>
{
using gcomp_args_function_t = cv::GCompileArgs(*)();
using common_params_t = std::tuple<MatType2, cv::Size, MatType2, gcomp_args_function_t>;
using common_params_t = std::tuple<CommonParams...>;
using specific_params_t = std::tuple<SpecificParams...>;
using params_t = std::tuple<MatType2, cv::Size, MatType2, gcomp_args_function_t, SpecificParams...>;
static constexpr const size_t common_params_size = std::tuple_size<common_params_t>::value;
using params_t = std::tuple<CommonParams..., SpecificParams...>;
static constexpr const size_t common_params_size = std::tuple_size<common_params_t>::value;
static constexpr const size_t specific_params_size = std::tuple_size<specific_params_t>::value;
template<size_t I>
@ -218,17 +266,24 @@ struct Params
}
};
// Base class for test fixtures
template<typename ...SpecificParams>
struct TestWithParamBase : TestFunctional,
TestWithParam<typename Params<SpecificParams...>::params_t>
template<typename... SpecificParams>
struct Params : public ParamsBase<std::tuple<MatType2,cv::Size,MatType2,cv::GCompileArgs(*)()>,
std::tuple<SpecificParams...>>
{
using AllParams = Params<SpecificParams...>;
static constexpr const size_t compile_args_num = 3;
};
MatType2 type = getCommonParam<0>();
cv::Size sz = getCommonParam<1>();
MatType2 dtype = getCommonParam<2>();
template<typename ...SpecificParams>
struct ParamsSpecific : public ParamsBase<std::tuple<cv::GCompileArgs(*)()>,
std::tuple<SpecificParams...>>
{
static constexpr const size_t compile_args_num = 0;
};
// Base class for test fixtures
template<typename AllParams>
struct TestWithParamsBase : TestFunctional, TestWithParam<typename AllParams::params_t>
{
// Get common (pre-defined) parameter value by index
template<size_t I>
inline auto getCommonParam() const
@ -248,13 +303,30 @@ struct TestWithParamBase : TestFunctional,
// Return G-API compile arguments specified for test fixture
inline cv::GCompileArgs getCompileArgs() const
{
return getCommonParam<3>()();
return getCommonParam<AllParams::compile_args_num>()();
}
};
template<typename... SpecificParams>
struct TestWithParams : public TestWithParamsBase<Params<SpecificParams...>>
{
using AllParams = Params<SpecificParams...>;
MatType2 type = this->template getCommonParam<0>();
cv::Size sz = this->template getCommonParam<1>();
MatType2 dtype = this->template getCommonParam<2>();
};
template<typename... SpecificParams>
struct TestWithParamsSpecific : public TestWithParamsBase<ParamsSpecific<SpecificParams...>>
{
using AllParams = ParamsSpecific<SpecificParams...>;
};
/**
* @private
* @brief Create G-API test fixture with TestWithParamBase base class
* @brief Create G-API test fixture with TestWithParams base class
* @param Fixture test fixture name
* @param InitF callable that will initialize default available members (from TestFunctional)
* @param API base class API. Specifies types of user-defined parameters. If there are no such
@ -265,13 +337,33 @@ struct TestWithParamBase : TestFunctional,
* must be empty.
*/
#define GAPI_TEST_FIXTURE(Fixture, InitF, API, Number, ...) \
struct Fixture : public TestWithParamBase API { \
struct Fixture : public TestWithParams API { \
static_assert(Number == AllParams::specific_params_size, \
"Number of user-defined parameters doesn't match size of __VA_ARGS__"); \
__WRAP_VAARGS(DEFINE_SPECIFIC_PARAMS_##Number(__VA_ARGS__)) \
Fixture() { InitF(type, sz, dtype); } \
};
/**
* @private
* @brief Create G-API test fixture with TestWithParamsSpecific base class
* This fixture has reduced number of common parameters and no initialization;
* it should be used if you don't need common parameters of GAPI_TEST_FIXTURE.
* @param Fixture test fixture name
* @param API base class API. Specifies types of user-defined parameters. If there are no such
* parameters, empty angle brackets ("<>") must be specified.
* @param Number number of user-defined parameters (corresponds to the number of types in API).
* if there are no such parameters, 0 must be specified.
* @param ... list of names of user-defined parameters. if there are no parameters, the list
* must be empty.
*/
#define GAPI_TEST_FIXTURE_SPEC_PARAMS(Fixture, API, Number, ...) \
struct Fixture : public TestWithParamsSpecific API { \
static_assert(Number == AllParams::specific_params_size, \
"Number of user-defined parameters doesn't match size of __VA_ARGS__"); \
__WRAP_VAARGS(DEFINE_SPECIFIC_PARAMS_##Number(__VA_ARGS__)) \
};
// Wrapper for test fixture API. Use to specify multiple types.
// Example: FIXTURE_API(int, bool) expands to <int, bool>
#define FIXTURE_API(...) <__VA_ARGS__>
@ -298,6 +390,9 @@ private:
using CompareMats = CompareF<cv::Mat, cv::Mat>;
using CompareScalars = CompareF<cv::Scalar, cv::Scalar>;
template<typename Elem>
using CompareVectors = CompareF<std::vector<Elem>, std::vector<Elem>>;
template<typename T>
struct Wrappable
{
@ -340,6 +435,28 @@ struct WrappableScalar
}
};
template<typename T, typename Elem>
struct WrappableVector
{
compare_vector_f<Elem> to_compare_f()
{
T t = *static_cast<T* const>(this);
return [t](const std::vector<Elem>& a,
const std::vector<Elem>& b)
{
return t(a, b);
};
}
CompareVectors<Elem> to_compare_obj()
{
T t = *static_cast<T* const>(this);
std::stringstream ss;
ss << t;
return CompareVectors<Elem>(to_compare_f(), ss.str());
}
};
class AbsExact : public Wrappable<AbsExact>
{
@ -547,6 +664,31 @@ public:
private:
double _tol;
};
template<typename Elem>
class AbsExactVector : public WrappableVector<AbsExactVector<Elem>, Elem>
{
public:
AbsExactVector() {}
bool operator() (const std::vector<Elem>& in1,
const std::vector<Elem>& in2) const
{
if (cv::norm(in1, in2, NORM_INF, cv::noArray()) != 0)
{
std::cout << "AbsExact error: G-API output and reference output vectors are not"
" bitexact equal." << std::endl;
return false;
}
else
{
return true;
}
}
friend std::ostream& operator<<(std::ostream& os, const AbsExactVector<Elem>&)
{
return os << "AbsExactVector()";
}
};
} // namespace opencv_test
namespace
@ -560,6 +702,12 @@ inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_sca
{
return os << "compare_scalar_f";
}
template<typename Elem>
inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_vector_f<Elem>&)
{
return os << "compare_vector_f";
}
} // anonymous namespace
// Note: namespace must match the namespace of the type of the printed object

@ -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-2019 Intel Corporation
// Copyright (C) 2018-2020 Intel Corporation
#include "../test_precomp.hpp"
@ -196,6 +196,29 @@ INSTANTIATE_TEST_CASE_P(CannyTestCPU, CannyTest,
Values(3, 5),
testing::Bool()));
INSTANTIATE_TEST_CASE_P(GoodFeaturesTestCPU, GoodFeaturesTest,
Combine(Values(IMGPROC_CPU),
Values(AbsExactVector<cv::Point2f>().to_compare_obj()),
Values("cv/shared/fruits.png"),
Values(CV_32FC1, CV_8UC1),
Values(50, 100),
Values(0.01),
Values(10.0),
Values(3),
testing::Bool()));
INSTANTIATE_TEST_CASE_P(GoodFeaturesInternalTestCPU, GoodFeaturesTest,
Combine(Values(IMGPROC_CPU),
Values(AbsExactVector<cv::Point2f>().to_compare_obj()),
Values("cv/cascadeandhog/images/audrybt1.png"),
Values(CV_32FC1, CV_8UC1),
Values(100),
Values(0.0000001),
Values(5.0),
Values(3),
Values(true)));
INSTANTIATE_TEST_CASE_P(RGB2GrayTestCPU, RGB2GrayTest,
Combine(Values(CV_8UC3),
Values(cv::Size(1280, 720),

Loading…
Cancel
Save