add part of opencv

This commit is contained in:
Tang1705
2020-01-27 20:20:56 +08:00
parent 0c4ac1d8bb
commit a71fa47620
6518 changed files with 3122580 additions and 0 deletions

View File

@@ -0,0 +1,321 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/ts/cuda_perf.hpp"
#include "opencv2/core/cuda.hpp"
using namespace cv;
using namespace std;
namespace perf
{
Mat readImage(const string& fileName, int flags)
{
return imread(perf::TestBase::getDataPath(fileName), flags);
}
void PrintTo(const CvtColorInfo& info, std::ostream* os)
{
static const char* str[] =
{
"BGR2BGRA",
"BGRA2BGR",
"BGR2RGBA",
"RGBA2BGR",
"BGR2RGB",
"BGRA2RGBA",
"BGR2GRAY",
"RGB2GRAY",
"GRAY2BGR",
"GRAY2BGRA",
"BGRA2GRAY",
"RGBA2GRAY",
"BGR2BGR565",
"RGB2BGR565",
"BGR5652BGR",
"BGR5652RGB",
"BGRA2BGR565",
"RGBA2BGR565",
"BGR5652BGRA",
"BGR5652RGBA",
"GRAY2BGR565",
"BGR5652GRAY",
"BGR2BGR555",
"RGB2BGR555",
"BGR5552BGR",
"BGR5552RGB",
"BGRA2BGR555",
"RGBA2BGR555",
"BGR5552BGRA",
"BGR5552RGBA",
"GRAY2BGR555",
"BGR5552GRAY",
"BGR2XYZ",
"RGB2XYZ",
"XYZ2BGR",
"XYZ2RGB",
"BGR2YCrCb",
"RGB2YCrCb",
"YCrCb2BGR",
"YCrCb2RGB",
"BGR2HSV",
"RGB2HSV",
"",
"",
"BGR2Lab",
"RGB2Lab",
"BayerBG2BGR",
"BayerGB2BGR",
"BayerRG2BGR",
"BayerGR2BGR",
"BGR2Luv",
"RGB2Luv",
"BGR2HLS",
"RGB2HLS",
"HSV2BGR",
"HSV2RGB",
"Lab2BGR",
"Lab2RGB",
"Luv2BGR",
"Luv2RGB",
"HLS2BGR",
"HLS2RGB",
"BayerBG2BGR_VNG",
"BayerGB2BGR_VNG",
"BayerRG2BGR_VNG",
"BayerGR2BGR_VNG",
"BGR2HSV_FULL",
"RGB2HSV_FULL",
"BGR2HLS_FULL",
"RGB2HLS_FULL",
"HSV2BGR_FULL",
"HSV2RGB_FULL",
"HLS2BGR_FULL",
"HLS2RGB_FULL",
"LBGR2Lab",
"LRGB2Lab",
"LBGR2Luv",
"LRGB2Luv",
"Lab2LBGR",
"Lab2LRGB",
"Luv2LBGR",
"Luv2LRGB",
"BGR2YUV",
"RGB2YUV",
"YUV2BGR",
"YUV2RGB",
"BayerBG2GRAY",
"BayerGB2GRAY",
"BayerRG2GRAY",
"BayerGR2GRAY",
//YUV 4:2:0 formats family
"YUV2RGB_NV12",
"YUV2BGR_NV12",
"YUV2RGB_NV21",
"YUV2BGR_NV21",
"YUV2RGBA_NV12",
"YUV2BGRA_NV12",
"YUV2RGBA_NV21",
"YUV2BGRA_NV21",
"YUV2RGB_YV12",
"YUV2BGR_YV12",
"YUV2RGB_IYUV",
"YUV2BGR_IYUV",
"YUV2RGBA_YV12",
"YUV2BGRA_YV12",
"YUV2RGBA_IYUV",
"YUV2BGRA_IYUV",
"YUV2GRAY_420",
//YUV 4:2:2 formats family
"YUV2RGB_UYVY",
"YUV2BGR_UYVY",
"YUV2RGB_VYUY",
"YUV2BGR_VYUY",
"YUV2RGBA_UYVY",
"YUV2BGRA_UYVY",
"YUV2RGBA_VYUY",
"YUV2BGRA_VYUY",
"YUV2RGB_YUY2",
"YUV2BGR_YUY2",
"YUV2RGB_YVYU",
"YUV2BGR_YVYU",
"YUV2RGBA_YUY2",
"YUV2BGRA_YUY2",
"YUV2RGBA_YVYU",
"YUV2BGRA_YVYU",
"YUV2GRAY_UYVY",
"YUV2GRAY_YUY2",
// alpha premultiplication
"RGBA2mRGBA",
"mRGBA2RGBA",
"COLORCVT_MAX"
};
*os << str[info.code];
}
static void printOsInfo()
{
#if defined _WIN32
# if defined _WIN64
printf("[----------]\n[ GPU INFO ] \tRun on OS Windows x64.\n[----------]\n"), fflush(stdout);
# else
printf("[----------]\n[ GPU INFO ] \tRun on OS Windows x32.\n[----------]\n"), fflush(stdout);
# endif
#elif defined __ANDROID__
# if defined _LP64 || defined __LP64__
printf("[----------]\n[ GPU INFO ] \tRun on OS Android x64.\n[----------]\n"), fflush(stdout);
# else
printf("[----------]\n[ GPU INFO ] \tRun on OS Android x32.\n[----------]\n"), fflush(stdout);
# endif
#elif defined __APPLE__
# if defined _LP64 || defined __LP64__
printf("[----------]\n[ GPU INFO ] \tRun on OS Apple x64.\n[----------]\n"), fflush(stdout);
# else
printf("[----------]\n[ GPU INFO ] \tRun on OS Apple x32.\n[----------]\n"), fflush(stdout);
# endif
#elif defined linux
# if defined _LP64 || defined __LP64__
printf("[----------]\n[ GPU INFO ] \tRun on OS Linux x64.\n[----------]\n"), fflush(stdout);
# else
printf("[----------]\n[ GPU INFO ] \tRun on OS Linux x32.\n[----------]\n"), fflush(stdout);
# endif
#endif
}
void printCudaInfo()
{
printOsInfo();
for (int i = 0; i < cv::cuda::getCudaEnabledDeviceCount(); i++)
cv::cuda::printCudaDeviceInfo(i);
}
struct KeypointIdxCompare
{
std::vector<cv::KeyPoint>* keypoints;
explicit KeypointIdxCompare(std::vector<cv::KeyPoint>* _keypoints) : keypoints(_keypoints) {}
bool operator ()(size_t i1, size_t i2) const
{
cv::KeyPoint kp1 = (*keypoints)[i1];
cv::KeyPoint kp2 = (*keypoints)[i2];
if (kp1.pt.x != kp2.pt.x)
return kp1.pt.x < kp2.pt.x;
if (kp1.pt.y != kp2.pt.y)
return kp1.pt.y < kp2.pt.y;
if (kp1.response != kp2.response)
return kp1.response < kp2.response;
return kp1.octave < kp2.octave;
}
};
void sortKeyPoints(std::vector<cv::KeyPoint>& keypoints, cv::InputOutputArray _descriptors)
{
std::vector<size_t> indexies(keypoints.size());
for (size_t i = 0; i < indexies.size(); ++i)
indexies[i] = i;
std::sort(indexies.begin(), indexies.end(), KeypointIdxCompare(&keypoints));
std::vector<cv::KeyPoint> new_keypoints;
cv::Mat new_descriptors;
new_keypoints.resize(keypoints.size());
cv::Mat descriptors;
if (_descriptors.needed())
{
descriptors = _descriptors.getMat();
new_descriptors.create(descriptors.size(), descriptors.type());
}
for (size_t i = 0; i < indexies.size(); ++i)
{
size_t new_idx = indexies[i];
new_keypoints[i] = keypoints[new_idx];
if (!new_descriptors.empty())
descriptors.row((int) new_idx).copyTo(new_descriptors.row((int) i));
}
keypoints.swap(new_keypoints);
if (_descriptors.needed())
new_descriptors.copyTo(_descriptors);
}
}

View File

@@ -0,0 +1,560 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/ts/cuda_test.hpp"
#include <stdexcept>
using namespace cv;
using namespace cv::cuda;
using namespace cvtest;
using namespace testing;
using namespace testing::internal;
namespace perf
{
void printCudaInfo();
}
namespace cvtest
{
//////////////////////////////////////////////////////////////////////
// random generators
int randomInt(int minVal, int maxVal)
{
RNG& rng = TS::ptr()->get_rng();
return rng.uniform(minVal, maxVal);
}
double randomDouble(double minVal, double maxVal)
{
RNG& rng = TS::ptr()->get_rng();
return rng.uniform(minVal, maxVal);
}
Size randomSize(int minVal, int maxVal)
{
return Size(randomInt(minVal, maxVal), randomInt(minVal, maxVal));
}
Scalar randomScalar(double minVal, double maxVal)
{
return Scalar(randomDouble(minVal, maxVal), randomDouble(minVal, maxVal), randomDouble(minVal, maxVal), randomDouble(minVal, maxVal));
}
Mat randomMat(Size size, int type, double minVal, double maxVal)
{
return randomMat(TS::ptr()->get_rng(), size, type, minVal, maxVal, false);
}
//////////////////////////////////////////////////////////////////////
// GpuMat create
GpuMat createMat(Size size, int type, bool useRoi)
{
Size size0 = size;
if (useRoi)
{
size0.width += randomInt(5, 15);
size0.height += randomInt(5, 15);
}
GpuMat d_m(size0, type);
if (size0 != size)
d_m = d_m(Rect((size0.width - size.width) / 2, (size0.height - size.height) / 2, size.width, size.height));
return d_m;
}
GpuMat loadMat(const Mat& m, bool useRoi)
{
GpuMat d_m = createMat(m.size(), m.type(), useRoi);
d_m.upload(m);
return d_m;
}
//////////////////////////////////////////////////////////////////////
// Image load
Mat readImage(const std::string& fileName, int flags)
{
return imread(TS::ptr()->get_data_path() + fileName, flags);
}
Mat readImageType(const std::string& fname, int type)
{
Mat src = readImage(fname, CV_MAT_CN(type) == 1 ? IMREAD_GRAYSCALE : IMREAD_COLOR);
if (CV_MAT_CN(type) == 4)
{
Mat temp;
cvtColor(src, temp, COLOR_BGR2BGRA);
swap(src, temp);
}
src.convertTo(src, CV_MAT_DEPTH(type), CV_MAT_DEPTH(type) == CV_32F ? 1.0 / 255.0 : 1.0);
return src;
}
//////////////////////////////////////////////////////////////////////
// Gpu devices
bool supportFeature(const DeviceInfo& info, FeatureSet feature)
{
return TargetArchs::builtWith(feature) && info.supports(feature);
}
DeviceManager& DeviceManager::instance()
{
static DeviceManager obj;
return obj;
}
void DeviceManager::load(int i)
{
devices_.clear();
devices_.reserve(1);
std::ostringstream msg;
if (i < 0 || i >= getCudaEnabledDeviceCount())
{
msg << "Incorrect device number - " << i;
throw std::runtime_error(msg.str());
}
DeviceInfo info(i);
if (!info.isCompatible())
{
msg << "Device " << i << " [" << info.name() << "] is NOT compatible with current CUDA module build";
throw std::runtime_error(msg.str());
}
devices_.push_back(info);
}
void DeviceManager::loadAll()
{
int deviceCount = getCudaEnabledDeviceCount();
devices_.clear();
devices_.reserve(deviceCount);
for (int i = 0; i < deviceCount; ++i)
{
DeviceInfo info(i);
if (info.isCompatible())
{
devices_.push_back(info);
}
}
}
void parseCudaDeviceOptions(int argc, char **argv)
{
cv::CommandLineParser cmd(argc, argv,
"{ cuda_device | -1 | CUDA device on which tests will be executed (-1 means all devices) }"
"{ h help | false | Print help info }"
);
if (cmd.has("help"))
{
std::cout << "\nAvailable options besides google test option: \n";
cmd.printMessage();
}
int device = cmd.get<int>("cuda_device");
if (device < 0)
{
cvtest::DeviceManager::instance().loadAll();
std::cout << "Run tests on all supported CUDA devices \n" << std::endl;
}
else
{
cvtest::DeviceManager::instance().load(device);
cv::cuda::DeviceInfo info(device);
std::cout << "Run tests on CUDA device " << device << " [" << info.name() << "] \n" << std::endl;
}
}
//////////////////////////////////////////////////////////////////////
// Additional assertion
namespace
{
template <typename T, typename OutT> std::string printMatValImpl(const Mat& m, Point p)
{
const int cn = m.channels();
std::ostringstream ostr;
ostr << "(";
p.x /= cn;
ostr << static_cast<OutT>(m.at<T>(p.y, p.x * cn));
for (int c = 1; c < m.channels(); ++c)
{
ostr << ", " << static_cast<OutT>(m.at<T>(p.y, p.x * cn + c));
}
ostr << ")";
return ostr.str();
}
std::string printMatVal(const Mat& m, Point p)
{
typedef std::string (*func_t)(const Mat& m, Point p);
static const func_t funcs[] =
{
printMatValImpl<uchar, int>, printMatValImpl<schar, int>, printMatValImpl<ushort, int>, printMatValImpl<short, int>,
printMatValImpl<int, int>, printMatValImpl<float, float>, printMatValImpl<double, double>
};
return funcs[m.depth()](m, p);
}
}
void minMaxLocGold(const Mat& src, double* minVal_, double* maxVal_, Point* minLoc_, Point* maxLoc_, const Mat& mask)
{
if (src.depth() != CV_8S)
{
minMaxLoc(src, minVal_, maxVal_, minLoc_, maxLoc_, mask);
return;
}
// OpenCV's minMaxLoc doesn't support CV_8S type
double minVal = std::numeric_limits<double>::max();
Point minLoc(-1, -1);
double maxVal = -std::numeric_limits<double>::max();
Point maxLoc(-1, -1);
for (int y = 0; y < src.rows; ++y)
{
const schar* src_row = src.ptr<schar>(y);
const uchar* mask_row = mask.empty() ? 0 : mask.ptr<uchar>(y);
for (int x = 0; x < src.cols; ++x)
{
if (!mask_row || mask_row[x])
{
schar val = src_row[x];
if (val < minVal)
{
minVal = val;
minLoc = cv::Point(x, y);
}
if (val > maxVal)
{
maxVal = val;
maxLoc = cv::Point(x, y);
}
}
}
}
if (minVal_) *minVal_ = minVal;
if (maxVal_) *maxVal_ = maxVal;
if (minLoc_) *minLoc_ = minLoc;
if (maxLoc_) *maxLoc_ = maxLoc;
}
Mat getMat(InputArray arr)
{
if (arr.kind() == _InputArray::CUDA_GPU_MAT)
{
Mat m;
arr.getGpuMat().download(m);
return m;
}
return arr.getMat();
}
AssertionResult assertMatNear(const char* expr1, const char* expr2, const char* eps_expr, InputArray m1_, InputArray m2_, double eps)
{
Mat m1 = getMat(m1_);
Mat m2 = getMat(m2_);
if (m1.size() != m2.size())
{
std::stringstream msg;
msg << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different sizes : \""
<< expr1 << "\" [" << PrintToString(m1.size()) << "] vs \""
<< expr2 << "\" [" << PrintToString(m2.size()) << "]";
return AssertionFailure() << msg.str();
}
if (m1.type() != m2.type())
{
std::stringstream msg;
msg << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different types : \""
<< expr1 << "\" [" << PrintToString(MatType(m1.type())) << "] vs \""
<< expr2 << "\" [" << PrintToString(MatType(m2.type())) << "]";
return AssertionFailure() << msg.str();
}
Mat diff;
absdiff(m1.reshape(1), m2.reshape(1), diff);
double maxVal = 0.0;
Point maxLoc;
minMaxLocGold(diff, 0, &maxVal, 0, &maxLoc);
if (maxVal > eps)
{
std::stringstream msg;
msg << "The max difference between matrices \"" << expr1 << "\" and \"" << expr2
<< "\" is " << maxVal << " at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ")"
<< ", which exceeds \"" << eps_expr << "\", where \""
<< expr1 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m1, maxLoc) << ", \""
<< expr2 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m2, maxLoc) << ", \""
<< eps_expr << "\" evaluates to " << eps;
return AssertionFailure() << msg.str();
}
return AssertionSuccess();
}
double checkSimilarity(InputArray m1, InputArray m2)
{
Mat diff;
matchTemplate(getMat(m1), getMat(m2), diff, TM_CCORR_NORMED);
return std::abs(diff.at<float>(0, 0) - 1.f);
}
//////////////////////////////////////////////////////////////////////
// Helper structs for value-parameterized tests
vector<MatType> types(int depth_start, int depth_end, int cn_start, int cn_end)
{
vector<MatType> v;
v.reserve((depth_end - depth_start + 1) * (cn_end - cn_start + 1));
for (int depth = depth_start; depth <= depth_end; ++depth)
{
for (int cn = cn_start; cn <= cn_end; ++cn)
{
v.push_back(MatType(CV_MAKE_TYPE(depth, cn)));
}
}
return v;
}
const vector<MatType>& all_types()
{
static vector<MatType> v = types(CV_8U, CV_64F, 1, 4);
return v;
}
void PrintTo(const UseRoi& useRoi, std::ostream* os)
{
if (useRoi)
(*os) << "sub matrix";
else
(*os) << "whole matrix";
}
void PrintTo(const Inverse& inverse, std::ostream* os)
{
if (inverse)
(*os) << "inverse";
else
(*os) << "direct";
}
//////////////////////////////////////////////////////////////////////
// Other
void dumpImage(const std::string& fileName, const Mat& image)
{
imwrite(TS::ptr()->get_data_path() + fileName, image);
}
void showDiff(InputArray gold_, InputArray actual_, double eps)
{
Mat gold = getMat(gold_);
Mat actual = getMat(actual_);
Mat diff;
absdiff(gold, actual, diff);
threshold(diff, diff, eps, 255.0, cv::THRESH_BINARY);
namedWindow("gold", WINDOW_NORMAL);
namedWindow("actual", WINDOW_NORMAL);
namedWindow("diff", WINDOW_NORMAL);
imshow("gold", gold);
imshow("actual", actual);
imshow("diff", diff);
waitKey();
}
namespace
{
bool keyPointsEquals(const cv::KeyPoint& p1, const cv::KeyPoint& p2)
{
const double maxPtDif = 1.0;
const double maxSizeDif = 1.0;
const double maxAngleDif = 2.0;
const double maxResponseDif = 0.1;
double dist = cv::norm(p1.pt - p2.pt);
if (dist < maxPtDif &&
fabs(p1.size - p2.size) < maxSizeDif &&
abs(p1.angle - p2.angle) < maxAngleDif &&
abs(p1.response - p2.response) < maxResponseDif &&
p1.octave == p2.octave &&
p1.class_id == p2.class_id)
{
return true;
}
return false;
}
struct KeyPointLess
{
bool operator()(const cv::KeyPoint& kp1, const cv::KeyPoint& kp2) const
{
return kp1.pt.y < kp2.pt.y || (kp1.pt.y == kp2.pt.y && kp1.pt.x < kp2.pt.x);
}
};
}
testing::AssertionResult assertKeyPointsEquals(const char* gold_expr, const char* actual_expr, std::vector<cv::KeyPoint>& gold, std::vector<cv::KeyPoint>& actual)
{
if (gold.size() != actual.size())
{
std::stringstream msg;
msg << "KeyPoints size mistmach\n"
<< "\"" << gold_expr << "\" : " << gold.size() << "\n"
<< "\"" << actual_expr << "\" : " << actual.size();
return AssertionFailure() << msg.str();
}
std::sort(actual.begin(), actual.end(), KeyPointLess());
std::sort(gold.begin(), gold.end(), KeyPointLess());
for (size_t i = 0; i < gold.size(); ++i)
{
const cv::KeyPoint& p1 = gold[i];
const cv::KeyPoint& p2 = actual[i];
if (!keyPointsEquals(p1, p2))
{
std::stringstream msg;
msg << "KeyPoints differ at " << i << "\n"
<< "\"" << gold_expr << "\" vs \"" << actual_expr << "\" : \n"
<< "pt : " << testing::PrintToString(p1.pt) << " vs " << testing::PrintToString(p2.pt) << "\n"
<< "size : " << p1.size << " vs " << p2.size << "\n"
<< "angle : " << p1.angle << " vs " << p2.angle << "\n"
<< "response : " << p1.response << " vs " << p2.response << "\n"
<< "octave : " << p1.octave << " vs " << p2.octave << "\n"
<< "class_id : " << p1.class_id << " vs " << p2.class_id;
return AssertionFailure() << msg.str();
}
}
return ::testing::AssertionSuccess();
}
int getMatchedPointsCount(std::vector<cv::KeyPoint>& gold, std::vector<cv::KeyPoint>& actual)
{
std::sort(actual.begin(), actual.end(), KeyPointLess());
std::sort(gold.begin(), gold.end(), KeyPointLess());
int validCount = 0;
for (size_t i = 0; i < gold.size(); ++i)
{
const cv::KeyPoint& p1 = gold[i];
const cv::KeyPoint& p2 = actual[i];
if (keyPointsEquals(p1, p2))
++validCount;
}
return validCount;
}
int getMatchedPointsCount(const std::vector<cv::KeyPoint>& keypoints1, const std::vector<cv::KeyPoint>& keypoints2, const std::vector<cv::DMatch>& matches)
{
int validCount = 0;
for (size_t i = 0; i < matches.size(); ++i)
{
const cv::DMatch& m = matches[i];
const cv::KeyPoint& p1 = keypoints1[m.queryIdx];
const cv::KeyPoint& p2 = keypoints2[m.trainIdx];
if (keyPointsEquals(p1, p2))
++validCount;
}
return validCount;
}
void printCudaInfo()
{
perf::printCudaInfo();
}
}
void cv::cuda::PrintTo(const DeviceInfo& info, std::ostream* os)
{
(*os) << info.name();
if (info.deviceID())
(*os) << " [ID: " << info.deviceID() << "]";
}

View File

@@ -0,0 +1,83 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
namespace cvtest {
namespace ocl {
namespace perf {
void checkDeviceMaxMemoryAllocSize(const Size& size, int type, int factor)
{
assert(factor > 0);
if (!cv::ocl::useOpenCL())
return;
size_t memSize = size.area() * CV_ELEM_SIZE(type);
const cv::ocl::Device& dev = cv::ocl::Device::getDefault();
if (memSize * factor >= dev.maxMemAllocSize())
throw ::perf::TestBase::PerfSkipTestException();
}
void randu(InputOutputArray dst)
{
if (dst.depth() == CV_8U)
cv::randu(dst, 0, 256);
else if (dst.depth() == CV_8S)
cv::randu(dst, -128, 128);
else if (dst.depth() == CV_16U)
cv::randu(dst, 0, 1024);
else if (dst.depth() == CV_32F || dst.depth() == CV_64F)
cv::randu(dst, -1.0, 1.0);
else if (dst.depth() == CV_16S || dst.depth() == CV_32S)
cv::randu(dst, -4096, 4096);
else
CV_Error(Error::StsUnsupportedFormat, "Unsupported format");
}
} // namespace perf
} } // namespace cvtest::ocl

View File

@@ -0,0 +1,162 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
namespace cvtest {
namespace ocl {
using namespace cv;
int test_loop_times = 1; // TODO Read from command line / environment
Mat TestUtils::readImage(const String &fileName, int flags)
{
return cv::imread(cvtest::TS::ptr()->get_data_path() + fileName, flags);
}
Mat TestUtils::readImageType(const String &fname, int type)
{
Mat src = readImage(fname, CV_MAT_CN(type) == 1 ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
if (CV_MAT_CN(type) == 4)
{
Mat temp;
cv::cvtColor(src, temp, cv::COLOR_BGR2BGRA);
swap(src, temp);
}
src.convertTo(src, CV_MAT_DEPTH(type));
return src;
}
double TestUtils::checkNorm1(InputArray m, InputArray mask)
{
return cvtest::norm(m.getMat(), NORM_INF, mask.getMat());
}
double TestUtils::checkNorm2(InputArray m1, InputArray m2, InputArray mask)
{
return cvtest::norm(m1.getMat(), m2.getMat(), NORM_INF, mask.getMat());
}
double TestUtils::checkSimilarity(InputArray m1, InputArray m2)
{
Mat diff;
matchTemplate(m1.getMat(), m2.getMat(), diff, CV_TM_CCORR_NORMED);
return std::abs(diff.at<float>(0, 0) - 1.f);
}
double TestUtils::checkRectSimilarity(const Size & sz, std::vector<Rect>& ob1, std::vector<Rect>& ob2)
{
double final_test_result = 0.0;
size_t sz1 = ob1.size();
size_t sz2 = ob2.size();
if (sz1 != sz2)
return sz1 > sz2 ? (double)(sz1 - sz2) : (double)(sz2 - sz1);
else
{
if (sz1 == 0 && sz2 == 0)
return 0;
cv::Mat cpu_result(sz, CV_8UC1);
cpu_result.setTo(0);
for (vector<Rect>::const_iterator r = ob1.begin(); r != ob1.end(); ++r)
{
cv::Mat cpu_result_roi(cpu_result, *r);
cpu_result_roi.setTo(1);
cpu_result.copyTo(cpu_result);
}
int cpu_area = cv::countNonZero(cpu_result > 0);
cv::Mat gpu_result(sz, CV_8UC1);
gpu_result.setTo(0);
for(vector<Rect>::const_iterator r2 = ob2.begin(); r2 != ob2.end(); ++r2)
{
cv::Mat gpu_result_roi(gpu_result, *r2);
gpu_result_roi.setTo(1);
gpu_result.copyTo(gpu_result);
}
cv::Mat result_;
multiply(cpu_result, gpu_result, result_);
int result = cv::countNonZero(result_ > 0);
if (cpu_area!=0 && result!=0)
final_test_result = 1.0 - (double)result/(double)cpu_area;
else if(cpu_area==0 && result!=0)
final_test_result = -1;
}
return final_test_result;
}
void TestUtils::showDiff(InputArray _src, InputArray _gold, InputArray _actual, double eps, bool alwaysShow)
{
Mat src = _src.getMat(), actual = _actual.getMat(), gold = _gold.getMat();
Mat diff, diff_thresh;
absdiff(gold, actual, diff);
diff.convertTo(diff, CV_32F);
threshold(diff, diff_thresh, eps, 255.0, cv::THRESH_BINARY);
if (alwaysShow || cv::countNonZero(diff_thresh.reshape(1)) > 0)
{
#if 0
std::cout << "Source: " << std::endl << src << std::endl;
std::cout << "Expected: " << std::endl << gold << std::endl;
std::cout << "Actual: " << std::endl << actual << std::endl;
#endif
namedWindow("src", WINDOW_NORMAL);
namedWindow("gold", WINDOW_NORMAL);
namedWindow("actual", WINDOW_NORMAL);
namedWindow("diff", WINDOW_NORMAL);
imshow("src", src);
imshow("gold", gold);
imshow("actual", actual);
imshow("diff", diff);
cv::waitKey();
}
}
} } // namespace cvtest::ocl

View File

@@ -0,0 +1,8 @@
#include "opencv2/ts.hpp"
#include <opencv2/core/utils/logger.hpp>
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#ifdef GTEST_LINKED_AS_SHARED_LIBRARY
#error ts module should not have GTEST_LINKED_AS_SHARED_LIBRARY defined
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,337 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/core/core_c.h"
namespace cvtest
{
static const int default_test_case_count = 500;
static const int default_max_log_array_size = 9;
ArrayTest::ArrayTest()
{
test_case_count = default_test_case_count;
iplimage_allowed = true;
cvmat_allowed = true;
optional_mask = false;
min_log_array_size = 0;
max_log_array_size = default_max_log_array_size;
element_wise_relative_error = true;
test_array.resize(MAX_ARR);
}
ArrayTest::~ArrayTest()
{
clear();
}
void ArrayTest::clear()
{
for( size_t i = 0; i < test_array.size(); i++ )
{
for( size_t j = 0; j < test_array[i].size(); j++ )
cvRelease( &test_array[i][j] );
}
BaseTest::clear();
}
int ArrayTest::read_params( const cv::FileStorage& fs )
{
int code = BaseTest::read_params( fs );
if( code < 0 )
return code;
read( find_param( fs, "min_log_array_size" ), min_log_array_size, min_log_array_size );
read( find_param( fs, "max_log_array_size" ), max_log_array_size, max_log_array_size );
read( find_param( fs, "test_case_count" ), test_case_count, test_case_count );
test_case_count = cvRound( test_case_count*ts->get_test_case_count_scale() );
min_log_array_size = clipInt( min_log_array_size, 0, 20 );
max_log_array_size = clipInt( max_log_array_size, min_log_array_size, 20 );
test_case_count = clipInt( test_case_count, 0, 100000 );
return code;
}
void ArrayTest::get_test_array_types_and_sizes( int /*test_case_idx*/, vector<vector<Size> >& sizes, vector<vector<int> >& types )
{
RNG& rng = ts->get_rng();
Size size;
double val;
size_t i, j;
val = randReal(rng) * (max_log_array_size - min_log_array_size) + min_log_array_size;
size.width = cvRound( exp(val*CV_LOG2) );
val = randReal(rng) * (max_log_array_size - min_log_array_size) + min_log_array_size;
size.height = cvRound( exp(val*CV_LOG2) );
for( i = 0; i < test_array.size(); i++ )
{
size_t sizei = test_array[i].size();
for( j = 0; j < sizei; j++ )
{
sizes[i][j] = size;
types[i][j] = CV_8UC1;
}
}
}
static const unsigned int icvTsTypeToDepth[] =
{
IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F
};
int ArrayTest::prepare_test_case( int test_case_idx )
{
int code = 1;
size_t max_arr = test_array.size();
vector<vector<Size> > sizes(max_arr);
vector<vector<Size> > whole_sizes(max_arr);
vector<vector<int> > types(max_arr);
size_t i, j;
RNG& rng = ts->get_rng();
bool is_image = false;
for( i = 0; i < max_arr; i++ )
{
size_t sizei = std::max(test_array[i].size(), (size_t)1);
sizes[i].resize(sizei);
types[i].resize(sizei);
whole_sizes[i].resize(sizei);
}
get_test_array_types_and_sizes( test_case_idx, sizes, types );
for( i = 0; i < max_arr; i++ )
{
size_t sizei = test_array[i].size();
for( j = 0; j < sizei; j++ )
{
unsigned t = randInt(rng);
bool create_mask = true, use_roi = false;
CvSize size = cvSize(sizes[i][j]), whole_size = size;
CvRect roi = CV_STRUCT_INITIALIZER;
is_image = !cvmat_allowed ? true : iplimage_allowed ? (t & 1) != 0 : false;
create_mask = (t & 6) == 0; // ~ each of 3 tests will use mask
use_roi = (t & 8) != 0;
if( use_roi )
{
whole_size.width += randInt(rng) % 10;
whole_size.height += randInt(rng) % 10;
}
cvRelease( &test_array[i][j] );
if( size.width > 0 && size.height > 0 &&
types[i][j] >= 0 && (i != MASK || create_mask) )
{
if( use_roi )
{
roi.width = size.width;
roi.height = size.height;
if( whole_size.width > size.width )
roi.x = randInt(rng) % (whole_size.width - size.width);
if( whole_size.height > size.height )
roi.y = randInt(rng) % (whole_size.height - size.height);
}
if( is_image )
{
test_array[i][j] = cvCreateImage( whole_size,
icvTsTypeToDepth[CV_MAT_DEPTH(types[i][j])], CV_MAT_CN(types[i][j]) );
if( use_roi )
cvSetImageROI( (IplImage*)test_array[i][j], roi );
}
else
{
test_array[i][j] = cvCreateMat( whole_size.height, whole_size.width, types[i][j] );
if( use_roi )
{
CvMat submat, *mat = (CvMat*)test_array[i][j];
cvGetSubRect( test_array[i][j], &submat, roi );
submat.refcount = mat->refcount;
*mat = submat;
}
}
}
}
}
test_mat.resize(test_array.size());
for( i = 0; i < max_arr; i++ )
{
size_t sizei = test_array[i].size();
test_mat[i].resize(sizei);
for( j = 0; j < sizei; j++ )
{
CvArr* arr = test_array[i][j];
test_mat[i][j] = cv::cvarrToMat(arr);
if( !test_mat[i][j].empty() )
fill_array( test_case_idx, (int)i, (int)j, test_mat[i][j] );
}
}
return code;
}
void ArrayTest::get_minmax_bounds( int i, int /*j*/, int type, Scalar& low, Scalar& high )
{
double l, u;
int depth = CV_MAT_DEPTH(type);
if( i == MASK )
{
l = -2;
u = 2;
}
else if( depth < CV_32S )
{
l = getMinVal(type);
u = getMaxVal(type);
}
else
{
u = depth == CV_32S ? 1000000 : 1000.;
l = -u;
}
low = Scalar::all(l);
high = Scalar::all(u);
}
void ArrayTest::fill_array( int /*test_case_idx*/, int i, int j, Mat& arr )
{
if( i == REF_INPUT_OUTPUT )
cvtest::copy( test_mat[INPUT_OUTPUT][j], arr, Mat() );
else if( i == INPUT || i == INPUT_OUTPUT || i == MASK )
{
Scalar low, high;
get_minmax_bounds( i, j, arr.type(), low, high );
randUni( ts->get_rng(), arr, low, high );
}
}
double ArrayTest::get_success_error_level( int /*test_case_idx*/, int i, int j )
{
int elem_depth = CV_MAT_DEPTH(cvGetElemType(test_array[i][j]));
assert( i == OUTPUT || i == INPUT_OUTPUT );
return elem_depth < CV_32F ? 0 : elem_depth == CV_32F ? FLT_EPSILON*100: DBL_EPSILON*5000;
}
void ArrayTest::prepare_to_validation( int /*test_case_idx*/ )
{
assert(0);
}
int ArrayTest::validate_test_results( int test_case_idx )
{
static const char* arr_names[] = { "input", "input/output", "output",
"ref input/output", "ref output",
"temporary", "mask" };
size_t i, j;
prepare_to_validation( test_case_idx );
for( i = 0; i < 2; i++ )
{
int i0 = i == 0 ? OUTPUT : INPUT_OUTPUT;
int i1 = i == 0 ? REF_OUTPUT : REF_INPUT_OUTPUT;
size_t sizei = test_array[i0].size();
assert( sizei == test_array[i1].size() );
for( j = 0; j < sizei; j++ )
{
double err_level;
int code;
if( !test_array[i1][j] )
continue;
err_level = get_success_error_level( test_case_idx, i0, (int)j );
code = cmpEps2(ts, test_mat[i0][j], test_mat[i1][j], err_level, element_wise_relative_error, arr_names[i0]);
if (code == 0) continue;
for( i0 = 0; i0 < (int)test_array.size(); i0++ )
{
size_t sizei0 = test_array[i0].size();
if( i0 == REF_INPUT_OUTPUT || i0 == OUTPUT || i0 == TEMP )
continue;
for( i1 = 0; i1 < (int)sizei0; i1++ )
{
const Mat& arr = test_mat[i0][i1];
if( !arr.empty() )
{
string sizestr = vec2str(", ", &arr.size[0], arr.dims);
ts->printf( TS::LOG, "%s array %d type=%sC%d, size=(%s)\n",
arr_names[i0], i1, getTypeName(arr.depth()),
arr.channels(), sizestr.c_str() );
}
}
}
ts->set_failed_test_info( code );
return code;
}
}
return 0;
}
}
/* End of file. */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,539 @@
// 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.
#include "precomp.hpp"
#include "ts_tags.hpp"
namespace cvtest {
static bool printTestTag = false;
static std::vector<std::string> currentDirectTestTags, currentImpliedTestTags;
static std::vector<const ::testing::TestInfo*> skipped_tests;
static std::map<std::string, int>& getTestTagsSkipCounts()
{
static std::map<std::string, int> testTagsSkipCounts;
return testTagsSkipCounts;
}
static std::map<std::string, int>& getTestTagsSkipExtraCounts()
{
static std::map<std::string, int> testTagsSkipExtraCounts;
return testTagsSkipExtraCounts;
}
void testTagIncreaseSkipCount(const std::string& tag, bool isMain, bool appendSkipTests)
{
if (appendSkipTests)
skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info());
std::map<std::string, int>& counts = isMain ? getTestTagsSkipCounts() : getTestTagsSkipExtraCounts();
std::map<std::string, int>::iterator i = counts.find(tag);
if (i == counts.end())
{
counts[tag] = 1;
}
else
{
i->second++;
}
}
static std::vector<std::string>& getTestTagsSkipList()
{
static std::vector<std::string> testSkipWithTags;
static bool initialized = false;
if (!initialized)
{
#if OPENCV_32BIT_CONFIGURATION
testSkipWithTags.push_back(CV_TEST_TAG_MEMORY_2GB);
#else
if (!cvtest::runBigDataTests)
testSkipWithTags.push_back(CV_TEST_TAG_MEMORY_6GB);
#endif
testSkipWithTags.push_back(CV_TEST_TAG_VERYLONG);
#if defined(_DEBUG)
testSkipWithTags.push_back(CV_TEST_TAG_DEBUG_VERYLONG);
#endif
initialized = true;
}
return testSkipWithTags;
}
void registerGlobalSkipTag(const std::string& skipTag)
{
std::vector<std::string>& skipTags = getTestTagsSkipList();
for (size_t i = 0; i < skipTags.size(); ++i)
{
if (skipTag == skipTags[i])
return; // duplicate
}
skipTags.push_back(skipTag);
}
static std::vector<std::string>& getTestTagsForceList()
{
static std::vector<std::string> getTestTagsForceList;
return getTestTagsForceList;
}
static std::vector<std::string>& getTestTagsRequiredList()
{
static std::vector<std::string> getTestTagsRequiredList;
return getTestTagsRequiredList;
}
class TestTagsListener: public ::testing::EmptyTestEventListener
{
public:
void OnTestProgramStart(const ::testing::UnitTest& /*unit_test*/) CV_OVERRIDE
{
{
const std::vector<std::string>& tags = getTestTagsRequiredList();
std::ostringstream os, os_direct;
for (size_t i = 0; i < tags.size(); i++)
{
os << (i == 0 ? "'" : ", '") << tags[i] << "'";
os_direct << (i == 0 ? "" : ",") << tags[i];
}
std::string tags_str = os.str();
if (!tags.empty())
std::cout << "TEST: Run tests with tags: " << tags_str << std::endl;
::testing::Test::RecordProperty("test_tags", os_direct.str());
}
{
const std::vector<std::string>& tags = getTestTagsSkipList();
std::ostringstream os, os_direct;
for (size_t i = 0; i < tags.size(); i++)
{
os << (i == 0 ? "'" : ", '") << tags[i] << "'";
os_direct << (i == 0 ? "" : ",") << tags[i];
}
std::string tags_str = os.str();
if (!tags.empty())
std::cout << "TEST: Skip tests with tags: " << tags_str << std::endl;
::testing::Test::RecordProperty("test_tags_skip", os_direct.str());
}
{
const std::vector<std::string>& tags = getTestTagsForceList();
std::ostringstream os, os_direct;
for (size_t i = 0; i < tags.size(); i++)
{
os << (i == 0 ? "'" : ", '") << tags[i] << "'";
os_direct << (i == 0 ? "" : ",") << tags[i];
}
std::string tags_str = os.str();
if (!tags.empty())
std::cout << "TEST: Force tests with tags: " << tags_str << std::endl;
::testing::Test::RecordProperty("test_tags_force", os_direct.str());
}
}
void OnTestStart(const ::testing::TestInfo& test_info) CV_OVERRIDE
{
currentDirectTestTags.clear();
currentImpliedTestTags.clear();
const char* value_param_ = test_info.value_param();
if (value_param_)
{
std::string value_param(value_param_);
if (value_param.find("CV_64F") != std::string::npos
|| (value_param.find("64F") != std::string::npos
&& value_param.find(" 64F") != std::string::npos
&& value_param.find(",64F") != std::string::npos
&& value_param.find("(64F") != std::string::npos
)
)
applyTestTag_(CV_TEST_TAG_TYPE_64F);
if (value_param.find("1280x720") != std::string::npos)
applyTestTag_(CV_TEST_TAG_SIZE_HD);
if (value_param.find("1920x1080") != std::string::npos)
applyTestTag_(CV_TEST_TAG_SIZE_FULLHD);
if (value_param.find("3840x2160") != std::string::npos)
applyTestTag_(CV_TEST_TAG_SIZE_4K);
}
}
void OnTestEnd(const ::testing::TestInfo& /*test_info*/) CV_OVERRIDE
{
if (currentDirectTestTags.empty() && currentImpliedTestTags.empty())
{
if (printTestTag) std::cout << "[ TAGS ] No tags" << std::endl;
return;
}
std::ostringstream os;
std::ostringstream os_direct;
std::ostringstream os_implied;
{
const std::vector<std::string>& tags = currentDirectTestTags;
for (size_t i = 0; i < tags.size(); i++)
{
os << (i == 0 ? "" : ", ") << tags[i];
os_direct << (i == 0 ? "" : ",") << tags[i];
}
}
if (!currentImpliedTestTags.empty())
{
os << " (implied tags: ";
const std::vector<std::string>& tags = currentImpliedTestTags;
for (size_t i = 0; i < tags.size(); i++)
{
os << (i == 0 ? "" : ", ") << tags[i];
os_implied << (i == 0 ? "" : ",") << tags[i];
}
os << ")";
}
if (printTestTag) std::cout << "[ TAGS ] " << os.str() << std::endl;
::testing::Test::RecordProperty("tags", os_direct.str());
::testing::Test::RecordProperty("tags_implied", os_implied.str());
}
void OnTestIterationEnd(const ::testing::UnitTest& /*unit_test*/, int /*iteration*/) CV_OVERRIDE
{
if (!skipped_tests.empty())
{
std::cout << "[ SKIPSTAT ] " << skipped_tests.size() << " tests skipped" << std::endl;
const std::vector<std::string>& skipTags = getTestTagsSkipList();
const std::map<std::string, int>& counts = getTestTagsSkipCounts();
const std::map<std::string, int>& countsExtra = getTestTagsSkipExtraCounts();
std::vector<std::string> skipTags_all = skipTags;
skipTags_all.push_back("skip_bigdata");
skipTags_all.push_back("skip_other");
for (std::vector<std::string>::const_iterator i = skipTags_all.begin(); i != skipTags_all.end(); ++i)
{
int c1 = 0;
std::map<std::string, int>::const_iterator i1 = counts.find(*i);
if (i1 != counts.end()) c1 = i1->second;
int c2 = 0;
std::map<std::string, int>::const_iterator i2 = countsExtra.find(*i);
if (i2 != countsExtra.end()) c2 = i2->second;
if (c2 > 0)
{
std::cout << "[ SKIPSTAT ] TAG='" << *i << "' skip " << c1 << " tests (" << c2 << " times in extra skip list)" << std::endl;
}
else if (c1 > 0)
{
std::cout << "[ SKIPSTAT ] TAG='" << *i << "' skip " << c1 << " tests" << std::endl;
}
}
}
skipped_tests.clear();
}
void OnTestProgramEnd(const ::testing::UnitTest& /*unit_test*/) CV_OVERRIDE
{
/*if (!skipped_tests.empty())
{
for (size_t i = 0; i < skipped_tests.size(); i++)
{
const ::testing::TestInfo* test_info = skipped_tests[i];
if (!test_info) continue;
std::cout << "- " << test_info->test_case_name() << "." << test_info->name() << std::endl;
}
}*/
}
};
static bool isTestTagForced(const std::string& testTag)
{
const std::vector<std::string>& forceTags = getTestTagsForceList();
for (size_t i = 0; i < forceTags.size(); ++i)
{
const std::string& forceTag = forceTags[i];
if (testTag == forceTag
|| (testTag.size() >= forceTag.size()
&& forceTag[forceTag.size() - 1] == '*'
&& forceTag.substr(0, forceTag.size() - 1) == testTag.substr(0, forceTag.size() - 1)
)
)
{
return true;
}
}
return false;
}
static bool isTestTagSkipped(const std::string& testTag, CV_OUT std::string& skippedByTag)
{
skippedByTag.clear();
const std::vector<std::string>& skipTags = getTestTagsSkipList();
for (size_t i = 0; i < skipTags.size(); ++i)
{
const std::string& skipTag = skipTags[i];
if (testTag == skipTag
|| (testTag.size() >= skipTag.size()
&& skipTag[skipTag.size() - 1] == '*'
&& skipTag.substr(0, skipTag.size() - 1) == testTag.substr(0, skipTag.size() - 1)
)
)
{
skippedByTag = skipTag;
return true;
}
}
return false;
}
void checkTestTags()
{
std::string skipTag;
const std::vector<std::string>& testTags = currentDirectTestTags;
{
const std::vector<std::string>& tags = getTestTagsRequiredList();
if (!tags.empty())
{
size_t found = 0;
for (size_t i = 0; i < tags.size(); ++i)
{
const std::string& tag = tags[i];
for (size_t j = 0; j < testTags.size(); ++j)
{
const std::string& testTag = testTags[i];
if (testTag == tag
|| (testTag.size() >= tag.size()
&& tag[tag.size() - 1] == '*'
&& tag.substr(0, tag.size() - 1) == testTag.substr(0, tag.size() - 1)
)
)
{
found++;
break;
}
}
}
if (found != tags.size())
{
skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info());
throw details::SkipTestExceptionBase("Test tags don't pass required tags list (--test_tag parameter)", true);
}
}
}
for (size_t i = 0; i < testTags.size(); ++i)
{
const std::string& testTag = testTags[i];
if (isTestTagForced(testTag))
return;
}
std::string skip_message;
for (size_t i = 0; i < testTags.size(); ++i)
{
const std::string& testTag = testTags[i];
if (isTestTagSkipped(testTag, skipTag))
{
testTagIncreaseSkipCount(skipTag, skip_message.empty());
if (skip_message.empty()) skip_message = "Test with tag '" + testTag + "' is skipped ('" + skipTag + "' is in skip list)";
}
}
const std::vector<std::string>& testTagsImplied = currentImpliedTestTags;
for (size_t i = 0; i < testTagsImplied.size(); ++i)
{
const std::string& testTag = testTagsImplied[i];
if (isTestTagSkipped(testTag, skipTag))
{
testTagIncreaseSkipCount(skipTag, skip_message.empty());
if (skip_message.empty()) skip_message = "Test with tag '" + testTag + "' is skipped (implied '" + skipTag + "' is in skip list)";
}
}
if (!skip_message.empty())
{
skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info());
throw details::SkipTestExceptionBase(skip_message, true);
}
}
static bool applyTestTagImpl(const std::string& tag, bool direct = false)
{
CV_Assert(!tag.empty());
std::vector<std::string>& testTags = direct ? currentDirectTestTags : currentImpliedTestTags;
for (size_t i = 0; i < testTags.size(); ++i)
{
const std::string& testTag = testTags[i];
if (tag == testTag)
{
return false; // already exists, skip
}
}
testTags.push_back(tag);
// Tags implies logic
if (tag == CV_TEST_TAG_MEMORY_14GB)
applyTestTagImpl(CV_TEST_TAG_MEMORY_6GB);
if (tag == CV_TEST_TAG_MEMORY_6GB)
applyTestTagImpl(CV_TEST_TAG_MEMORY_2GB);
if (tag == CV_TEST_TAG_MEMORY_2GB)
applyTestTagImpl(CV_TEST_TAG_MEMORY_1GB);
if (tag == CV_TEST_TAG_MEMORY_1GB)
applyTestTagImpl(CV_TEST_TAG_MEMORY_512MB);
if (tag == CV_TEST_TAG_VERYLONG)
{
applyTestTagImpl(CV_TEST_TAG_DEBUG_VERYLONG);
applyTestTagImpl(CV_TEST_TAG_LONG);
}
else if (tag == CV_TEST_TAG_DEBUG_VERYLONG)
{
applyTestTagImpl(CV_TEST_TAG_DEBUG_LONG);
}
else if (tag == CV_TEST_TAG_LONG)
{
applyTestTagImpl(CV_TEST_TAG_DEBUG_LONG);
}
if (tag == CV_TEST_TAG_SIZE_4K)
applyTestTagImpl(CV_TEST_TAG_SIZE_FULLHD);
if (tag == CV_TEST_TAG_SIZE_FULLHD)
applyTestTagImpl(CV_TEST_TAG_SIZE_HD);
return true;
}
void applyTestTag(const std::string& tag)
{
if (tag.empty()) return;
if (!applyTestTagImpl(tag, true))
return;
checkTestTags();
}
void applyTestTag_(const std::string& tag)
{
if (tag.empty()) return;
if (!applyTestTagImpl(tag, true))
return;
}
static std::vector<std::string> parseStringList(const std::string& s)
{
std::vector<std::string> result;
size_t start_pos = 0;
while (start_pos != std::string::npos)
{
while (start_pos < s.size() && s[start_pos] == ' ')
start_pos++;
const size_t pos_ = s.find(',', start_pos);
size_t pos = (pos_ == std::string::npos ? s.size() : pos_);
while (pos > start_pos && s[pos - 1] == ' ')
pos--;
if (pos > start_pos)
{
const std::string one_piece(s, start_pos, pos - start_pos);
result.push_back(one_piece);
}
start_pos = (pos_ == std::string::npos ? pos_ : pos_ + 1);
}
return result;
}
void activateTestTags(const cv::CommandLineParser& parser)
{
std::string test_tag_skip = parser.get<std::string>("test_tag_skip");
if (!test_tag_skip.empty())
{
const std::vector<std::string> tag_list = parseStringList(test_tag_skip);
if (!tag_list.empty())
{
std::vector<std::string>& skipTags = getTestTagsSkipList();
for (size_t k = 0; k < tag_list.size(); ++k)
{
const std::string& tag = tag_list[k];
bool found = false;
for (size_t i = 0; i < skipTags.size(); ++i)
{
if (tag == skipTags[i])
{
found = true;
break;
}
}
if (!found)
skipTags.push_back(tag);
}
}
}
std::string test_tag_enable = parser.get<std::string>("test_tag_enable");
if (!test_tag_enable.empty())
{
const std::vector<std::string> tag_list = parseStringList(test_tag_enable);
if (!tag_list.empty())
{
std::vector<std::string>& skipTags = getTestTagsSkipList();
for (size_t k = 0; k < tag_list.size(); ++k)
{
const std::string& tag = tag_list[k];
bool found = false;
for (size_t i = 0; i < skipTags.size(); ++i)
{
if (tag == skipTags[i])
{
skipTags.erase(skipTags.begin() + i);
found = true;
}
}
if (!found)
{
std::cerr << "Can't re-enable tag '" << tag << "' - it is not in the skip list" << std::endl;
}
}
}
}
std::string test_tag_force = parser.get<std::string>("test_tag_force");
if (!test_tag_force.empty())
{
const std::vector<std::string> tag_list = parseStringList(test_tag_force);
if (!tag_list.empty())
{
std::vector<std::string>& forceTags = getTestTagsForceList();
for (size_t k = 0; k < tag_list.size(); ++k)
{
const std::string& tag = tag_list[k];
bool found = false;
for (size_t i = 0; i < forceTags.size(); ++i)
{
if (tag == forceTags[i])
{
found = true;
break;
}
}
if (!found)
forceTags.push_back(tag);
}
}
}
std::string test_tag = parser.get<std::string>("test_tag");
if (!test_tag.empty())
{
const std::vector<std::string> tag_list = parseStringList(test_tag);
if (!tag_list.empty())
{
std::vector<std::string>& requiredTags = getTestTagsRequiredList();
for (size_t k = 0; k < tag_list.size(); ++k)
{
const std::string& tag = tag_list[k];
bool found = false;
for (size_t i = 0; i < requiredTags.size(); ++i)
{
if (tag == requiredTags[i])
{
found = true;
break;
}
}
if (!found)
requiredTags.push_back(tag);
}
}
}
printTestTag = parser.get<bool>("test_tag_print");
::testing::UnitTest::GetInstance()->listeners().Append(new TestTagsListener());
}
} // namespace

View File

@@ -0,0 +1,28 @@
// 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.
#ifndef OPENCV_TS_SRC_TAGS_HPP
#define OPENCV_TS_SRC_TAGS_HPP
// [all | test_tag] - (test_tag_skip - test_tag_enable) + test_tag_force
#define CV_TEST_TAGS_PARAMS \
"{ test_tag | |run tests with specified 'tag' markers only (comma ',' separated list) }" \
"{ test_tag_skip | |skip tests with 'tag' markers (comma ',' separated list) }" \
"{ test_tag_enable | |don't skip tests with 'tag' markers (comma ',' separated list) }" \
"{ test_tag_force | |force running of tests with 'tag' markers (comma ',' separated list) }" \
"{ test_tag_print | false |print assigned tags for each test }" \
// TODO
// "{ test_tag_file | |read test tags assignment }" \
namespace cvtest {
void activateTestTags(const cv::CommandLineParser& parser);
void testTagIncreaseSkipCount(const std::string& tag, bool isMain = true, bool appendSkipTests = false);
} // namespace
#endif // OPENCV_TS_SRC_TAGS_HPP