// 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) 2018-2020 Intel Corporation #ifndef OPENCV_GAPI_TESTS_COMMON_HPP #define OPENCV_GAPI_TESTS_COMMON_HPP #include #include #include #include #include #include #include #include "gapi_tests_helpers.hpp" #include namespace { inline std::ostream& operator<<(std::ostream& o, const cv::GCompileArg& arg) { return o << (arg.tag.empty() ? "empty" : arg.tag); } inline std::ostream& operator<<(std::ostream& o, const cv::gapi::wip::draw::Prim& p) { using namespace cv::gapi::wip::draw; switch (p.index()) { case Prim::index_of(): o << "cv::gapi::draw::Rect"; break; case Prim::index_of(): o << "cv::gapi::draw::Text"; break; case Prim::index_of(): o << "cv::gapi::draw::Circle"; break; case Prim::index_of(): o << "cv::gapi::draw::Line"; break; case Prim::index_of(): o << "cv::gapi::draw::Mosaic"; break; case Prim::index_of(): o << "cv::gapi::draw::Image"; break; case Prim::index_of(): o << "cv::gapi::draw::Poly"; break; default: o << "Unrecognized primitive"; } 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 } template inline void initPointRandU(cv::RNG &rng, cv::Point_& pt) { GAPI_Assert(std::is_integral::value); pt = cv::Point_(static_cast(static_cast(rng(CHAR_MAX + 1U))), static_cast(static_cast(rng(CHAR_MAX + 1U)))); } template inline void initPointRandU(cv::RNG &rng, cv::Point3_& pt) { GAPI_Assert(std::is_integral::value); pt = cv::Point3_(static_cast(static_cast(rng(CHAR_MAX + 1U))), static_cast(static_cast(rng(CHAR_MAX + 1U))), static_cast(static_cast(rng(CHAR_MAX + 1U)))); } template inline void initFloatPointRandU(cv::RNG &rng, cv::Point_ &pt) { GAPI_Assert(std::is_floating_point::value); static const int fscale = 256; // avoid bits near ULP, generate stable test input pt = cv::Point_(rng.uniform(0, 255 * fscale) / static_cast(fscale), rng.uniform(0, 255 * fscale) / static_cast(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 inline void initFloatPointRandU(cv::RNG &rng, cv::Point3_ &pt) { GAPI_Assert(std::is_floating_point::value); static const int fscale = 256; // avoid bits near ULP, generate stable test input pt = cv::Point3_(rng.uniform(0, 255 * fscale) / static_cast(fscale), rng.uniform(0, 255 * fscale) / static_cast(fscale), rng.uniform(0, 255 * fscale) / static_cast(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 { class TestFunctional { public: cv::Mat in_mat1; cv::Mat in_mat2; cv::Mat out_mat_gapi; cv::Mat out_mat_ocv; cv::Scalar sc; // integral Scalar initialization cv::Scalar initScalarRandU(unsigned upper) { cv::RNG rng(time(nullptr)); double s1 = rng(upper); double s2 = rng(upper); double s3 = rng(upper); double s4 = rng(upper); return cv::Scalar(s1, s2, s3, s4); } // floating-point Scalar initialization (cv::core) cv::Scalar initScalarRandU() { cv::RNG rng(time(nullptr)); double s1 = exp(rng.uniform(-1, 6) * 3.0 * CV_LOG2) * (rng.uniform(0, 2) ? 1. : -1.); double s2 = exp(rng.uniform(-1, 6) * 3.0 * CV_LOG2) * (rng.uniform(0, 2) ? 1. : -1.); double s3 = exp(rng.uniform(-1, 6) * 3.0 * CV_LOG2) * (rng.uniform(0, 2) ? 1. : -1.); double s4 = exp(rng.uniform(-1, 6) * 3.0 * CV_LOG2) * (rng.uniform(0, 2) ? 1. : -1.); return cv::Scalar(s1, s2, s3, s4); } void initOutMats(cv::Size sz_in, int dtype) { if (dtype != -1) { out_mat_gapi = cv::Mat(sz_in, dtype); out_mat_ocv = cv::Mat(sz_in, dtype); } } void initMatsRandU(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true) { in_mat1 = cv::Mat(sz_in, type); in_mat2 = cv::Mat(sz_in, type); int sdepth = CV_MAT_DEPTH(type); int ddepth = (dtype >= 0) ? CV_MAT_DEPTH(dtype) : sdepth; // dtype == -1 <=> dtype == SAME_TYPE if ((sdepth >= CV_32F) || (ddepth >= CV_32F)) { sc = initScalarRandU(); // initializing by floating-points } else { switch (sdepth) { case CV_8U: sc = initScalarRandU(UCHAR_MAX + 1U); break; case CV_16U: sc = initScalarRandU(USHRT_MAX + 1U); break; case CV_16S: sc = initScalarRandU(SHRT_MAX + 1U); break; default: sc = initScalarRandU(SCHAR_MAX + 1U); break; } } // Details: https://github.com/opencv/opencv/pull/16083 //if (CV_MAT_DEPTH(type) < CV_32F) if (1) { cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255)); cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255)); } else { const int fscale = 256; // avoid bits near ULP, generate stable test input Mat in_mat32s(in_mat1.size(), CV_MAKE_TYPE(CV_32S, CV_MAT_CN(type))); cv::randu(in_mat32s, cv::Scalar::all(0), cv::Scalar::all(255 * fscale)); in_mat32s.convertTo(in_mat1, type, 1.0f / fscale, 0); cv::randu(in_mat32s, cv::Scalar::all(0), cv::Scalar::all(255 * fscale)); in_mat32s.convertTo(in_mat2, type, 1.0f / fscale, 0); } if (createOutputMatrices) { initOutMats(sz_in, dtype); } } void initMatrixRandU(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true) { in_mat1 = cv::Mat(sz_in, type); int sdepth = CV_MAT_DEPTH(type); int ddepth = (dtype >= 0) ? CV_MAT_DEPTH(dtype) : sdepth; // dtype == -1 <=> dtype == SAME_TYPE if ((sdepth >= CV_32F) || (ddepth >= CV_32F)) { sc = initScalarRandU(); } else { switch (sdepth) { case CV_8U: sc = initScalarRandU(UCHAR_MAX + 1U); break; case CV_16U: sc = initScalarRandU(USHRT_MAX + 1U); break; case CV_16S: sc = initScalarRandU(SHRT_MAX + 1U); break; default: sc = initScalarRandU(SCHAR_MAX + 1U); break; } } if (CV_MAT_DEPTH(type) < CV_32F) { cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255)); } else { const int fscale = 256; // avoid bits near ULP, generate stable test input Mat in_mat32s(in_mat1.size(), CV_MAKE_TYPE(CV_32S, CV_MAT_CN(type))); cv::randu(in_mat32s, cv::Scalar::all(0), cv::Scalar::all(255 * fscale)); in_mat32s.convertTo(in_mat1, type, 1.0f / fscale, 0); } if (createOutputMatrices) { initOutMats(sz_in, dtype); } } void initMatrixRandN(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true) { in_mat1 = cv::Mat(sz_in, type); cv::randn(in_mat1, cv::Scalar::all(127), cv::Scalar::all(40.f)); if (createOutputMatrices) { initOutMats(sz_in, dtype); } } 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); } } 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); } } template 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>/std::vector> template class Pt> void initPointsVectorRandU(const int sz_in, std::vector> &vec_) { cv::RNG& rng = theRNG(); vec_.clear(); vec_.reserve(sz_in); for (int i = 0; i < sz_in; i++) { Pt pt; initPointRandU(rng, pt); vec_.emplace_back(pt); } } #if defined _MSC_VER && _MSC_VER < 1910 /*MSVS 2017*/ #pragma warning(pop) #endif template inline void initMatByPointsVectorRandU(const cv::Size &sz_in) { std::vector in_vector; initPointsVectorRandU(sz_in.width, in_vector); in_mat1 = cv::Mat(in_vector, true); } // initialize Mat by a vector of Points template