mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
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)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user