mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge pull request #18790 from OrestChura:oc/fitLine
[G-API]: fitLine() Standard Kernel Implementation * fitLine API (Mat, 32S, 32F) (2D, 3D) * Complete fitLine kernel & accuracy tests - initialization for vectors of cv::Point and Mats via vectors added - comparison functions for Vec<T, n> added: - straight average difference comparison - comparison by equasion for 2d line - stream overload for cv::DistanceTypes added * Fix precommit warnings * Fix docs * Address comments Try to fix warning * Disable warning in tests
This commit is contained in:
@@ -83,6 +83,22 @@ GAPI_TEST_FIXTURE(BoundingRectVector32STest, initNothing, FIXTURE_API(CompareRec
|
||||
GAPI_TEST_FIXTURE(BoundingRectVector32FTest, initNothing, FIXTURE_API(CompareRects), 1, cmpF)
|
||||
GAPI_TEST_FIXTURE(BGR2RGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
|
||||
GAPI_TEST_FIXTURE(RGB2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
|
||||
GAPI_TEST_FIXTURE(FitLine2DMatVectorTest, initMatByPointsVectorRandU<cv::Point_>,
|
||||
FIXTURE_API(CompareVecs<float, 4>,cv::DistanceTypes), 2, cmpF, distType)
|
||||
GAPI_TEST_FIXTURE(FitLine2DVector32STest, initNothing,
|
||||
FIXTURE_API(CompareVecs<float, 4>,cv::DistanceTypes), 2, cmpF, distType)
|
||||
GAPI_TEST_FIXTURE(FitLine2DVector32FTest, initNothing,
|
||||
FIXTURE_API(CompareVecs<float, 4>,cv::DistanceTypes), 2, cmpF, distType)
|
||||
GAPI_TEST_FIXTURE(FitLine2DVector64FTest, initNothing,
|
||||
FIXTURE_API(CompareVecs<float, 4>,cv::DistanceTypes), 2, cmpF, distType)
|
||||
GAPI_TEST_FIXTURE(FitLine3DMatVectorTest, initMatByPointsVectorRandU<cv::Point3_>,
|
||||
FIXTURE_API(CompareVecs<float, 6>,cv::DistanceTypes), 2, cmpF, distType)
|
||||
GAPI_TEST_FIXTURE(FitLine3DVector32STest, initNothing,
|
||||
FIXTURE_API(CompareVecs<float, 6>,cv::DistanceTypes), 2, cmpF, distType)
|
||||
GAPI_TEST_FIXTURE(FitLine3DVector32FTest, initNothing,
|
||||
FIXTURE_API(CompareVecs<float, 6>,cv::DistanceTypes), 2, cmpF, distType)
|
||||
GAPI_TEST_FIXTURE(FitLine3DVector64FTest, initNothing,
|
||||
FIXTURE_API(CompareVecs<float, 6>,cv::DistanceTypes), 2, cmpF, distType)
|
||||
GAPI_TEST_FIXTURE(BGR2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
|
||||
GAPI_TEST_FIXTURE(RGB2YUVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
|
||||
GAPI_TEST_FIXTURE(BGR2I420Test, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
|
||||
|
||||
@@ -752,6 +752,192 @@ TEST_P(BoundingRectVector32FTest, AccuracyTest)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(FitLine2DMatVectorTest, AccuracyTest)
|
||||
{
|
||||
cv::Vec4f out_vec_gapi, out_vec_ocv;
|
||||
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
|
||||
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
cv::GMat in;
|
||||
auto out = cv::gapi::fitLine2D(in, distType, paramDefault, repsDefault, aepsDefault);
|
||||
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
c.apply(cv::gin(in_mat1), cv::gout(out_vec_gapi), getCompileArgs());
|
||||
// OpenCV code /////////////////////////////////////////////////////////////
|
||||
{
|
||||
cv::fitLine(in_mat1, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
|
||||
}
|
||||
// Comparison //////////////////////////////////////////////////////////////
|
||||
{
|
||||
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(FitLine2DVector32STest, AccuracyTest)
|
||||
{
|
||||
cv::Vec4f out_vec_gapi, out_vec_ocv;
|
||||
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
|
||||
|
||||
std::vector<cv::Point2i> in_vec;
|
||||
initPointsVectorRandU(sz.width, in_vec);
|
||||
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
cv::GArray<cv::Point2i> in;
|
||||
auto out = cv::gapi::fitLine2D(in, distType, paramDefault, repsDefault, aepsDefault);
|
||||
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
|
||||
// OpenCV code /////////////////////////////////////////////////////////////
|
||||
{
|
||||
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
|
||||
}
|
||||
// Comparison //////////////////////////////////////////////////////////////
|
||||
{
|
||||
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(FitLine2DVector32FTest, AccuracyTest)
|
||||
{
|
||||
cv::Vec4f out_vec_gapi, out_vec_ocv;
|
||||
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
|
||||
|
||||
std::vector<cv::Point2f> in_vec;
|
||||
initPointsVectorRandU(sz.width, in_vec);
|
||||
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
cv::GArray<cv::Point2f> in;
|
||||
auto out = cv::gapi::fitLine2D(in, distType, paramDefault, repsDefault, aepsDefault);
|
||||
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
|
||||
// OpenCV code /////////////////////////////////////////////////////////////
|
||||
{
|
||||
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
|
||||
}
|
||||
// Comparison //////////////////////////////////////////////////////////////
|
||||
{
|
||||
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(FitLine2DVector64FTest, AccuracyTest)
|
||||
{
|
||||
cv::Vec4f out_vec_gapi, out_vec_ocv;
|
||||
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
|
||||
|
||||
std::vector<cv::Point2d> in_vec;
|
||||
initPointsVectorRandU(sz.width, in_vec);
|
||||
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
cv::GArray<cv::Point2d> in;
|
||||
auto out = cv::gapi::fitLine2D(in, distType, paramDefault, repsDefault, aepsDefault);
|
||||
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
|
||||
// OpenCV code /////////////////////////////////////////////////////////////
|
||||
{
|
||||
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
|
||||
}
|
||||
// Comparison //////////////////////////////////////////////////////////////
|
||||
{
|
||||
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(FitLine3DMatVectorTest, AccuracyTest)
|
||||
{
|
||||
cv::Vec6f out_vec_gapi, out_vec_ocv;
|
||||
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
|
||||
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
cv::GMat in;
|
||||
auto out = cv::gapi::fitLine3D(in, distType, paramDefault, repsDefault, aepsDefault);
|
||||
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
c.apply(cv::gin(in_mat1), cv::gout(out_vec_gapi), getCompileArgs());
|
||||
// OpenCV code /////////////////////////////////////////////////////////////
|
||||
{
|
||||
cv::fitLine(in_mat1, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
|
||||
}
|
||||
// Comparison //////////////////////////////////////////////////////////////
|
||||
{
|
||||
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(FitLine3DVector32STest, AccuracyTest)
|
||||
{
|
||||
cv::Vec6f out_vec_gapi, out_vec_ocv;
|
||||
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
|
||||
|
||||
std::vector<cv::Point3i> in_vec;
|
||||
initPointsVectorRandU(sz.width, in_vec);
|
||||
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
cv::GArray<cv::Point3i> in;
|
||||
auto out = cv::gapi::fitLine3D(in, distType, paramDefault, repsDefault, aepsDefault);
|
||||
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
|
||||
// OpenCV code /////////////////////////////////////////////////////////////
|
||||
{
|
||||
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
|
||||
}
|
||||
// Comparison //////////////////////////////////////////////////////////////
|
||||
{
|
||||
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(FitLine3DVector32FTest, AccuracyTest)
|
||||
{
|
||||
cv::Vec6f out_vec_gapi, out_vec_ocv;
|
||||
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
|
||||
|
||||
std::vector<cv::Point3f> in_vec;
|
||||
initPointsVectorRandU(sz.width, in_vec);
|
||||
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
cv::GArray<cv::Point3f> in;
|
||||
auto out = cv::gapi::fitLine3D(in, distType, paramDefault, repsDefault, aepsDefault);
|
||||
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
|
||||
// OpenCV code /////////////////////////////////////////////////////////////
|
||||
{
|
||||
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
|
||||
}
|
||||
// Comparison //////////////////////////////////////////////////////////////
|
||||
{
|
||||
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(FitLine3DVector64FTest, AccuracyTest)
|
||||
{
|
||||
cv::Vec6f out_vec_gapi, out_vec_ocv;
|
||||
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
|
||||
|
||||
std::vector<cv::Point3d> in_vec;
|
||||
initPointsVectorRandU(sz.width, in_vec);
|
||||
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
cv::GArray<cv::Point3d> in;
|
||||
auto out = cv::gapi::fitLine3D(in, distType, paramDefault, repsDefault, aepsDefault);
|
||||
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
|
||||
// OpenCV code /////////////////////////////////////////////////////////////
|
||||
{
|
||||
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
|
||||
}
|
||||
// Comparison //////////////////////////////////////////////////////////////
|
||||
{
|
||||
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(BGR2RGBTest, AccuracyTest)
|
||||
{
|
||||
// G-API code //////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -74,6 +74,50 @@ namespace
|
||||
}
|
||||
#endif // WINRT
|
||||
}
|
||||
|
||||
template <typename T> inline void initPointRandU(cv::RNG &rng, cv::Point_<T>& pt)
|
||||
{
|
||||
GAPI_Assert(std::is_integral<T>::value);
|
||||
pt = cv::Point_<T>(static_cast<T>(static_cast<char>(rng(CHAR_MAX + 1U))),
|
||||
static_cast<T>(static_cast<char>(rng(CHAR_MAX + 1U))));
|
||||
}
|
||||
|
||||
template <typename T> inline void initPointRandU(cv::RNG &rng, cv::Point3_<T>& pt)
|
||||
{
|
||||
GAPI_Assert(std::is_integral<T>::value);
|
||||
pt = cv::Point3_<T>(static_cast<T>(static_cast<char>(rng(CHAR_MAX + 1U))),
|
||||
static_cast<T>(static_cast<char>(rng(CHAR_MAX + 1U))),
|
||||
static_cast<T>(static_cast<char>(rng(CHAR_MAX + 1U))));
|
||||
}
|
||||
|
||||
template <typename F> inline void initFloatPointRandU(cv::RNG &rng, cv::Point_<F> &pt)
|
||||
{
|
||||
GAPI_Assert(std::is_floating_point<F>::value);
|
||||
static const int fscale = 256; // avoid bits near ULP, generate stable test input
|
||||
pt = cv::Point_<F>(rng.uniform(0, 255 * fscale) / static_cast<F>(fscale),
|
||||
rng.uniform(0, 255 * fscale) / static_cast<F>(fscale));
|
||||
}
|
||||
|
||||
template<> inline void initPointRandU(cv::RNG &rng, cv::Point2f &pt)
|
||||
{ initFloatPointRandU(rng, pt); }
|
||||
|
||||
template<> inline void initPointRandU(cv::RNG &rng, cv::Point2d &pt)
|
||||
{ initFloatPointRandU(rng, pt); }
|
||||
|
||||
template <typename F> inline void initFloatPointRandU(cv::RNG &rng, cv::Point3_<F> &pt)
|
||||
{
|
||||
GAPI_Assert(std::is_floating_point<F>::value);
|
||||
static const int fscale = 256; // avoid bits near ULP, generate stable test input
|
||||
pt = cv::Point3_<F>(rng.uniform(0, 255 * fscale) / static_cast<F>(fscale),
|
||||
rng.uniform(0, 255 * fscale) / static_cast<F>(fscale),
|
||||
rng.uniform(0, 255 * fscale) / static_cast<F>(fscale));
|
||||
}
|
||||
|
||||
template<> inline void initPointRandU(cv::RNG &rng, cv::Point3f &pt)
|
||||
{ initFloatPointRandU(rng, pt); }
|
||||
|
||||
template<> inline void initPointRandU(cv::RNG &rng, cv::Point3d &pt)
|
||||
{ initFloatPointRandU(rng, pt); }
|
||||
} // namespace
|
||||
|
||||
namespace opencv_test
|
||||
@@ -279,6 +323,80 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void initPointRandU(cv::RNG& rng, T& pt)
|
||||
{ ::initPointRandU(rng, pt); }
|
||||
|
||||
// Disable unreachable code warning for MSVS 2015
|
||||
#if defined _MSC_VER && _MSC_VER < 1910 /*MSVS 2017*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
// initialize std::vector<cv::Point_<T>>/std::vector<cv::Point3_<T>>
|
||||
template <typename T, template <typename> class Pt>
|
||||
void initPointsVectorRandU(const int sz_in, std::vector<Pt<T>> &vec_)
|
||||
{
|
||||
cv::RNG& rng = theRNG();
|
||||
|
||||
vec_.clear();
|
||||
vec_.reserve(sz_in);
|
||||
|
||||
for (int i = 0; i < sz_in; i++)
|
||||
{
|
||||
Pt<T> pt;
|
||||
initPointRandU(rng, pt);
|
||||
vec_.emplace_back(pt);
|
||||
}
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER < 1910 /*MSVS 2017*/
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template<typename Pt>
|
||||
inline void initMatByPointsVectorRandU(const cv::Size &sz_in)
|
||||
{
|
||||
std::vector<Pt> in_vector;
|
||||
initPointsVectorRandU(sz_in.width, in_vector);
|
||||
in_mat1 = cv::Mat(in_vector, true);
|
||||
}
|
||||
|
||||
// initialize Mat by a vector of Points
|
||||
template<template <typename> class Pt>
|
||||
inline void initMatByPointsVectorRandU(int type, cv::Size sz_in, int)
|
||||
{
|
||||
int depth = CV_MAT_DEPTH(type);
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8U:
|
||||
initMatByPointsVectorRandU<Pt<uchar>>(sz_in);
|
||||
break;
|
||||
case CV_8S:
|
||||
initMatByPointsVectorRandU<Pt<char>>(sz_in);
|
||||
break;
|
||||
case CV_16U:
|
||||
initMatByPointsVectorRandU<Pt<ushort>>(sz_in);
|
||||
break;
|
||||
case CV_16S:
|
||||
initMatByPointsVectorRandU<Pt<short>>(sz_in);
|
||||
break;
|
||||
case CV_32S:
|
||||
initMatByPointsVectorRandU<Pt<int>>(sz_in);
|
||||
break;
|
||||
case CV_32F:
|
||||
initMatByPointsVectorRandU<Pt<float>>(sz_in);
|
||||
break;
|
||||
case CV_64F:
|
||||
initMatByPointsVectorRandU<Pt<double>>(sz_in);
|
||||
break;
|
||||
case CV_16F:
|
||||
initMatByPointsVectorRandU<Pt<cv::float16_t>>(sz_in);
|
||||
break;
|
||||
default:
|
||||
GAPI_Assert(false && "Unsupported depth");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// empty function intended to show that nothing is to be initialized via TestFunctional methods
|
||||
void initNothing(int, cv::Size, int, bool = true) {}
|
||||
};
|
||||
@@ -469,6 +587,9 @@ template<typename Elem>
|
||||
using compare_vector_f = std::function<bool(const std::vector<Elem> &a,
|
||||
const std::vector<Elem> &b)>;
|
||||
|
||||
template<typename Elem, int cn>
|
||||
using compare_vec_f = std::function<bool(const cv::Vec<Elem, cn> &a, const cv::Vec<Elem, cn> &b)>;
|
||||
|
||||
template<typename T1, typename T2>
|
||||
struct CompareF
|
||||
{
|
||||
@@ -495,6 +616,9 @@ using CompareRects = CompareF<cv::Rect, cv::Rect>;
|
||||
template<typename Elem>
|
||||
using CompareVectors = CompareF<std::vector<Elem>, std::vector<Elem>>;
|
||||
|
||||
template<typename Elem, int cn>
|
||||
using CompareVecs = CompareF<cv::Vec<Elem, cn>, cv::Vec<Elem, cn>>;
|
||||
|
||||
template<typename T>
|
||||
struct Wrappable
|
||||
{
|
||||
@@ -580,6 +704,27 @@ struct WrappableVector
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Elem, int cn>
|
||||
struct WrappableVec
|
||||
{
|
||||
compare_vec_f<Elem, cn> to_compare_f()
|
||||
{
|
||||
T t = *static_cast<T* const>(this);
|
||||
return [t](const cv::Vec<Elem, cn> &a, const cv::Vec<Elem, cn> &b)
|
||||
{
|
||||
return t(a, b);
|
||||
};
|
||||
}
|
||||
|
||||
CompareVecs<Elem, cn> to_compare_obj()
|
||||
{
|
||||
T t = *static_cast<T* const>(this);
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
return CompareVecs<Elem, cn>(to_compare_f(), ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class AbsExact : public Wrappable<AbsExact>
|
||||
{
|
||||
@@ -855,6 +1000,41 @@ public:
|
||||
return os << "AbsExactVector()";
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Elem, int cn>
|
||||
class RelDiffToleranceVec : public WrappableVec<RelDiffToleranceVec<Elem, cn>, Elem, cn>
|
||||
{
|
||||
public:
|
||||
RelDiffToleranceVec(double tol) : _tol(tol) {}
|
||||
bool operator() (const cv::Vec<Elem, cn> &in1, const cv::Vec<Elem, cn> &in2) const
|
||||
{
|
||||
double abs_err = cv::norm(in1, in2, cv::NORM_L1);
|
||||
double in2_norm = cv::norm(in2, cv::NORM_L1);
|
||||
// Checks to avoid dividing by zero
|
||||
double err = abs_err ? abs_err / (in2_norm ? in2_norm : cv::norm(in1, cv::NORM_L1))
|
||||
: abs_err;
|
||||
if (err > _tol)
|
||||
{
|
||||
std::cout << "RelDiffToleranceVec error: err=" << err << " tolerance=" << _tol;
|
||||
for (int i = 0; i < cn; i++)
|
||||
{
|
||||
std::cout << " in1[" << i << "]=" << in1[i] << " in2[" << i << "]=" << in2[i];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& os, const RelDiffToleranceVec<Elem, cn>& obj)
|
||||
{
|
||||
return os << "RelDiffToleranceVec(" << std::to_string(obj._tol) << ")";
|
||||
}
|
||||
private:
|
||||
double _tol;
|
||||
};
|
||||
} // namespace opencv_test
|
||||
|
||||
namespace
|
||||
@@ -879,6 +1059,12 @@ inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_vec
|
||||
{
|
||||
return os << "compare_vector_f";
|
||||
}
|
||||
|
||||
template<typename Elem, int cn>
|
||||
inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_vec_f<Elem, cn>&)
|
||||
{
|
||||
return os << "compare_vec_f";
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
// Note: namespace must match the namespace of the type of the printed object
|
||||
@@ -969,6 +1155,25 @@ inline std::ostream& operator<<(std::ostream& os, MorphTypes op)
|
||||
#undef CASE
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, DistanceTypes op)
|
||||
{
|
||||
#define CASE(v) case DistanceTypes::v: os << #v; break
|
||||
switch (op)
|
||||
{
|
||||
CASE(DIST_USER);
|
||||
CASE(DIST_L1);
|
||||
CASE(DIST_L2);
|
||||
CASE(DIST_C);
|
||||
CASE(DIST_L12);
|
||||
CASE(DIST_FAIR);
|
||||
CASE(DIST_WELSCH);
|
||||
CASE(DIST_HUBER);
|
||||
default: GAPI_Assert(false && "unknown DistanceTypes value");
|
||||
}
|
||||
#undef CASE
|
||||
return os;
|
||||
}
|
||||
} // namespace cv
|
||||
|
||||
#endif //OPENCV_GAPI_TESTS_COMMON_HPP
|
||||
|
||||
Reference in New Issue
Block a user