提交 6f788ff8 编写于 作者: A Alexey Spizhevoy

ported GPU test to GTest framework

上级 97eaa95a
......@@ -5,7 +5,7 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include"
"${CMAKE_CURRENT_SOURCE_DIR}/.."
"${CMAKE_CURRENT_BINARY_DIR}")
set(test_deps opencv_${name} opencv_ts opencv_highgui ${DEPS})
set(test_deps opencv_${name} opencv_ts opencv_highgui opencv_calib3d ${DEPS})
foreach(d ${test_deps})
if(${d} MATCHES "opencv_")
if(${d} MATCHES "opencv_lapack")
......@@ -50,4 +50,4 @@ add_test(${the_target} "${LOC}")
if(WIN32)
install(TARGETS ${the_target} RUNTIME DESTINATION bin COMPONENT main)
endif()
\ No newline at end of file
endif()
/*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 <iostream>
#include <cmath>
#include <limits>
#include "test_precomp.hpp"
using namespace cv;
using namespace std;
using namespace gpu;
#define CHECK(pred, err) if (!(pred)) { \
ts->printf(cvtest::TS::CONSOLE, "Fail: \"%s\" at line: %d\n", #pred, __LINE__); \
ts->set_failed_test_info(err); \
return; }
class CV_GpuArithmTest : public cvtest::BaseTest
{
public:
CV_GpuArithmTest(const char* test_name, const char* test_funcs){}
virtual ~CV_GpuArithmTest() {}
protected:
void run(int);
int test(int type);
virtual int test(const Mat& mat1, const Mat& mat2) = 0;
int CheckNorm(const Mat& m1, const Mat& m2, double eps = 1e-5);
int CheckNorm(const Scalar& s1, const Scalar& s2, double eps = 1e-5);
int CheckNorm(double d1, double d2, double eps = 1e-5);
};
int CV_GpuArithmTest::test(int type)
{
cv::Size sz(200, 200);
cv::Mat mat1(sz, type), mat2(sz, type);
cv::RNG& rng = ts->get_rng();
if (type != CV_32FC1)
{
rng.fill(mat1, cv::RNG::UNIFORM, cv::Scalar::all(1), cv::Scalar::all(20));
rng.fill(mat2, cv::RNG::UNIFORM, cv::Scalar::all(1), cv::Scalar::all(20));
}
else
{
rng.fill(mat1, cv::RNG::UNIFORM, cv::Scalar::all(0.1), cv::Scalar::all(1.0));
rng.fill(mat2, cv::RNG::UNIFORM, cv::Scalar::all(0.1), cv::Scalar::all(1.0));
}
return test(mat1, mat2);
}
int CV_GpuArithmTest::CheckNorm(const Mat& m1, const Mat& m2, double eps)
{
double ret = norm(m1, m2, NORM_INF);
if (ret < eps)
return cvtest::TS::OK;
ts->printf(cvtest::TS::LOG, "\nNorm: %f\n", ret);
return cvtest::TS::FAIL_GENERIC;
}
int CV_GpuArithmTest::CheckNorm(const Scalar& s1, const Scalar& s2, double eps)
{
int ret0 = CheckNorm(s1[0], s2[0], eps),
ret1 = CheckNorm(s1[1], s2[1], eps),
ret2 = CheckNorm(s1[2], s2[2], eps),
ret3 = CheckNorm(s1[3], s2[3], eps);
return (ret0 == cvtest::TS::OK && ret1 == cvtest::TS::OK && ret2 == cvtest::TS::OK && ret3 == cvtest::TS::OK) ? cvtest::TS::OK : cvtest::TS::FAIL_GENERIC;
}
int CV_GpuArithmTest::CheckNorm(double d1, double d2, double eps)
{
double ret = ::fabs(d1 - d2);
if (ret < eps)
return cvtest::TS::OK;
ts->printf(cvtest::TS::LOG, "\nNorm: %f\n", ret);
return cvtest::TS::FAIL_GENERIC;
}
void CV_GpuArithmTest::run( int )
{
int testResult = cvtest::TS::OK;
const int types[] = {CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1};
const char* type_names[] = {"CV_8UC1 ", "CV_8UC3 ", "CV_8UC4 ", "CV_32FC1"};
const int type_count = sizeof(types)/sizeof(types[0]);
//run tests
for (int t = 0; t < type_count; ++t)
{
ts->printf(cvtest::TS::LOG, "Start testing %s", type_names[t]);
if (cvtest::TS::OK == test(types[t]))
ts->printf(cvtest::TS::LOG, "SUCCESS\n");
else
{
ts->printf(cvtest::TS::LOG, "FAIL\n");
testResult = cvtest::TS::FAIL_MISMATCH;
}
}
ts->set_failed_test_info(testResult);
}
////////////////////////////////////////////////////////////////////////////////
// Add
struct CV_GpuNppImageAddTest : public CV_GpuArithmTest
{
CV_GpuNppImageAddTest() : CV_GpuArithmTest( "GPU-NppImageAdd", "add" ) {}
virtual int test(const Mat& mat1, const Mat& mat2)
{
if (mat1.type() != CV_8UC1 && mat1.type() != CV_8UC4 && mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::add(mat1, mat2, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuRes;
cv::gpu::add(gpu1, gpu2, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// Sub
struct CV_GpuNppImageSubtractTest : public CV_GpuArithmTest
{
CV_GpuNppImageSubtractTest() : CV_GpuArithmTest( "GPU-NppImageSubtract", "subtract" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_8UC1 && mat1.type() != CV_8UC4 && mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::subtract(mat1, mat2, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuRes;
cv::gpu::subtract(gpu1, gpu2, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// multiply
struct CV_GpuNppImageMultiplyTest : public CV_GpuArithmTest
{
CV_GpuNppImageMultiplyTest() : CV_GpuArithmTest( "GPU-NppImageMultiply", "multiply" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_8UC1 && mat1.type() != CV_8UC4 && mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::multiply(mat1, mat2, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuRes;
cv::gpu::multiply(gpu1, gpu2, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// divide
struct CV_GpuNppImageDivideTest : public CV_GpuArithmTest
{
CV_GpuNppImageDivideTest() : CV_GpuArithmTest( "GPU-NppImageDivide", "divide" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_8UC1 && mat1.type() != CV_8UC4 && mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::divide(mat1, mat2, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuRes;
cv::gpu::divide(gpu1, gpu2, gpuRes);
return CheckNorm(cpuRes, gpuRes, 1.01f);
}
};
////////////////////////////////////////////////////////////////////////////////
// transpose
struct CV_GpuNppImageTransposeTest : public CV_GpuArithmTest
{
CV_GpuNppImageTransposeTest() : CV_GpuArithmTest( "GPU-NppImageTranspose", "transpose" ) {}
int test( const Mat& mat1, const Mat& )
{
if (mat1.type() != CV_8UC1 && mat1.type() != CV_8UC4 && mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::transpose(mat1, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpuRes;
cv::gpu::transpose(gpu1, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// absdiff
struct CV_GpuNppImageAbsdiffTest : public CV_GpuArithmTest
{
CV_GpuNppImageAbsdiffTest() : CV_GpuArithmTest( "GPU-NppImageAbsdiff", "absdiff" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_8UC1 && mat1.type() != CV_8UC4 && mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::absdiff(mat1, mat2, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuRes;
cv::gpu::absdiff(gpu1, gpu2, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// compare
struct CV_GpuNppImageCompareTest : public CV_GpuArithmTest
{
CV_GpuNppImageCompareTest() : CV_GpuArithmTest( "GPU-NppImageCompare", "compare" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
int cmp_codes[] = {CMP_EQ, CMP_GT, CMP_GE, CMP_LT, CMP_LE, CMP_NE};
const char* cmp_str[] = {"CMP_EQ", "CMP_GT", "CMP_GE", "CMP_LT", "CMP_LE", "CMP_NE"};
int cmp_num = sizeof(cmp_codes) / sizeof(int);
int test_res = cvtest::TS::OK;
for (int i = 0; i < cmp_num; ++i)
{
ts->printf(cvtest::TS::LOG, "\nCompare operation: %s\n", cmp_str[i]);
cv::Mat cpuRes;
cv::compare(mat1, mat2, cpuRes, cmp_codes[i]);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuRes;
cv::gpu::compare(gpu1, gpu2, gpuRes, cmp_codes[i]);
if (CheckNorm(cpuRes, gpuRes) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// meanStdDev
struct CV_GpuNppImageMeanStdDevTest : public CV_GpuArithmTest
{
CV_GpuNppImageMeanStdDevTest() : CV_GpuArithmTest( "GPU-NppImageMeanStdDev", "meanStdDev" ) {}
int test( const Mat& mat1, const Mat& )
{
if (mat1.type() != CV_8UC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
Scalar cpumean;
Scalar cpustddev;
cv::meanStdDev(mat1, cpumean, cpustddev);
GpuMat gpu1(mat1);
Scalar gpumean;
Scalar gpustddev;
cv::gpu::meanStdDev(gpu1, gpumean, gpustddev);
int test_res = cvtest::TS::OK;
if (CheckNorm(cpumean, gpumean) != cvtest::TS::OK)
{
ts->printf(cvtest::TS::LOG, "\nMean FAILED\n");
test_res = cvtest::TS::FAIL_GENERIC;
}
if (CheckNorm(cpustddev, gpustddev) != cvtest::TS::OK)
{
ts->printf(cvtest::TS::LOG, "\nStdDev FAILED\n");
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// norm
struct CV_GpuNppImageNormTest : public CV_GpuArithmTest
{
CV_GpuNppImageNormTest() : CV_GpuArithmTest( "GPU-NppImageNorm", "norm" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_8UC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
int norms[] = {NORM_INF, NORM_L1, NORM_L2};
const char* norms_str[] = {"NORM_INF", "NORM_L1", "NORM_L2"};
int norms_num = sizeof(norms) / sizeof(int);
int test_res = cvtest::TS::OK;
for (int i = 0; i < norms_num; ++i)
{
ts->printf(cvtest::TS::LOG, "\nNorm type: %s\n", norms_str[i]);
double cpu_norm = cv::norm(mat1, mat2, norms[i]);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
double gpu_norm = cv::gpu::norm(gpu1, gpu2, norms[i]);
if (CheckNorm(cpu_norm, gpu_norm) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// flip
struct CV_GpuNppImageFlipTest : public CV_GpuArithmTest
{
CV_GpuNppImageFlipTest() : CV_GpuArithmTest( "GPU-NppImageFlip", "flip" ) {}
int test( const Mat& mat1, const Mat& )
{
if (mat1.type() != CV_8UC1 && mat1.type() != CV_8UC4)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
int flip_codes[] = {0, 1, -1};
const char* flip_axis[] = {"X", "Y", "Both"};
int flip_codes_num = sizeof(flip_codes) / sizeof(int);
int test_res = cvtest::TS::OK;
for (int i = 0; i < flip_codes_num; ++i)
{
ts->printf(cvtest::TS::LOG, "\nFlip Axis: %s\n", flip_axis[i]);
Mat cpu_res;
cv::flip(mat1, cpu_res, flip_codes[i]);
GpuMat gpu1(mat1);
GpuMat gpu_res;
cv::gpu::flip(gpu1, gpu_res, flip_codes[i]);
if (CheckNorm(cpu_res, gpu_res) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// LUT
struct CV_GpuNppImageLUTTest : public CV_GpuArithmTest
{
CV_GpuNppImageLUTTest() : CV_GpuArithmTest( "GPU-NppImageLUT", "LUT" ) {}
int test( const Mat& mat1, const Mat& )
{
if (mat1.type() != CV_8UC1 && mat1.type() != CV_8UC3)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat lut(1, 256, CV_8UC1);
cv::RNG& rng = ts->get_rng();
rng.fill(lut, cv::RNG::UNIFORM, cv::Scalar::all(100), cv::Scalar::all(200));
cv::Mat cpuRes;
cv::LUT(mat1, lut, cpuRes);
cv::gpu::GpuMat gpuRes;
cv::gpu::LUT(GpuMat(mat1), lut, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// exp
struct CV_GpuNppImageExpTest : public CV_GpuArithmTest
{
CV_GpuNppImageExpTest() : CV_GpuArithmTest( "GPU-NppImageExp", "exp" ) {}
int test( const Mat& mat1, const Mat& )
{
if (mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::exp(mat1, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpuRes;
cv::gpu::exp(gpu1, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// log
struct CV_GpuNppImageLogTest : public CV_GpuArithmTest
{
CV_GpuNppImageLogTest() : CV_GpuArithmTest( "GPU-NppImageLog", "log" ) {}
int test( const Mat& mat1, const Mat& )
{
if (mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::log(mat1, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpuRes;
cv::gpu::log(gpu1, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// magnitude
struct CV_GpuNppImageMagnitudeTest : public CV_GpuArithmTest
{
CV_GpuNppImageMagnitudeTest() : CV_GpuArithmTest( "GPU-NppImageMagnitude", "magnitude" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::magnitude(mat1, mat2, cpuRes);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuRes;
cv::gpu::magnitude(gpu1, gpu2, gpuRes);
return CheckNorm(cpuRes, gpuRes);
}
};
////////////////////////////////////////////////////////////////////////////////
// phase
struct CV_GpuNppImagePhaseTest : public CV_GpuArithmTest
{
CV_GpuNppImagePhaseTest() : CV_GpuArithmTest( "GPU-NppImagePhase", "phase" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuRes;
cv::phase(mat1, mat2, cpuRes, true);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuRes;
cv::gpu::phase(gpu1, gpu2, gpuRes, true);
return CheckNorm(cpuRes, gpuRes, 0.3f);
}
};
////////////////////////////////////////////////////////////////////////////////
// cartToPolar
struct CV_GpuNppImageCartToPolarTest : public CV_GpuArithmTest
{
CV_GpuNppImageCartToPolarTest() : CV_GpuArithmTest( "GPU-NppImageCartToPolar", "cartToPolar" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuMag, cpuAngle;
cv::cartToPolar(mat1, mat2, cpuMag, cpuAngle);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuMag, gpuAngle;
cv::gpu::cartToPolar(gpu1, gpu2, gpuMag, gpuAngle);
int magRes = CheckNorm(cpuMag, gpuMag);
int angleRes = CheckNorm(cpuAngle, gpuAngle, 0.005f);
return magRes == cvtest::TS::OK && angleRes == cvtest::TS::OK ? cvtest::TS::OK : cvtest::TS::FAIL_GENERIC;
}
};
////////////////////////////////////////////////////////////////////////////////
// polarToCart
struct CV_GpuNppImagePolarToCartTest : public CV_GpuArithmTest
{
CV_GpuNppImagePolarToCartTest() : CV_GpuArithmTest( "GPU-NppImagePolarToCart", "polarToCart" ) {}
int test( const Mat& mat1, const Mat& mat2 )
{
if (mat1.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\tUnsupported type\t");
return cvtest::TS::OK;
}
cv::Mat cpuX, cpuY;
cv::polarToCart(mat1, mat2, cpuX, cpuY);
GpuMat gpu1(mat1);
GpuMat gpu2(mat2);
GpuMat gpuX, gpuY;
cv::gpu::polarToCart(gpu1, gpu2, gpuX, gpuY);
int xRes = CheckNorm(cpuX, gpuX);
int yRes = CheckNorm(cpuY, gpuY);
return xRes == cvtest::TS::OK && yRes == cvtest::TS::OK ? cvtest::TS::OK : cvtest::TS::FAIL_GENERIC;
}
};
////////////////////////////////////////////////////////////////////////////////
// Min max
struct CV_GpuMinMaxTest: public cvtest::BaseTest
{
CV_GpuMinMaxTest() {}
cv::gpu::GpuMat buf;
void run(int)
{
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
int depth_end = double_ok ? CV_64F : CV_32F;
for (int depth = CV_8U; depth <= depth_end; ++depth)
{
for (int i = 0; i < 3; ++i)
{
int rows = 1 + rand() % 1000;
int cols = 1 + rand() % 1000;
test(rows, cols, 1, depth);
test_masked(rows, cols, 1, depth);
}
}
}
void test(int rows, int cols, int cn, int depth)
{
cv::Mat src(rows, cols, CV_MAKE_TYPE(depth, cn));
cv::RNG& rng = ts->get_rng();
rng.fill(src, RNG::UNIFORM, Scalar(0), Scalar(255));
double minVal, maxVal;
cv::Point minLoc, maxLoc;
if (depth != CV_8S)
{
cv::minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc);
}
else
{
minVal = std::numeric_limits<double>::max();
maxVal = -std::numeric_limits<double>::max();
for (int i = 0; i < src.rows; ++i)
for (int j = 0; j < src.cols; ++j)
{
signed char val = src.at<signed char>(i, j);
if (val < minVal) minVal = val;
if (val > maxVal) maxVal = val;
}
}
double minVal_, maxVal_;
cv::gpu::minMax(cv::gpu::GpuMat(src), &minVal_, &maxVal_, cv::gpu::GpuMat(), buf);
if (abs(minVal - minVal_) > 1e-3f)
{
ts->printf(cvtest::TS::CONSOLE, "\nfail: minVal=%f minVal_=%f rows=%d cols=%d depth=%d cn=%d\n", minVal, minVal_, rows, cols, depth, cn);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
}
if (abs(maxVal - maxVal_) > 1e-3f)
{
ts->printf(cvtest::TS::CONSOLE, "\nfail: maxVal=%f maxVal_=%f rows=%d cols=%d depth=%d cn=%d\n", maxVal, maxVal_, rows, cols, depth, cn);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
}
}
void test_masked(int rows, int cols, int cn, int depth)
{
cv::Mat src(rows, cols, CV_MAKE_TYPE(depth, cn));
cv::RNG& rng = ts->get_rng();
rng.fill(src, RNG::UNIFORM, Scalar(0), Scalar(255));
cv::Mat mask(src.size(), CV_8U);
rng.fill(mask, RNG::UNIFORM, Scalar(0), Scalar(2));
double minVal, maxVal;
cv::Point minLoc, maxLoc;
Mat src_ = src.reshape(1);
if (depth != CV_8S)
{
cv::minMaxLoc(src_, &minVal, &maxVal, &minLoc, &maxLoc, mask);
}
else
{
// OpenCV's minMaxLoc doesn't support CV_8S type
minVal = std::numeric_limits<double>::max();
maxVal = -std::numeric_limits<double>::max();
for (int i = 0; i < src_.rows; ++i)
for (int j = 0; j < src_.cols; ++j)
{
char val = src_.at<char>(i, j);
if (mask.at<unsigned char>(i, j)) { if (val < minVal) minVal = val; }
if (mask.at<unsigned char>(i, j)) { if (val > maxVal) maxVal = val; }
}
}
double minVal_, maxVal_;
cv::Point minLoc_, maxLoc_;
cv::gpu::minMax(cv::gpu::GpuMat(src), &minVal_, &maxVal_, cv::gpu::GpuMat(mask), buf);
if (abs(minVal - minVal_) > 1e-3f)
{
ts->printf(cvtest::TS::CONSOLE, "\nfail: minVal=%f minVal_=%f rows=%d cols=%d depth=%d cn=%d\n", minVal, minVal_, rows, cols, depth, cn);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
}
if (abs(maxVal - maxVal_) > 1e-3f)
{
ts->printf(cvtest::TS::CONSOLE, "\nfail: maxVal=%f maxVal_=%f rows=%d cols=%d depth=%d cn=%d\n", maxVal, maxVal_, rows, cols, depth, cn);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
}
}
};
////////////////////////////////////////////////////////////////////////////////
// Min max loc
struct CV_GpuMinMaxLocTest: public cvtest::BaseTest
{
CV_GpuMinMaxLocTest() {}
GpuMat valbuf, locbuf;
void run(int)
{
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
int depth_end = double_ok ? CV_64F : CV_32F;
for (int depth = CV_8U; depth <= depth_end; ++depth)
{
int rows = 1, cols = 3;
test(rows, cols, depth);
for (int i = 0; i < 4; ++i)
{
int rows = 1 + rand() % 1000;
int cols = 1 + rand() % 1000;
test(rows, cols, depth);
}
}
}
void test(int rows, int cols, int depth)
{
cv::Mat src(rows, cols, depth);
cv::RNG& rng = ts->get_rng();
rng.fill(src, RNG::UNIFORM, Scalar(0), Scalar(255));
cv::Mat mask(src.size(), CV_8U);
rng.fill(mask, RNG::UNIFORM, Scalar(0), Scalar(2));
// At least one of the mask elements must be non zero as OpenCV returns 0
// in such case, when our implementation returns maximum or minimum value
mask.at<unsigned char>(0, 0) = 1;
double minVal, maxVal;
cv::Point minLoc, maxLoc;
if (depth != CV_8S)
cv::minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc, mask);
else
{
// OpenCV's minMaxLoc doesn't support CV_8S type
minVal = std::numeric_limits<double>::max();
maxVal = -std::numeric_limits<double>::max();
for (int i = 0; i < src.rows; ++i)
for (int j = 0; j < src.cols; ++j)
{
char val = src.at<char>(i, j);
if (mask.at<unsigned char>(i, j))
{
if (val < minVal) { minVal = val; minLoc = cv::Point(j, i); }
if (val > maxVal) { maxVal = val; maxLoc = cv::Point(j, i); }
}
}
}
double minVal_, maxVal_;
cv::Point minLoc_, maxLoc_;
cv::gpu::minMaxLoc(cv::gpu::GpuMat(src), &minVal_, &maxVal_, &minLoc_, &maxLoc_, cv::gpu::GpuMat(mask), valbuf, locbuf);
CHECK(minVal == minVal_, cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(maxVal == maxVal_, cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(0 == memcmp(src.ptr(minLoc.y) + minLoc.x * src.elemSize(), src.ptr(minLoc_.y) + minLoc_.x * src.elemSize(), src.elemSize()),
cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(0 == memcmp(src.ptr(maxLoc.y) + maxLoc.x * src.elemSize(), src.ptr(maxLoc_.y) + maxLoc_.x * src.elemSize(), src.elemSize()),
cvtest::TS::FAIL_INVALID_OUTPUT);
}
};
////////////////////////////////////////////////////////////////////////////
// Count non zero
struct CV_GpuCountNonZeroTest: cvtest::BaseTest
{
CV_GpuCountNonZeroTest(){}
void run(int)
{
int depth_end;
if (cv::gpu::DeviceInfo().supports(cv::gpu::NATIVE_DOUBLE))
depth_end = CV_64F;
else
depth_end = CV_32F;
for (int depth = CV_8U; depth <= CV_32F; ++depth)
{
for (int i = 0; i < 4; ++i)
{
int rows = 1 + rand() % 1000;
int cols = 1 + rand() % 1000;
test(rows, cols, depth);
}
}
}
void test(int rows, int cols, int depth)
{
cv::Mat src(rows, cols, depth);
cv::RNG rng;
if (depth == 5)
rng.fill(src, RNG::UNIFORM, Scalar(-1000.f), Scalar(1000.f));
else if (depth == 6)
rng.fill(src, RNG::UNIFORM, Scalar(-1000.), Scalar(1000.));
else
for (int i = 0; i < src.rows; ++i)
{
Mat row(1, src.cols * src.elemSize(), CV_8U, src.ptr(i));
rng.fill(row, RNG::UNIFORM, Scalar(0), Scalar(256));
}
int n_gold = cv::countNonZero(src);
int n = cv::gpu::countNonZero(cv::gpu::GpuMat(src));
if (n != n_gold)
{
ts->printf(cvtest::TS::LOG, "%d %d %d %d %d\n", n, n_gold, depth, cols, rows);
n_gold = cv::countNonZero(src);
}
CHECK(n == n_gold, cvtest::TS::FAIL_INVALID_OUTPUT);
}
};
//////////////////////////////////////////////////////////////////////////////
// sum
struct CV_GpuSumTest: cvtest::BaseTest
{
CV_GpuSumTest() {}
void run(int)
{
Mat src;
Scalar a, b;
double max_err = 1e-5;
int typemax = CV_32F;
for (int type = CV_8U; type <= typemax; ++type)
{
//
// sum
//
gen(1 + rand() % 500, 1 + rand() % 500, CV_MAKETYPE(type, 1), src);
a = sum(src);
b = sum(GpuMat(src));
if (abs(a[0] - b[0]) > src.size().area() * max_err)
{
ts->printf(cvtest::TS::CONSOLE, "1 cols: %d, rows: %d, expected: %f, actual: %f\n", src.cols, src.rows, a[0], b[0]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
gen(1 + rand() % 500, 1 + rand() % 500, CV_MAKETYPE(type, 2), src);
a = sum(src);
b = sum(GpuMat(src));
if (abs(a[0] - b[0]) + abs(a[1] - b[1]) > src.size().area() * max_err)
{
ts->printf(cvtest::TS::CONSOLE, "2 cols: %d, rows: %d, expected: %f, actual: %f\n", src.cols, src.rows, a[1], b[1]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
gen(1 + rand() % 500, 1 + rand() % 500, CV_MAKETYPE(type, 3), src);
a = sum(src);
b = sum(GpuMat(src));
if (abs(a[0] - b[0]) + abs(a[1] - b[1]) + abs(a[2] - b[2])> src.size().area() * max_err)
{
ts->printf(cvtest::TS::CONSOLE, "3 cols: %d, rows: %d, expected: %f, actual: %f\n", src.cols, src.rows, a[2], b[2]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
gen(1 + rand() % 500, 1 + rand() % 500, CV_MAKETYPE(type, 4), src);
a = sum(src);
b = sum(GpuMat(src));
if (abs(a[0] - b[0]) + abs(a[1] - b[1]) + abs(a[2] - b[2]) + abs(a[3] - b[3])> src.size().area() * max_err)
{
ts->printf(cvtest::TS::CONSOLE, "4 cols: %d, rows: %d, expected: %f, actual: %f\n", src.cols, src.rows, a[3], b[3]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
gen(1 + rand() % 500, 1 + rand() % 500, type, src);
a = sum(src);
b = sum(GpuMat(src));
if (abs(a[0] - b[0]) > src.size().area() * max_err)
{
ts->printf(cvtest::TS::CONSOLE, "cols: %d, rows: %d, expected: %f, actual: %f\n", src.cols, src.rows, a[0], b[0]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
//
// absSum
//
gen(1 + rand() % 200, 1 + rand() % 200, CV_MAKETYPE(type, 1), src);
b = absSum(GpuMat(src));
a = norm(src, NORM_L1);
if (abs(a[0] - b[0]) > src.size().area() * max_err)
{
ts->printf(cvtest::TS::CONSOLE, "type: %d, cols: %d, rows: %d, expected: %f, actual: %f\n", type, src.cols, src.rows, a[0], b[0]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
//
// sqrSum
//
if (type != CV_8S)
{
gen(1 + rand() % 200, 1 + rand() % 200, CV_MAKETYPE(type, 1), src);
b = sqrSum(GpuMat(src));
Mat sqrsrc;
multiply(src, src, sqrsrc);
a = sum(sqrsrc);
if (abs(a[0] - b[0]) > src.size().area() * max_err)
{
ts->printf(cvtest::TS::CONSOLE, "type: %d, cols: %d, rows: %d, expected: %f, actual: %f\n", type, src.cols, src.rows, a[0], b[0]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
gen(1 + rand() % 200, 1 + rand() % 200, CV_MAKETYPE(type, 2), src);
b = sqrSum(GpuMat(src));
multiply(src, src, sqrsrc);
a = sum(sqrsrc);
if (abs(a[0] - b[0]) + abs(a[1] - b[1])> src.size().area() * max_err * 2)
{
ts->printf(cvtest::TS::CONSOLE, "type: %d, cols: %d, rows: %d, expected: %f, actual: %f\n", type, src.cols, src.rows, a[0], b[0]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
gen(1 + rand() % 200, 1 + rand() % 200, CV_MAKETYPE(type, 3), src);
b = sqrSum(GpuMat(src));
multiply(src, src, sqrsrc);
a = sum(sqrsrc);
if (abs(a[0] - b[0]) + abs(a[1] - b[1]) + abs(a[2] - b[2])> src.size().area() * max_err * 3)
{
ts->printf(cvtest::TS::CONSOLE, "type: %d, cols: %d, rows: %d, expected: %f, actual: %f\n", type, src.cols, src.rows, a[0], b[0]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
gen(1 + rand() % 200, 1 + rand() % 200, CV_MAKETYPE(type, 4), src);
b = sqrSum(GpuMat(src));
multiply(src, src, sqrsrc);
a = sum(sqrsrc);
if (abs(a[0] - b[0]) + abs(a[1] - b[1]) + abs(a[2] - b[2]) + abs(a[3] - b[3])> src.size().area() * max_err * 4)
{
ts->printf(cvtest::TS::CONSOLE, "type: %d, cols: %d, rows: %d, expected: %f, actual: %f\n", type, src.cols, src.rows, a[0], b[0]);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
}
}
void gen(int cols, int rows, int type, Mat& m)
{
m.create(rows, cols, type);
RNG rng;
rng.fill(m, RNG::UNIFORM, Scalar::all(0), Scalar::all(16));
}
};
TEST(add, accuracy) { CV_GpuNppImageAddTest test; test.safe_run(); }
TEST(subtract, accuracy) { CV_GpuNppImageSubtractTest test; test.safe_run(); }
TEST(multiply, accuracy) { CV_GpuNppImageMultiplyTest test; test.safe_run(); }
TEST(divide, accuracy) { CV_GpuNppImageDivideTest test; test.safe_run(); }
TEST(transpose, accuracy) { CV_GpuNppImageTransposeTest test; test.safe_run(); }
TEST(absdiff, accuracy) { CV_GpuNppImageAbsdiffTest test; test.safe_run(); }
TEST(compare, accuracy) { CV_GpuNppImageCompareTest test; test.safe_run(); }
TEST(meanStdDev, accuracy) { CV_GpuNppImageMeanStdDevTest test; test.safe_run(); }
TEST(normDiff, accuracy) { CV_GpuNppImageNormTest test; test.safe_run(); }
TEST(flip, accuracy) { CV_GpuNppImageFlipTest test; test.safe_run(); }
TEST(LUT, accuracy) { CV_GpuNppImageLUTTest test; test.safe_run(); }
TEST(exp, accuracy) { CV_GpuNppImageExpTest test; test.safe_run(); }
TEST(log, accuracy) { CV_GpuNppImageLogTest test; test.safe_run(); }
TEST(magnitude, accuracy) { CV_GpuNppImageMagnitudeTest test; test.safe_run(); }
TEST(phase, accuracy) { CV_GpuNppImagePhaseTest test; test.safe_run(); }
TEST(cartToPolar, accuracy) { CV_GpuNppImageCartToPolarTest test; test.safe_run(); }
TEST(polarToCart, accuracy) { CV_GpuNppImagePolarToCartTest test; test.safe_run(); }
TEST(minMax, accuracy) { CV_GpuMinMaxTest test; test.safe_run(); }
TEST(minMaxLoc, accuracy) { CV_GpuMinMaxLocTest test; test.safe_run(); }
TEST(countNonZero, accuracy) { CV_GpuCountNonZeroTest test; test.safe_run(); }
TEST(sum, accuracy) { CV_GpuSumTest test; test.safe_run(); }
/*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 <iostream>
#include <limits>
#include "test_precomp.hpp"
#define CHECK(pred, err) if (!(pred)) { \
ts->printf(cvtest::TS::CONSOLE, "Fail: \"%s\" at line: %d\n", #pred, __LINE__); \
ts->set_failed_test_info(err); \
return; }
using namespace cv;
using namespace std;
struct CV_GpuBitwiseTest: public cvtest::BaseTest
{
CV_GpuBitwiseTest() {}
void run(int)
{
int rows, cols;
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
int depth_end = double_ok ? CV_64F : CV_32F;
for (int depth = CV_8U; depth <= depth_end; ++depth)
for (int cn = 1; cn <= 4; ++cn)
for (int attempt = 0; attempt < 3; ++attempt)
{
rows = 1 + rand() % 100;
cols = 1 + rand() % 100;
test_bitwise_not(rows, cols, CV_MAKETYPE(depth, cn));
test_bitwise_or(rows, cols, CV_MAKETYPE(depth, cn));
test_bitwise_and(rows, cols, CV_MAKETYPE(depth, cn));
test_bitwise_xor(rows, cols, CV_MAKETYPE(depth, cn));
}
}
void test_bitwise_not(int rows, int cols, int type)
{
Mat src(rows, cols, type);
RNG rng;
for (int i = 0; i < src.rows; ++i)
{
Mat row(1, src.cols * src.elemSize(), CV_8U, src.ptr(i));
rng.fill(row, RNG::UNIFORM, Scalar(0), Scalar(255));
}
Mat dst_gold = ~src;
gpu::GpuMat mask(src.size(), CV_8U);
mask.setTo(Scalar(1));
gpu::GpuMat dst;
gpu::bitwise_not(gpu::GpuMat(src), dst);
CHECK(dst_gold.size() == dst.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(dst_gold.type() == dst.type(), cvtest::TS::FAIL_INVALID_OUTPUT);
Mat dsth(dst);
for (int i = 0; i < dst_gold.rows; ++i)
CHECK(memcmp(dst_gold.ptr(i), dsth.ptr(i), dst_gold.cols * dst_gold.elemSize()) == 0, cvtest::TS::FAIL_INVALID_OUTPUT);
dst.setTo(Scalar::all(0));
gpu::bitwise_not(gpu::GpuMat(src), dst, mask);
CHECK(dst_gold.size() == dst.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(dst_gold.type() == dst.type(), cvtest::TS::FAIL_INVALID_OUTPUT);
dsth = dst;
for (int i = 0; i < dst_gold.rows; ++i)
CHECK(memcmp(dst_gold.ptr(i), dsth.ptr(i), dst_gold.cols * dst_gold.elemSize()) == 0, cvtest::TS::FAIL_INVALID_OUTPUT)
}
void test_bitwise_or(int rows, int cols, int type)
{
Mat src1(rows, cols, type);
Mat src2(rows, cols, type);
RNG rng;
for (int i = 0; i < src1.rows; ++i)
{
Mat row1(1, src1.cols * src1.elemSize(), CV_8U, src1.ptr(i));
rng.fill(row1, RNG::UNIFORM, Scalar(0), Scalar(255));
Mat row2(1, src2.cols * src2.elemSize(), CV_8U, src2.ptr(i));
rng.fill(row2, RNG::UNIFORM, Scalar(0), Scalar(255));
}
Mat dst_gold = src1 | src2;
gpu::GpuMat dst = gpu::GpuMat(src1) | gpu::GpuMat(src2);
CHECK(dst_gold.size() == dst.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(dst_gold.type() == dst.type(), cvtest::TS::FAIL_INVALID_OUTPUT);
Mat dsth(dst);
for (int i = 0; i < dst_gold.rows; ++i)
CHECK(memcmp(dst_gold.ptr(i), dsth.ptr(i), dst_gold.cols * dst_gold.elemSize()) == 0, cvtest::TS::FAIL_INVALID_OUTPUT)
Mat mask(src1.size(), CV_8U);
randu(mask, Scalar(0), Scalar(255));
Mat dst_gold2(dst_gold.size(), dst_gold.type()); dst_gold2.setTo(Scalar::all(0));
gpu::GpuMat dst2(dst.size(), dst.type()); dst2.setTo(Scalar::all(0));
bitwise_or(src1, src2, dst_gold2, mask);
gpu::bitwise_or(gpu::GpuMat(src1), gpu::GpuMat(src2), dst2, gpu::GpuMat(mask));
CHECK(dst_gold2.size() == dst2.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(dst_gold2.type() == dst2.type(), cvtest::TS::FAIL_INVALID_OUTPUT);
dsth = dst2;
for (int i = 0; i < dst_gold.rows; ++i)
CHECK(memcmp(dst_gold2.ptr(i), dsth.ptr(i), dst_gold2.cols * dst_gold2.elemSize()) == 0, cvtest::TS::FAIL_INVALID_OUTPUT)
}
void test_bitwise_and(int rows, int cols, int type)
{
Mat src1(rows, cols, type);
Mat src2(rows, cols, type);
RNG rng;
for (int i = 0; i < src1.rows; ++i)
{
Mat row1(1, src1.cols * src1.elemSize(), CV_8U, src1.ptr(i));
rng.fill(row1, RNG::UNIFORM, Scalar(0), Scalar(255));
Mat row2(1, src2.cols * src2.elemSize(), CV_8U, src2.ptr(i));
rng.fill(row2, RNG::UNIFORM, Scalar(0), Scalar(255));
}
Mat dst_gold = src1 & src2;
gpu::GpuMat dst = gpu::GpuMat(src1) & gpu::GpuMat(src2);
CHECK(dst_gold.size() == dst.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(dst_gold.type() == dst.type(), cvtest::TS::FAIL_INVALID_OUTPUT);
Mat dsth(dst);
for (int i = 0; i < dst_gold.rows; ++i)
CHECK(memcmp(dst_gold.ptr(i), dsth.ptr(i), dst_gold.cols * dst_gold.elemSize()) == 0, cvtest::TS::FAIL_INVALID_OUTPUT)
Mat mask(src1.size(), CV_8U);
randu(mask, Scalar(0), Scalar(255));
Mat dst_gold2(dst_gold.size(), dst_gold.type()); dst_gold2.setTo(Scalar::all(0));
gpu::GpuMat dst2(dst.size(), dst.type()); dst2.setTo(Scalar::all(0));
bitwise_and(src1, src2, dst_gold2, mask);
gpu::bitwise_and(gpu::GpuMat(src1), gpu::GpuMat(src2), dst2, gpu::GpuMat(mask));
CHECK(dst_gold2.size() == dst2.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(dst_gold2.type() == dst2.type(), cvtest::TS::FAIL_INVALID_OUTPUT);
dsth = dst2;
for (int i = 0; i < dst_gold.rows; ++i)
CHECK(memcmp(dst_gold2.ptr(i), dsth.ptr(i), dst_gold2.cols * dst_gold2.elemSize()) == 0, cvtest::TS::FAIL_INVALID_OUTPUT)
}
void test_bitwise_xor(int rows, int cols, int type)
{
Mat src1(rows, cols, type);
Mat src2(rows, cols, type);
RNG rng;
for (int i = 0; i < src1.rows; ++i)
{
Mat row1(1, src1.cols * src1.elemSize(), CV_8U, src1.ptr(i));
rng.fill(row1, RNG::UNIFORM, Scalar(0), Scalar(255));
Mat row2(1, src2.cols * src2.elemSize(), CV_8U, src2.ptr(i));
rng.fill(row2, RNG::UNIFORM, Scalar(0), Scalar(255));
}
Mat dst_gold = src1 ^ src2;
gpu::GpuMat dst = gpu::GpuMat(src1) ^ gpu::GpuMat(src2);
CHECK(dst_gold.size() == dst.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(dst_gold.type() == dst.type(), cvtest::TS::FAIL_INVALID_OUTPUT);
Mat dsth(dst);
for (int i = 0; i < dst_gold.rows; ++i)
CHECK(memcmp(dst_gold.ptr(i), dsth.ptr(i), dst_gold.cols * dst_gold.elemSize()) == 0, cvtest::TS::FAIL_INVALID_OUTPUT)
Mat mask(src1.size(), CV_8U);
randu(mask, Scalar(0), Scalar(255));
Mat dst_gold2(dst_gold.size(), dst_gold.type()); dst_gold2.setTo(Scalar::all(0));
gpu::GpuMat dst2(dst.size(), dst.type()); dst2.setTo(Scalar::all(0));
bitwise_xor(src1, src2, dst_gold2, mask);
gpu::bitwise_xor(gpu::GpuMat(src1), gpu::GpuMat(src2), dst2, gpu::GpuMat(mask));
CHECK(dst_gold2.size() == dst2.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(dst_gold2.type() == dst2.type(), cvtest::TS::FAIL_INVALID_OUTPUT);
dsth = dst2;
for (int i = 0; i < dst_gold.rows; ++i)
CHECK(memcmp(dst_gold2.ptr(i), dsth.ptr(i), dst_gold2.cols * dst_gold2.elemSize()) == 0, cvtest::TS::FAIL_INVALID_OUTPUT)
}
};
TEST(BitwiseOperations, accuracy) { CV_GpuBitwiseTest test; test; }
/*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 "test_precomp.hpp"
#include <algorithm>
#include <iterator>
using namespace cv;
using namespace cv::gpu;
using namespace std;
class CV_GpuBruteForceMatcherTest : public cvtest::BaseTest
{
public:
CV_GpuBruteForceMatcherTest()
{
}
protected:
virtual void run(int);
void emptyDataTest();
void dataTest(int dim);
void generateData(GpuMat& query, GpuMat& train, int dim);
void matchTest(const GpuMat& query, const GpuMat& train);
void knnMatchTest(const GpuMat& query, const GpuMat& train);
void radiusMatchTest(const GpuMat& query, const GpuMat& train);
private:
BruteForceMatcher_GPU< L2<float> > dmatcher;
static const int queryDescCount = 300; // must be even number because we split train data in some cases in two
static const int countFactor = 4; // do not change it
};
void CV_GpuBruteForceMatcherTest::emptyDataTest()
{
GpuMat queryDescriptors, trainDescriptors, mask;
vector<GpuMat> trainDescriptorCollection, masks;
vector<DMatch> matches;
vector< vector<DMatch> > vmatches;
try
{
dmatcher.match(queryDescriptors, trainDescriptors, matches, mask);
}
catch(...)
{
ts->printf( cvtest::TS::LOG, "match() on empty descriptors must not generate exception (1).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
try
{
dmatcher.knnMatch(queryDescriptors, trainDescriptors, vmatches, 2, mask);
}
catch(...)
{
ts->printf( cvtest::TS::LOG, "knnMatch() on empty descriptors must not generate exception (1).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
try
{
dmatcher.radiusMatch(queryDescriptors, trainDescriptors, vmatches, 10.f, mask);
}
catch(...)
{
ts->printf( cvtest::TS::LOG, "radiusMatch() on empty descriptors must not generate exception (1).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
try
{
dmatcher.add(trainDescriptorCollection);
}
catch(...)
{
ts->printf( cvtest::TS::LOG, "add() on empty descriptors must not generate exception.\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
try
{
dmatcher.match(queryDescriptors, matches, masks);
}
catch(...)
{
ts->printf( cvtest::TS::LOG, "match() on empty descriptors must not generate exception (2).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
try
{
dmatcher.knnMatch(queryDescriptors, vmatches, 2, masks);
}
catch(...)
{
ts->printf( cvtest::TS::LOG, "knnMatch() on empty descriptors must not generate exception (2).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
try
{
dmatcher.radiusMatch( queryDescriptors, vmatches, 10.f, masks );
}
catch(...)
{
ts->printf( cvtest::TS::LOG, "radiusMatch() on empty descriptors must not generate exception (2).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
}
void CV_GpuBruteForceMatcherTest::generateData( GpuMat& queryGPU, GpuMat& trainGPU, int dim )
{
Mat query, train;
RNG& rng = ts->get_rng();
// Generate query descriptors randomly.
// Descriptor vector elements are integer values.
Mat buf( queryDescCount, dim, CV_32SC1 );
rng.fill( buf, RNG::UNIFORM, Scalar::all(0), Scalar(3) );
buf.convertTo( query, CV_32FC1 );
// Generate train decriptors as follows:
// copy each query descriptor to train set countFactor times
// and perturb some one element of the copied descriptors in
// in ascending order. General boundaries of the perturbation
// are (0.f, 1.f).
train.create( query.rows*countFactor, query.cols, CV_32FC1 );
float step = 1.f / countFactor;
for( int qIdx = 0; qIdx < query.rows; qIdx++ )
{
Mat queryDescriptor = query.row(qIdx);
for( int c = 0; c < countFactor; c++ )
{
int tIdx = qIdx * countFactor + c;
Mat trainDescriptor = train.row(tIdx);
queryDescriptor.copyTo( trainDescriptor );
int elem = rng(dim);
float diff = rng.uniform( step*c, step*(c+1) );
trainDescriptor.at<float>(0, elem) += diff;
}
}
queryGPU.upload(query);
trainGPU.upload(train);
}
void CV_GpuBruteForceMatcherTest::matchTest( const GpuMat& query, const GpuMat& train )
{
dmatcher.clear();
// test const version of match()
{
vector<DMatch> matches;
dmatcher.match( query, train, matches );
if( (int)matches.size() != queryDescCount )
{
ts->printf(cvtest::TS::LOG, "Incorrect matches count while test match() function (1).\n");
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
else
{
int badCount = 0;
for( size_t i = 0; i < matches.size(); i++ )
{
DMatch match = matches[i];
if( (match.queryIdx != (int)i) || (match.trainIdx != (int)i*countFactor) || (match.imgIdx != 0) )
badCount++;
}
if (badCount > 0)
{
ts->printf( cvtest::TS::LOG, "%f - too large bad matches part while test match() function (1).\n",
(float)badCount/(float)queryDescCount );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
}
}
// test version of match() with add()
{
vector<DMatch> matches;
// make add() twice to test such case
dmatcher.add( vector<GpuMat>(1,train.rowRange(0, train.rows/2)) );
dmatcher.add( vector<GpuMat>(1,train.rowRange(train.rows/2, train.rows)) );
// prepare masks (make first nearest match illegal)
vector<GpuMat> masks(2);
for(int mi = 0; mi < 2; mi++ )
{
masks[mi] = GpuMat(query.rows, train.rows/2, CV_8UC1, Scalar::all(1));
for( int di = 0; di < queryDescCount/2; di++ )
masks[mi].col(di*countFactor).setTo(Scalar::all(0));
}
dmatcher.match( query, matches, masks );
if( (int)matches.size() != queryDescCount )
{
ts->printf(cvtest::TS::LOG, "Incorrect matches count while test match() function (2).\n");
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
else
{
int badCount = 0;
for( size_t i = 0; i < matches.size(); i++ )
{
DMatch match = matches[i];
int shift = dmatcher.isMaskSupported() ? 1 : 0;
{
if( i < queryDescCount/2 )
{
if( (match.queryIdx != (int)i) || (match.trainIdx != (int)i*countFactor + shift) || (match.imgIdx != 0) )
badCount++;
}
else
{
if( (match.queryIdx != (int)i) || (match.trainIdx != ((int)i-queryDescCount/2)*countFactor + shift) || (match.imgIdx != 1) )
badCount++;
}
}
}
if (badCount > 0)
{
ts->printf( cvtest::TS::LOG, "%f - too large bad matches part while test match() function (2).\n",
(float)badCount/(float)queryDescCount );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
}
}
}
}
void CV_GpuBruteForceMatcherTest::knnMatchTest( const GpuMat& query, const GpuMat& train )
{
dmatcher.clear();
// test const version of knnMatch()
{
const int knn = 3;
vector< vector<DMatch> > matches;
dmatcher.knnMatch( query, train, matches, knn );
if( (int)matches.size() != queryDescCount )
{
ts->printf(cvtest::TS::LOG, "Incorrect matches count while test knnMatch() function (1).\n");
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
else
{
int badCount = 0;
for( size_t i = 0; i < matches.size(); i++ )
{
if( (int)matches[i].size() != knn )
badCount++;
else
{
int localBadCount = 0;
for( int k = 0; k < knn; k++ )
{
DMatch match = matches[i][k];
if( (match.queryIdx != (int)i) || (match.trainIdx != (int)i*countFactor+k) || (match.imgIdx != 0) )
localBadCount++;
}
badCount += localBadCount > 0 ? 1 : 0;
}
}
if (badCount > 0)
{
ts->printf( cvtest::TS::LOG, "%f - too large bad matches part while test knnMatch() function (1).\n",
(float)badCount/(float)queryDescCount );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
}
}
// test version of knnMatch() with add()
{
const int knn = 2;
vector<vector<DMatch> > matches;
// make add() twice to test such case
dmatcher.add( vector<GpuMat>(1,train.rowRange(0, train.rows/2)) );
dmatcher.add( vector<GpuMat>(1,train.rowRange(train.rows/2, train.rows)) );
// prepare masks (make first nearest match illegal)
vector<GpuMat> masks(2);
for(int mi = 0; mi < 2; mi++ )
{
masks[mi] = GpuMat(query.rows, train.rows/2, CV_8UC1, Scalar::all(1));
for( int di = 0; di < queryDescCount/2; di++ )
masks[mi].col(di*countFactor).setTo(Scalar::all(0));
}
dmatcher.knnMatch( query, matches, knn, masks );
if( (int)matches.size() != queryDescCount )
{
ts->printf(cvtest::TS::LOG, "Incorrect matches count while test knnMatch() function (2).\n");
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
else
{
int badCount = 0;
int shift = dmatcher.isMaskSupported() ? 1 : 0;
for( size_t i = 0; i < matches.size(); i++ )
{
if( (int)matches[i].size() != knn )
badCount++;
else
{
int localBadCount = 0;
for( int k = 0; k < knn; k++ )
{
DMatch match = matches[i][k];
{
if( i < queryDescCount/2 )
{
if( (match.queryIdx != (int)i) || (match.trainIdx != (int)i*countFactor + k + shift) ||
(match.imgIdx != 0) )
localBadCount++;
}
else
{
if( (match.queryIdx != (int)i) || (match.trainIdx != ((int)i-queryDescCount/2)*countFactor + k + shift) ||
(match.imgIdx != 1) )
localBadCount++;
}
}
}
badCount += localBadCount > 0 ? 1 : 0;
}
}
if (badCount > 0)
{
ts->printf( cvtest::TS::LOG, "%f - too large bad matches part while test knnMatch() function (2).\n",
(float)badCount/(float)queryDescCount );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
}
}
}
}
void CV_GpuBruteForceMatcherTest::radiusMatchTest( const GpuMat& query, const GpuMat& train )
{
bool atomics_ok = TargetArchs::builtWith(GLOBAL_ATOMICS) && DeviceInfo().supports(GLOBAL_ATOMICS);
if (!atomics_ok)
{
ts->printf(cvtest::TS::CONSOLE, "\nCode and device atomics support is required for radiusMatch (CC >= 1.1)");
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
dmatcher.clear();
// test const version of match()
{
const float radius = 1.f/countFactor;
vector< vector<DMatch> > matches;
dmatcher.radiusMatch( query, train, matches, radius );
if( (int)matches.size() != queryDescCount )
{
ts->printf(cvtest::TS::LOG, "Incorrect matches count while test radiusMatch() function (1).\n");
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
else
{
int badCount = 0;
for( size_t i = 0; i < matches.size(); i++ )
{
if( (int)matches[i].size() != 1 )
badCount++;
else
{
DMatch match = matches[i][0];
if( (match.queryIdx != (int)i) || (match.trainIdx != (int)i*countFactor) || (match.imgIdx != 0) )
badCount++;
}
}
if (badCount > 0)
{
ts->printf( cvtest::TS::LOG, "%f - too large bad matches part while test radiusMatch() function (1).\n",
(float)badCount/(float)queryDescCount );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
}
}
// test version of match() with add()
{
int n = 3;
const float radius = 1.f/countFactor * n;
vector< vector<DMatch> > matches;
// make add() twice to test such case
dmatcher.add( vector<GpuMat>(1,train.rowRange(0, train.rows/2)) );
dmatcher.add( vector<GpuMat>(1,train.rowRange(train.rows/2, train.rows)) );
// prepare masks (make first nearest match illegal)
vector<GpuMat> masks(2);
for(int mi = 0; mi < 2; mi++ )
{
masks[mi] = GpuMat(query.rows, train.rows/2, CV_8UC1, Scalar::all(1));
for( int di = 0; di < queryDescCount/2; di++ )
masks[mi].col(di*countFactor).setTo(Scalar::all(0));
}
dmatcher.radiusMatch( query, matches, radius, masks );
int curRes = cvtest::TS::OK;
if( (int)matches.size() != queryDescCount )
{
ts->printf(cvtest::TS::LOG, "Incorrect matches count while test radiusMatch() function (1).\n");
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
int badCount = 0;
int shift = dmatcher.isMaskSupported() ? 1 : 0;
int needMatchCount = dmatcher.isMaskSupported() ? n-1 : n;
for( size_t i = 0; i < matches.size(); i++ )
{
if( (int)matches[i].size() != needMatchCount )
badCount++;
else
{
int localBadCount = 0;
for( int k = 0; k < needMatchCount; k++ )
{
DMatch match = matches[i][k];
{
if( i < queryDescCount/2 )
{
if( (match.queryIdx != (int)i) || (match.trainIdx != (int)i*countFactor + k + shift) ||
(match.imgIdx != 0) )
localBadCount++;
}
else
{
if( (match.queryIdx != (int)i) || (match.trainIdx != ((int)i-queryDescCount/2)*countFactor + k + shift) ||
(match.imgIdx != 1) )
localBadCount++;
}
}
}
badCount += localBadCount > 0 ? 1 : 0;
}
}
if (badCount > 0)
{
curRes = cvtest::TS::FAIL_INVALID_OUTPUT;
ts->printf( cvtest::TS::LOG, "%f - too large bad matches part while test radiusMatch() function (2).\n",
(float)badCount/(float)queryDescCount );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
}
}
}
void CV_GpuBruteForceMatcherTest::dataTest(int dim)
{
GpuMat query, train;
generateData(query, train, dim);
matchTest(query, train);
knnMatchTest(query, train);
radiusMatchTest(query, train);
dmatcher.clear();
}
void CV_GpuBruteForceMatcherTest::run(int)
{
emptyDataTest();
dataTest(50);
dataTest(64);
dataTest(100);
dataTest(128);
dataTest(200);
dataTest(256);
dataTest(300);
}
TEST(BruteForceMatcher, accuracy) { CV_GpuBruteForceMatcherTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
using namespace cv;
using namespace cv::gpu;
using namespace std;
struct CV_GpuMulSpectrumsTest: cvtest::BaseTest
{
CV_GpuMulSpectrumsTest() {}
void run(int)
{
test(0);
testConj(0);
testScaled(0);
testScaledConj(0);
test(DFT_ROWS);
testConj(DFT_ROWS);
testScaled(DFT_ROWS);
testScaledConj(DFT_ROWS);
}
void gen(int cols, int rows, Mat& mat)
{
RNG rng;
mat.create(rows, cols, CV_32FC2);
rng.fill(mat, RNG::UNIFORM, Scalar::all(0.f), Scalar::all(10.f));
}
bool cmp(const Mat& gold, const Mat& mine, float max_err=1e-3f)
{
if (gold.size() != mine.size())
{
ts->printf(cvtest::TS::CONSOLE, "bad sizes: gold: %d d%, mine: %d %d\n", gold.cols, gold.rows, mine.cols, mine.rows);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
if (gold.type() != mine.type())
{
ts->printf(cvtest::TS::CONSOLE, "bad types: gold=%d, mine=%d\n", gold.type(), mine.type());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
for (int i = 0; i < gold.rows; ++i)
{
for (int j = 0; j < gold.cols * 2; ++j)
{
float gold_ = gold.at<float>(i, j);
float mine_ = mine.at<float>(i, j);
if (fabs(gold_ - mine_) > max_err)
{
ts->printf(cvtest::TS::CONSOLE, "bad values at %d %d: gold=%f, mine=%f\n", j, i, gold_, mine_);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
}
}
return true;
}
bool cmpScaled(const Mat& gold, const Mat& mine, float scale, float max_err=1e-3f)
{
if (gold.size() != mine.size())
{
ts->printf(cvtest::TS::CONSOLE, "bad sizes: gold: %d d%, mine: %d %d\n", gold.cols, gold.rows, mine.cols, mine.rows);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
if (gold.type() != mine.type())
{
ts->printf(cvtest::TS::CONSOLE, "bad types: gold=%d, mine=%d\n", gold.type(), mine.type());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
for (int i = 0; i < gold.rows; ++i)
{
for (int j = 0; j < gold.cols * 2; ++j)
{
float gold_ = gold.at<float>(i, j) * scale;
float mine_ = mine.at<float>(i, j);
if (fabs(gold_ - mine_) > max_err)
{
ts->printf(cvtest::TS::CONSOLE, "bad values at %d %d: gold=%f, mine=%f\n", j, i, gold_, mine_);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
}
}
return true;
}
void test(int flags)
{
int cols = 1 + rand() % 100, rows = 1 + rand() % 1000;
Mat a, b;
gen(cols, rows, a);
gen(cols, rows, b);
Mat c_gold;
mulSpectrums(a, b, c_gold, flags, false);
GpuMat d_c;
mulSpectrums(GpuMat(a), GpuMat(b), d_c, flags, false);
if (!cmp(c_gold, Mat(d_c)))
ts->printf(cvtest::TS::CONSOLE, "test failed: cols=%d, rows=%d, flags=%d\n", cols, rows, flags);
}
void testConj(int flags)
{
int cols = 1 + rand() % 100, rows = 1 + rand() % 1000;
Mat a, b;
gen(cols, rows, a);
gen(cols, rows, b);
Mat c_gold;
mulSpectrums(a, b, c_gold, flags, true);
GpuMat d_c;
mulSpectrums(GpuMat(a), GpuMat(b), d_c, flags, true);
if (!cmp(c_gold, Mat(d_c)))
ts->printf(cvtest::TS::CONSOLE, "testConj failed: cols=%d, rows=%d, flags=%d\n", cols, rows, flags);
}
void testScaled(int flags)
{
int cols = 1 + rand() % 100, rows = 1 + rand() % 1000;
Mat a, b;
gen(cols, rows, a);
gen(cols, rows, b);
float scale = 1.f / a.size().area();
Mat c_gold;
mulSpectrums(a, b, c_gold, flags, false);
GpuMat d_c;
mulAndScaleSpectrums(GpuMat(a), GpuMat(b), d_c, flags, scale, false);
if (!cmpScaled(c_gold, Mat(d_c), scale))
ts->printf(cvtest::TS::CONSOLE, "testScaled failed: cols=%d, rows=%d, flags=%d\n", cols, rows, flags);
}
void testScaledConj(int flags)
{
int cols = 1 + rand() % 100, rows = 1 + rand() % 1000;
Mat a, b;
gen(cols, rows, a);
gen(cols, rows, b);
float scale = 1.f / a.size().area();
Mat c_gold;
mulSpectrums(a, b, c_gold, flags, true);
GpuMat d_c;
mulAndScaleSpectrums(GpuMat(a), GpuMat(b), d_c, flags, scale, true);
if (!cmpScaled(c_gold, Mat(d_c), scale))
ts->printf(cvtest::TS::CONSOLE, "testScaledConj failed: cols=%d, rows=%d, flags=%D\n", cols, rows, flags);
}
} CV_GpuMulSpectrumsTest_inst;
struct CV_GpuDftTest: cvtest::BaseTest
{
CV_GpuDftTest() {}
void run(int)
{
srand(0);
int cols = 2 + rand() % 100, rows = 2 + rand() % 100;
for (int i = 0; i < 2; ++i)
{
bool inplace = i != 0;
testC2C("no flags", cols, rows, 0, inplace);
testC2C("no flags 0 1", cols, rows + 1, 0, inplace);
testC2C("no flags 1 0", cols, rows + 1, 0, inplace);
testC2C("no flags 1 1", cols + 1, rows, 0, inplace);
testC2C("DFT_INVERSE", cols, rows, DFT_INVERSE, inplace);
testC2C("DFT_ROWS", cols, rows, DFT_ROWS, inplace);
testC2C("single col", 1, rows, 0, inplace);
testC2C("single row", cols, 1, 0, inplace);
testC2C("single col inversed", 1, rows, DFT_INVERSE, inplace);
testC2C("single row inversed", cols, 1, DFT_INVERSE, inplace);
testC2C("single row DFT_ROWS", cols, 1, DFT_ROWS, inplace);
testC2C("size 1 2", 1, 2, 0, inplace);
testC2C("size 2 1", 2, 1, 0, inplace);
}
testR2CThenC2R("sanity", cols, rows);
testR2CThenC2R("sanity 0 1", cols, rows + 1);
testR2CThenC2R("sanity 1 0", cols + 1, rows);
testR2CThenC2R("sanity 1 1", cols + 1, rows + 1);
testR2CThenC2R("single col", 1, rows);
testR2CThenC2R("single col 1", 1, rows + 1);
testR2CThenC2R("single row", cols, 1);
testR2CThenC2R("single row 1", cols + 1, 1);
testR2CThenC2R("sanity", cols, rows, true);
testR2CThenC2R("sanity 0 1", cols, rows + 1, true);
testR2CThenC2R("sanity 1 0", cols + 1, rows, true);
testR2CThenC2R("sanity 1 1", cols + 1, rows + 1, true);
testR2CThenC2R("single row", cols, 1, true);
testR2CThenC2R("single row 1", cols + 1, 1, true);
}
void gen(int cols, int rows, int cn, Mat& mat)
{
RNG rng(1);
mat.create(rows, cols, CV_MAKETYPE(CV_32F, cn));
rng.fill(mat, RNG::UNIFORM, Scalar::all(0.f), Scalar::all(10.f));
}
bool cmp(const Mat& gold, const Mat& mine, float max_err=1e-3f)
{
if (gold.size() != mine.size())
{
ts->printf(cvtest::TS::CONSOLE, "bad sizes: gold: %d %d, mine: %d %d\n", gold.cols, gold.rows, mine.cols, mine.rows);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
if (gold.depth() != mine.depth())
{
ts->printf(cvtest::TS::CONSOLE, "bad depth: gold=%d, mine=%d\n", gold.depth(), mine.depth());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
if (gold.channels() != mine.channels())
{
ts->printf(cvtest::TS::CONSOLE, "bad channel count: gold=%d, mine=%d\n", gold.channels(), mine.channels());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
for (int i = 0; i < gold.rows; ++i)
{
for (int j = 0; j < gold.cols * gold.channels(); ++j)
{
float gold_ = gold.at<float>(i, j);
float mine_ = mine.at<float>(i, j);
if (fabs(gold_ - mine_) > max_err)
{
ts->printf(cvtest::TS::CONSOLE, "bad values at %d %d: gold=%f, mine=%f\n", j / gold.channels(), i, gold_, mine_);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
}
}
return true;
}
void testC2C(const std::string& hint, int cols, int rows, int flags, bool inplace=false)
{
Mat a;
gen(cols, rows, 2, a);
Mat b_gold;
dft(a, b_gold, flags);
GpuMat d_b;
GpuMat d_b_data;
if (inplace)
{
d_b_data.create(1, a.size().area(), CV_32FC2);
d_b = GpuMat(a.rows, a.cols, CV_32FC2, d_b_data.ptr(), a.cols * d_b_data.elemSize());
}
dft(GpuMat(a), d_b, Size(cols, rows), flags);
bool ok = true;
if (ok && inplace && d_b.ptr() != d_b_data.ptr())
{
ts->printf(cvtest::TS::CONSOLE, "unnecessary reallocation was done\n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
ok = false;
}
if (ok && d_b.depth() != CV_32F)
{
ts->printf(cvtest::TS::CONSOLE, "bad depth: %d\n", d_b.depth());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
ok = false;
}
if (ok && d_b.channels() != 2)
{
ts->printf(cvtest::TS::CONSOLE, "bad channel count: %d\n", d_b.channels());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
ok = false;
}
if (ok) ok = cmp(b_gold, Mat(d_b), rows * cols * 1e-4f);
if (!ok)
ts->printf(cvtest::TS::CONSOLE, "testC2C failed: hint=%s, cols=%d, rows=%d, flags=%d, inplace=%d\n",
hint.c_str(), cols, rows, flags, inplace);
}
void testR2CThenC2R(const std::string& hint, int cols, int rows, bool inplace=false)
{
Mat a;
gen(cols, rows, 1, a);
bool ok = true;
GpuMat d_b, d_c;
GpuMat d_b_data, d_c_data;
if (inplace)
{
if (a.cols == 1)
{
d_b_data.create(1, (a.rows / 2 + 1) * a.cols, CV_32FC2);
d_b = GpuMat(a.rows / 2 + 1, a.cols, CV_32FC2, d_b_data.ptr(), a.cols * d_b_data.elemSize());
}
else
{
d_b_data.create(1, a.rows * (a.cols / 2 + 1), CV_32FC2);
d_b = GpuMat(a.rows, a.cols / 2 + 1, CV_32FC2, d_b_data.ptr(), (a.cols / 2 + 1) * d_b_data.elemSize());
}
d_c_data.create(1, a.size().area(), CV_32F);
d_c = GpuMat(a.rows, a.cols, CV_32F, d_c_data.ptr(), a.cols * d_c_data.elemSize());
}
dft(GpuMat(a), d_b, Size(cols, rows), 0);
dft(d_b, d_c, Size(cols, rows), DFT_REAL_OUTPUT | DFT_SCALE);
if (ok && inplace && d_b.ptr() != d_b_data.ptr())
{
ts->printf(cvtest::TS::CONSOLE, "unnecessary reallocation was done for b\n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
ok = false;
}
if (ok && inplace && d_c.ptr() != d_c_data.ptr())
{
ts->printf(cvtest::TS::CONSOLE, "unnecessary reallocation was done for c\n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
ok = false;
}
if (ok && d_c.depth() != CV_32F)
{
ts->printf(cvtest::TS::CONSOLE, "bad depth: %d\n", d_c.depth());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
ok = false;
}
if (ok && d_c.channels() != 1)
{
ts->printf(cvtest::TS::CONSOLE, "bad channel count: %d\n", d_c.channels());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
ok = false;
}
if (ok) ok = cmp(a, Mat(d_c), rows * cols * 1e-5f);
if (!ok)
ts->printf(cvtest::TS::CONSOLE, "testR2CThenC2R failed: hint=%s, cols=%d, rows=%d, inplace=%d\n",
hint.c_str(), cols, rows, inplace);
}
};
TEST(dft, accuracy) { CV_GpuDftTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
#include <string>
using namespace cv;
using namespace cv::gpu;
using namespace std;
const string FEATURES2D_DIR = "features2d";
const string IMAGE_FILENAME = "aloe.png";
const string VALID_FILE_NAME = "surf.xml.gz";
class CV_GPU_SURFTest : public cvtest::BaseTest
{
public:
CV_GPU_SURFTest()
{
}
protected:
bool isSimilarKeypoints(const KeyPoint& p1, const KeyPoint& p2);
void compareKeypointSets(const vector<KeyPoint>& validKeypoints, const vector<KeyPoint>& calcKeypoints,
const Mat& validDescriptors, const Mat& calcDescriptors);
void emptyDataTest(SURF_GPU& fdetector);
void regressionTest(SURF_GPU& fdetector);
virtual void run(int);
};
void CV_GPU_SURFTest::emptyDataTest(SURF_GPU& fdetector)
{
GpuMat image;
vector<KeyPoint> keypoints;
vector<float> descriptors;
try
{
fdetector(image, GpuMat(), keypoints, descriptors);
}
catch(...)
{
ts->printf( cvtest::TS::LOG, "detect() on empty image must not generate exception (1).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
if( !keypoints.empty() )
{
ts->printf( cvtest::TS::LOG, "detect() on empty image must return empty keypoints vector (1).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
if( !descriptors.empty() )
{
ts->printf( cvtest::TS::LOG, "detect() on empty image must return empty descriptors vector (1).\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
}
bool CV_GPU_SURFTest::isSimilarKeypoints(const KeyPoint& p1, const KeyPoint& p2)
{
const float maxPtDif = 1.f;
const float maxSizeDif = 1.f;
const float maxAngleDif = 2.f;
const float maxResponseDif = 0.1f;
float dist = (float)norm( p1.pt - p2.pt );
return (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 );
}
void CV_GPU_SURFTest::compareKeypointSets(const vector<KeyPoint>& validKeypoints, const vector<KeyPoint>& calcKeypoints,
const Mat& validDescriptors, const Mat& calcDescriptors)
{
if (validKeypoints.size() != calcKeypoints.size())
{
ts->printf(cvtest::TS::LOG, "Keypoints sizes doesn't equal (validCount = %d, calcCount = %d).\n",
validKeypoints.size(), calcKeypoints.size());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
if (validDescriptors.size() != calcDescriptors.size())
{
ts->printf(cvtest::TS::LOG, "Descriptors sizes doesn't equal.\n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
for (size_t v = 0; v < validKeypoints.size(); v++)
{
int nearestIdx = -1;
float minDist = std::numeric_limits<float>::max();
for (size_t c = 0; c < calcKeypoints.size(); c++)
{
float curDist = (float)norm(calcKeypoints[c].pt - validKeypoints[v].pt);
if (curDist < minDist)
{
minDist = curDist;
nearestIdx = c;
}
}
assert(minDist >= 0);
if (!isSimilarKeypoints(validKeypoints[v], calcKeypoints[nearestIdx]))
{
ts->printf(cvtest::TS::LOG, "Bad keypoints accuracy.\n");
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}
if (norm(validDescriptors.row(v), calcDescriptors.row(nearestIdx), NORM_L2) > 1.5f)
{
ts->printf(cvtest::TS::LOG, "Bad descriptors accuracy.\n");
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}
}
}
void CV_GPU_SURFTest::regressionTest(SURF_GPU& fdetector)
{
string imgFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME;
string resFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + VALID_FILE_NAME;
// Read the test image.
GpuMat image(imread(imgFilename, 0));
if (image.empty())
{
ts->printf( cvtest::TS::LOG, "Image %s can not be read.\n", imgFilename.c_str() );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
FileStorage fs(resFilename, FileStorage::READ);
// Compute keypoints.
GpuMat mask(image.size(), CV_8UC1, Scalar::all(1));
mask(Range(0, image.rows / 2), Range(0, image.cols / 2)).setTo(Scalar::all(0));
vector<KeyPoint> calcKeypoints;
GpuMat calcDespcriptors;
fdetector(image, mask, calcKeypoints, calcDespcriptors);
if (fs.isOpened()) // Compare computed and valid keypoints.
{
// Read validation keypoints set.
vector<KeyPoint> validKeypoints;
Mat validDespcriptors;
read(fs["keypoints"], validKeypoints);
read(fs["descriptors"], validDespcriptors);
if (validKeypoints.empty() || validDespcriptors.empty())
{
ts->printf(cvtest::TS::LOG, "Validation file can not be read.\n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
return;
}
compareKeypointSets(validKeypoints, calcKeypoints, validDespcriptors, calcDespcriptors);
}
else // Write detector parameters and computed keypoints as validation data.
{
fs.open(resFilename, FileStorage::WRITE);
if (!fs.isOpened())
{
ts->printf(cvtest::TS::LOG, "File %s can not be opened to write.\n", resFilename.c_str());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
return;
}
else
{
write(fs, "keypoints", calcKeypoints);
write(fs, "descriptors", (Mat)calcDespcriptors);
}
}
}
void CV_GPU_SURFTest::run( int /*start_from*/ )
{
SURF_GPU fdetector;
emptyDataTest(fdetector);
regressionTest(fdetector);
}
TEST(SURF, empty_data_and_regression) { CV_GPU_SURFTest test; test.safe_run(); }
/*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 <iostream>
#include <cmath>
#include <limits>
#include "test_precomp.hpp"
using namespace cv;
using namespace std;
using namespace gpu;
class CV_GpuNppFilterTest : public cvtest::BaseTest
{
public:
CV_GpuNppFilterTest(const char* test_name, const char* test_funcs) {}
virtual ~CV_GpuNppFilterTest() {}
protected:
void run(int);
virtual int test(const Mat& img) = 0;
int test8UC1(const Mat& img)
{
cv::Mat img_C1;
cvtColor(img, img_C1, CV_BGR2GRAY);
return test(img_C1);
}
int test8UC4(const Mat& img)
{
cv::Mat img_C4;
cvtColor(img, img_C4, CV_BGR2BGRA);
return test(img_C4);
}
int CheckNorm(const Mat& m1, const Mat& m2, const Size& ksize)
{
Rect roi = Rect(ksize.width, ksize.height, m1.cols - 2 * ksize.width, m1.rows - 2 * ksize.height);
Mat m1ROI = m1(roi);
Mat m2ROI = m2(roi);
double res = norm(m1ROI, m2ROI, NORM_INF);
// Max difference (2.0) in GaussianBlur
if (res <= 2)
return cvtest::TS::OK;
ts->printf(cvtest::TS::LOG, "Norm: %f\n", res);
return cvtest::TS::FAIL_GENERIC;
}
};
void CV_GpuNppFilterTest::run( int )
{
cv::Mat img = cv::imread(std::string(ts->get_data_path()) + "stereobp/aloe-L.png");
if (img.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
//run tests
int testResult = cvtest::TS::OK;
if (test8UC1(img) != cvtest::TS::OK)
testResult = cvtest::TS::FAIL_GENERIC;
if (test8UC4(img) != cvtest::TS::OK)
testResult = cvtest::TS::FAIL_GENERIC;
ts->set_failed_test_info(testResult);
ts->set_failed_test_info(cvtest::TS::OK);
}
////////////////////////////////////////////////////////////////////////////////
// blur
struct CV_GpuNppImageBlurTest : public CV_GpuNppFilterTest
{
CV_GpuNppImageBlurTest() : CV_GpuNppFilterTest( "GPU-NppImageBlur", "blur" ) {}
int test(const Mat& img)
{
int ksizes[] = {3, 5, 7};
int ksizes_num = sizeof(ksizes) / sizeof(int);
int test_res = cvtest::TS::OK;
for (int i = 0; i < ksizes_num; ++i)
{
for (int j = 0; j < ksizes_num; ++j)
{
Size ksize(ksizes[i], ksizes[j]);
ts->printf(cvtest::TS::LOG, "\nksize = (%dx%d)\n", ksizes[i], ksizes[j]);
Mat cpudst;
cv::blur(img, cpudst, ksize);
GpuMat gpu1(img);
GpuMat gpudst;
cv::gpu::blur(gpu1, gpudst, ksize);
if (CheckNorm(cpudst, gpudst, ksize) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// Sobel
struct CV_GpuNppImageSobelTest : public CV_GpuNppFilterTest
{
CV_GpuNppImageSobelTest() : CV_GpuNppFilterTest( "GPU-NppImageSobel", "Sobel" ) {}
int test(const Mat& img)
{
int ksizes[] = {3, 5, 7};
int ksizes_num = sizeof(ksizes) / sizeof(int);
int dx = 1, dy = 0;
int test_res = cvtest::TS::OK;
for (int i = 0; i < ksizes_num; ++i)
{
ts->printf(cvtest::TS::LOG, "\nksize = %d\n", ksizes[i]);
Mat cpudst;
cv::Sobel(img, cpudst, -1, dx, dy, ksizes[i]);
GpuMat gpu1(img);
GpuMat gpudst;
cv::gpu::Sobel(gpu1, gpudst, -1, dx, dy, ksizes[i]);
if (CheckNorm(cpudst, gpudst, Size(ksizes[i], ksizes[i])) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// Scharr
struct CV_GpuNppImageScharrTest : public CV_GpuNppFilterTest
{
CV_GpuNppImageScharrTest() : CV_GpuNppFilterTest( "GPU-NppImageScharr", "Scharr" ) {}
int test(const Mat& img)
{
int dx = 1, dy = 0;
Mat cpudst;
cv::Scharr(img, cpudst, -1, dx, dy);
GpuMat gpu1(img);
GpuMat gpudst;
cv::gpu::Scharr(gpu1, gpudst, -1, dx, dy);
return CheckNorm(cpudst, gpudst, Size(3, 3));
}
};
////////////////////////////////////////////////////////////////////////////////
// GaussianBlur
struct CV_GpuNppImageGaussianBlurTest : public CV_GpuNppFilterTest
{
CV_GpuNppImageGaussianBlurTest() : CV_GpuNppFilterTest( "GPU-NppImageGaussianBlur", "GaussianBlur" ) {}
int test(const Mat& img)
{
int ksizes[] = {3, 5, 7};
int ksizes_num = sizeof(ksizes) / sizeof(int);
int test_res = cvtest::TS::OK;
const double sigma1 = 3.0;
for (int i = 0; i < ksizes_num; ++i)
{
for (int j = 0; j < ksizes_num; ++j)
{
cv::Size ksize(ksizes[i], ksizes[j]);
ts->printf(cvtest::TS::LOG, "ksize = (%dx%d)\t\n", ksizes[i], ksizes[j]);
Mat cpudst;
cv::GaussianBlur(img, cpudst, ksize, sigma1);
GpuMat gpu1(img);
GpuMat gpudst;
cv::gpu::GaussianBlur(gpu1, gpudst, ksize, sigma1);
if (CheckNorm(cpudst, gpudst, ksize) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// Laplacian
struct CV_GpuNppImageLaplacianTest : public CV_GpuNppFilterTest
{
CV_GpuNppImageLaplacianTest() : CV_GpuNppFilterTest( "GPU-NppImageLaplacian", "Laplacian" ) {}
int test(const Mat& img)
{
int ksizes[] = {1, 3};
int ksizes_num = sizeof(ksizes) / sizeof(int);
int test_res = cvtest::TS::OK;
for (int i = 0; i < ksizes_num; ++i)
{
ts->printf(cvtest::TS::LOG, "\nksize = %d\n", ksizes[i]);
Mat cpudst;
cv::Laplacian(img, cpudst, -1, ksizes[i]);
GpuMat gpu1(img);
GpuMat gpudst;
cv::gpu::Laplacian(gpu1, gpudst, -1, ksizes[i]);
if (CheckNorm(cpudst, gpudst, Size(3, 3)) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// Erode
class CV_GpuErodeTest : public CV_GpuNppFilterTest
{
public:
CV_GpuErodeTest() : CV_GpuNppFilterTest( "GPU-NppErode", "erode" ) {}
protected:
virtual int test(const Mat& img)
{
Mat kernel(Mat::ones(3, 3, CV_8U));
cv::Mat cpuRes;
cv::erode(img, cpuRes, kernel);
GpuMat gpuRes;
cv::gpu::erode(GpuMat(img), gpuRes, kernel);
return CheckNorm(cpuRes, gpuRes, Size(3, 3));
}
};
////////////////////////////////////////////////////////////////////////////////
// Dilate
class CV_GpuDilateTest : public CV_GpuNppFilterTest
{
public:
CV_GpuDilateTest() : CV_GpuNppFilterTest( "GPU-NppDilate", "dilate" ) {}
protected:
virtual int test(const Mat& img)
{
Mat kernel(Mat::ones(3, 3, CV_8U));
cv::Mat cpuRes;
cv::dilate(img, cpuRes, kernel);
GpuMat gpuRes;
cv::gpu::dilate(GpuMat(img), gpuRes, kernel);
return CheckNorm(cpuRes, gpuRes, Size(3, 3));
}
};
////////////////////////////////////////////////////////////////////////////////
// MorphologyEx
class CV_GpuMorphExTest : public CV_GpuNppFilterTest
{
public:
CV_GpuMorphExTest() : CV_GpuNppFilterTest( "GPU-NppMorphologyEx", "morphologyEx" ) {}
protected:
virtual int test(const Mat& img)
{
static int ops[] = { MORPH_OPEN, CV_MOP_CLOSE, CV_MOP_GRADIENT, CV_MOP_TOPHAT, CV_MOP_BLACKHAT};
const char *names[] = { "MORPH_OPEN", "CV_MOP_CLOSE", "CV_MOP_GRADIENT", "CV_MOP_TOPHAT", "CV_MOP_BLACKHAT"};
int num = sizeof(ops)/sizeof(ops[0]);
GpuMat kernel(Mat::ones(3, 3, CV_8U));
int res = cvtest::TS::OK;
for(int i = 0; i < num; ++i)
{
ts->printf(cvtest::TS::LOG, "Tesing %s\n", names[i]);
cv::Mat cpuRes;
cv::morphologyEx(img, cpuRes, ops[i], kernel);
GpuMat gpuRes;
cv::gpu::morphologyEx(GpuMat(img), gpuRes, ops[i], kernel);
if (cvtest::TS::OK != CheckNorm(cpuRes, gpuRes, Size(4, 4)))
res = cvtest::TS::FAIL_GENERIC;
}
return res;
}
};
TEST(blur, accuracy) { CV_GpuNppImageBlurTest test; test.safe_run(); }
TEST(sobel, accuracy) { CV_GpuNppImageSobelTest test; test.safe_run(); }
TEST(scharr, accuracy) { CV_GpuNppImageScharrTest test; test.safe_run(); }
TEST(gaussianBlur, accuracy) { CV_GpuNppImageGaussianBlurTest test; test.safe_run(); }
TEST(laplcaian, accuracy) { CV_GpuNppImageLaplacianTest test; test.safe_run(); }
TEST(erode, accuracy) { CV_GpuErodeTest test; test.safe_run(); }
TEST(dilate, accuracy) { CV_GpuDilateTest test; test.safe_run(); }
TEST(morphEx, accuracy) { CV_GpuMorphExTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
#include <fstream>
using namespace std;
//#define DUMP
#define CHECK(pred, err) if (!(pred)) { \
ts->printf(cvtest::TS::CONSOLE, "Fail: \"%s\" at line: %d\n", #pred, __LINE__); \
ts->set_failed_test_info(err); \
return; }
struct CV_GpuHogDetectTestRunner: cv::gpu::HOGDescriptor
{
CV_GpuHogDetectTestRunner(cvtest::TS* ts_): ts(ts_) {}
void run(int)
{
cv::Mat img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/road.png");
CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);
#ifdef DUMP
f.open((std::string(ts->get_data_path()) + "hog/expected_output.bin").c_str(), std::ios_base::binary);
CHECK(f.is_open(), cvtest::TS::FAIL_GENERIC);
#else
f.open((std::string(ts->get_data_path()) + "hog/expected_output.bin").c_str(), std::ios_base::binary);
CHECK(f.is_open(), cvtest::TS::FAIL_MISSING_TEST_DATA);
#endif
// Test on color image
cv::Mat img;
cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
test(img);
// Test on gray image
cv::cvtColor(img_rgb, img, CV_BGR2GRAY);
test(img);
f.close();
}
#ifdef DUMP
void dump(const cv::Mat& block_hists, const std::vector<cv::Point>& locations)
{
f.write((char*)&block_hists.rows, sizeof(block_hists.rows));
f.write((char*)&block_hists.cols, sizeof(block_hists.cols));
for (int i = 0; i < block_hists.rows; ++i)
{
for (int j = 0; j < block_hists.cols; ++j)
{
float val = block_hists.at<float>(i, j);
f.write((char*)&val, sizeof(val));
}
}
size_t nlocations = locations.size();
f.write((char*)&nlocations, sizeof(nlocations));
for (size_t i = 0; i < locations.size(); ++i)
f.write((char*)&locations[i], sizeof(locations[i]));
}
#else
void compare(const cv::Mat& block_hists, const std::vector<cv::Point>& locations)
{
int rows, cols;
size_t nlocations;
f.read((char*)&rows, sizeof(rows));
f.read((char*)&cols, sizeof(cols));
CHECK(rows == block_hists.rows, cvtest::TS::FAIL_INVALID_OUTPUT);
CHECK(cols == block_hists.cols, cvtest::TS::FAIL_INVALID_OUTPUT);
for (int i = 0; i < block_hists.rows; ++i)
{
for (int j = 0; j < block_hists.cols; ++j)
{
float val;
f.read((char*)&val, sizeof(val));
CHECK(fabs(val - block_hists.at<float>(i, j)) < 1e-3f, cvtest::TS::FAIL_INVALID_OUTPUT);
}
}
f.read((char*)&nlocations, sizeof(nlocations));
CHECK(nlocations == locations.size(), cvtest::TS::FAIL_INVALID_OUTPUT);
for (size_t i = 0; i < nlocations; ++i)
{
cv::Point location;
f.read((char*)&location, sizeof(location));
CHECK(location == locations[i], cvtest::TS::FAIL_INVALID_OUTPUT);
}
}
#endif
void test(const cv::Mat& img)
{
cv::gpu::GpuMat d_img(img);
gamma_correction = false;
setSVMDetector(cv::gpu::HOGDescriptor::getDefaultPeopleDetector());
//cpu detector may be updated soon
//hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
std::vector<cv::Point> locations;
// Test detect
detect(d_img, locations, 0);
#ifdef DUMP
dump(block_hists, locations);
#else
compare(block_hists, locations);
#endif
// Test detect on smaller image
cv::Mat img2;
cv::resize(img, img2, cv::Size(img.cols / 2, img.rows / 2));
detect(cv::gpu::GpuMat(img2), locations, 0);
#ifdef DUMP
dump(block_hists, locations);
#else
compare(block_hists, locations);
#endif
// Test detect on greater image
cv::resize(img, img2, cv::Size(img.cols * 2, img.rows * 2));
detect(cv::gpu::GpuMat(img2), locations, 0);
#ifdef DUMP
dump(block_hists, locations);
#else
compare(block_hists, locations);
#endif
}
#ifdef DUMP
std::ofstream f;
#else
std::ifstream f;
#endif
cvtest::TS* ts;
};
struct CV_GpuHogDetectTest: cvtest::BaseTest
{
CV_GpuHogDetectTest() {}
void run(int i)
{
CV_GpuHogDetectTestRunner runner(ts);
runner.run(i);
}
};
TEST(HOG, detect_accuracy) { CV_GpuHogDetectTest test; test.safe_run(); }
struct CV_GpuHogGetDescriptorsTestRunner: cv::gpu::HOGDescriptor
{
CV_GpuHogGetDescriptorsTestRunner(cvtest::TS* ts_): HOGDescriptor(cv::Size(64, 128)), ts(ts_) {}
void run(int)
{
// Load image (e.g. train data, composed from windows)
cv::Mat img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/train_data.png");
CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);
// Convert to C4
cv::Mat img;
cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
cv::gpu::GpuMat d_img(img);
// Convert train images into feature vectors (train table)
cv::gpu::GpuMat descriptors, descriptors_by_cols;
getDescriptors(d_img, win_size, descriptors, DESCR_FORMAT_ROW_BY_ROW);
getDescriptors(d_img, win_size, descriptors_by_cols, DESCR_FORMAT_COL_BY_COL);
// Check size of the result train table
wins_per_img_x = 3;
wins_per_img_y = 2;
blocks_per_win_x = 7;
blocks_per_win_y = 15;
block_hist_size = 36;
cv::Size descr_size_expected = cv::Size(blocks_per_win_x * blocks_per_win_y * block_hist_size,
wins_per_img_x * wins_per_img_y);
CHECK(descriptors.size() == descr_size_expected, cvtest::TS::FAIL_INVALID_OUTPUT);
// Check both formats of output descriptors are handled correctly
cv::Mat dr(descriptors);
cv::Mat dc(descriptors_by_cols);
for (int i = 0; i < wins_per_img_x * wins_per_img_y; ++i)
{
const float* l = dr.rowRange(i, i + 1).ptr<float>();
const float* r = dc.rowRange(i, i + 1).ptr<float>();
for (int y = 0; y < blocks_per_win_y; ++y)
for (int x = 0; x < blocks_per_win_x; ++x)
for (int k = 0; k < block_hist_size; ++k)
CHECK(l[(y * blocks_per_win_x + x) * block_hist_size + k] ==
r[(x * blocks_per_win_y + y) * block_hist_size + k], cvtest::TS::FAIL_INVALID_OUTPUT);
}
/* Now we want to extract the same feature vectors, but from single images. NOTE: results will
be defferent, due to border values interpolation. Using of many small images is slower, however we
wont't call getDescriptors and will use computeBlockHistograms instead of. computeBlockHistograms
works good, it can be checked in the gpu_hog sample */
img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/positive1.png");
CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);
cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
computeBlockHistograms(cv::gpu::GpuMat(img));
// Everything is fine with interpolation for left top subimage
CHECK(cv::norm(block_hists, descriptors.rowRange(0, 1)) == 0.f, cvtest::TS::FAIL_INVALID_OUTPUT);
img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/positive2.png");
CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);
cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
computeBlockHistograms(cv::gpu::GpuMat(img));
compare_inner_parts(block_hists, descriptors.rowRange(1, 2));
img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/negative1.png");
CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);
cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
computeBlockHistograms(cv::gpu::GpuMat(img));
compare_inner_parts(block_hists, descriptors.rowRange(2, 3));
img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/negative2.png");
CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);
cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
computeBlockHistograms(cv::gpu::GpuMat(img));
compare_inner_parts(block_hists, descriptors.rowRange(3, 4));
img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/positive3.png");
CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);
cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
computeBlockHistograms(cv::gpu::GpuMat(img));
compare_inner_parts(block_hists, descriptors.rowRange(4, 5));
img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/negative3.png");
CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);
cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
computeBlockHistograms(cv::gpu::GpuMat(img));
compare_inner_parts(block_hists, descriptors.rowRange(5, 6));
}
// Does not compare border value, as interpolation leads to delta
void compare_inner_parts(cv::Mat d1, cv::Mat d2)
{
for (int i = 1; i < blocks_per_win_y - 1; ++i)
for (int j = 1; j < blocks_per_win_x - 1; ++j)
for (int k = 0; k < block_hist_size; ++k)
{
float a = d1.at<float>(0, (i * blocks_per_win_x + j) * block_hist_size);
float b = d2.at<float>(0, (i * blocks_per_win_x + j) * block_hist_size);
CHECK(a == b, cvtest::TS::FAIL_INVALID_OUTPUT)
}
}
int wins_per_img_x;
int wins_per_img_y;
int blocks_per_win_x;
int blocks_per_win_y;
int block_hist_size;
cvtest::TS* ts;
};
struct CV_GpuHogGetDescriptorsTest: cvtest::BaseTest
{
CV_GpuHogGetDescriptorsTest() {}
void run(int i)
{
CV_GpuHogGetDescriptorsTestRunner runner(ts);
runner.run(i);
}
};
TEST(HOG, descriptors_accuracy) { CV_GpuHogGetDescriptorsTest test; test.safe_run(); }
/*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 <cmath>
#include <limits>
#include "test_precomp.hpp"
using namespace cv;
using namespace std;
using namespace gpu;
class CV_GpuImageProcTest : public cvtest::BaseTest
{
public:
virtual ~CV_GpuImageProcTest() {}
protected:
void run(int);
int test8UC1 (const Mat& img);
int test8UC4 (const Mat& img);
int test32SC1(const Mat& img);
int test32FC1(const Mat& img);
virtual int test(const Mat& img) = 0;
int CheckNorm(const Mat& m1, const Mat& m2);
// Checks whether two images are similar enough using normalized
// cross-correlation as an error measure
int CheckSimilarity(const Mat& m1, const Mat& m2, float max_err=1e-3f);
};
int CV_GpuImageProcTest::test8UC1(const Mat& img)
{
cv::Mat img_C1;
cvtColor(img, img_C1, CV_BGR2GRAY);
return test(img_C1);
}
int CV_GpuImageProcTest::test8UC4(const Mat& img)
{
cv::Mat img_C4;
cvtColor(img, img_C4, CV_BGR2BGRA);
return test(img_C4);
}
int CV_GpuImageProcTest::test32SC1(const Mat& img)
{
cv::Mat img_C1;
cvtColor(img, img_C1, CV_BGR2GRAY);
img_C1.convertTo(img_C1, CV_32S);
return test(img_C1);
}
int CV_GpuImageProcTest::test32FC1(const Mat& img)
{
cv::Mat temp, img_C1;
img.convertTo(temp, CV_32F, 1.f / 255.f);
cvtColor(temp, img_C1, CV_BGR2GRAY);
return test(img_C1);
}
int CV_GpuImageProcTest::CheckNorm(const Mat& m1, const Mat& m2)
{
double ret = norm(m1, m2, NORM_INF);
if (ret < std::numeric_limits<double>::epsilon())
{
return cvtest::TS::OK;
}
else
{
ts->printf(cvtest::TS::LOG, "Norm: %f\n", ret);
return cvtest::TS::FAIL_GENERIC;
}
}
int CV_GpuImageProcTest::CheckSimilarity(const Mat& m1, const Mat& m2, float max_err)
{
Mat diff;
cv::matchTemplate(m1, m2, diff, CV_TM_CCORR_NORMED);
float err = abs(diff.at<float>(0, 0) - 1.f);
if (err > max_err)
return cvtest::TS::FAIL_INVALID_OUTPUT;
return cvtest::TS::OK;
}
void CV_GpuImageProcTest::run( int )
{
//load image
cv::Mat img = cv::imread(std::string(ts->get_data_path()) + "stereobp/aloe-L.png");
if (img.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
int testResult = cvtest::TS::OK;
//run tests
ts->printf(cvtest::TS::LOG, "\n========Start test 8UC1========\n");
if (test8UC1(img) == cvtest::TS::OK)
ts->printf(cvtest::TS::LOG, "SUCCESS\n");
else
{
ts->printf(cvtest::TS::LOG, "FAIL\n");
testResult = cvtest::TS::FAIL_GENERIC;
}
ts->printf(cvtest::TS::LOG, "\n========Start test 8UC4========\n");
if (test8UC4(img) == cvtest::TS::OK)
ts->printf(cvtest::TS::LOG, "SUCCESS\n");
else
{
ts->printf(cvtest::TS::LOG, "FAIL\n");
testResult = cvtest::TS::FAIL_GENERIC;
}
ts->printf(cvtest::TS::LOG, "\n========Start test 32SC1========\n");
if (test32SC1(img) == cvtest::TS::OK)
ts->printf(cvtest::TS::LOG, "SUCCESS\n");
else
{
ts->printf(cvtest::TS::LOG, "FAIL\n");
testResult = cvtest::TS::FAIL_GENERIC;
}
ts->printf(cvtest::TS::LOG, "\n========Start test 32FC1========\n");
if (test32FC1(img) == cvtest::TS::OK)
ts->printf(cvtest::TS::LOG, "SUCCESS\n");
else
{
ts->printf(cvtest::TS::LOG, "FAIL\n");
testResult = cvtest::TS::FAIL_GENERIC;
}
ts->set_failed_test_info(testResult);
}
////////////////////////////////////////////////////////////////////////////////
// threshold
struct CV_GpuImageThresholdTest : public CV_GpuImageProcTest
{
public:
CV_GpuImageThresholdTest() {}
int test(const Mat& img)
{
if (img.type() != CV_8UC1 && img.type() != CV_32FC1)
{
ts->printf(cvtest::TS::LOG, "\nUnsupported type\n");
return cvtest::TS::OK;
}
const double maxVal = img.type() == CV_8UC1 ? 255 : 1.0;
cv::RNG& rng = ts->get_rng();
int res = cvtest::TS::OK;
for (int type = THRESH_BINARY; type <= THRESH_TOZERO_INV; ++type)
{
const double thresh = rng.uniform(0.0, maxVal);
cv::Mat cpuRes;
cv::threshold(img, cpuRes, thresh, maxVal, type);
GpuMat gpu1(img);
GpuMat gpuRes;
cv::gpu::threshold(gpu1, gpuRes, thresh, maxVal, type);
if (CheckNorm(cpuRes, gpuRes) != cvtest::TS::OK)
res = cvtest::TS::FAIL_GENERIC;
}
return res;
}
};
////////////////////////////////////////////////////////////////////////////////
// resize
struct CV_GpuNppImageResizeTest : public CV_GpuImageProcTest
{
CV_GpuNppImageResizeTest() {}
int test(const Mat& img)
{
if (img.type() != CV_8UC1 && img.type() != CV_8UC4)
{
ts->printf(cvtest::TS::LOG, "Unsupported type\n");
return cvtest::TS::OK;
}
int interpolations[] = {INTER_NEAREST, INTER_LINEAR, /*INTER_CUBIC,*/ /*INTER_LANCZOS4*/};
const char* interpolations_str[] = {"INTER_NEAREST", "INTER_LINEAR", /*"INTER_CUBIC",*/ /*"INTER_LANCZOS4"*/};
int interpolations_num = sizeof(interpolations) / sizeof(int);
int test_res = cvtest::TS::OK;
for (int i = 0; i < interpolations_num; ++i)
{
ts->printf(cvtest::TS::LOG, "Interpolation: %s\n", interpolations_str[i]);
Mat cpu_res1, cpu_res2;
cv::resize(img, cpu_res1, Size(), 2.0, 2.0, interpolations[i]);
cv::resize(cpu_res1, cpu_res2, Size(), 0.5, 0.5, interpolations[i]);
GpuMat gpu1(img), gpu_res1, gpu_res2;
cv::gpu::resize(gpu1, gpu_res1, Size(), 2.0, 2.0, interpolations[i]);
cv::gpu::resize(gpu_res1, gpu_res2, Size(), 0.5, 0.5, interpolations[i]);
if (CheckSimilarity(cpu_res2, gpu_res2) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// copyMakeBorder
struct CV_GpuNppImageCopyMakeBorderTest : public CV_GpuImageProcTest
{
CV_GpuNppImageCopyMakeBorderTest() {}
int test(const Mat& img)
{
if (img.type() != CV_8UC1 && img.type() != CV_8UC4 && img.type() != CV_32SC1)
{
ts->printf(cvtest::TS::LOG, "\nUnsupported type\n");
return cvtest::TS::OK;
}
cv::RNG& rng = ts->get_rng();
int top = rng.uniform(1, 10);
int botton = rng.uniform(1, 10);
int left = rng.uniform(1, 10);
int right = rng.uniform(1, 10);
cv::Scalar val(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
Mat cpudst;
cv::copyMakeBorder(img, cpudst, top, botton, left, right, BORDER_CONSTANT, val);
GpuMat gpu1(img);
GpuMat gpudst;
cv::gpu::copyMakeBorder(gpu1, gpudst, top, botton, left, right, val);
return CheckNorm(cpudst, gpudst);
}
};
////////////////////////////////////////////////////////////////////////////////
// warpAffine
struct CV_GpuNppImageWarpAffineTest : public CV_GpuImageProcTest
{
CV_GpuNppImageWarpAffineTest() {}
int test(const Mat& img)
{
if (img.type() == CV_32SC1)
{
ts->printf(cvtest::TS::LOG, "\nUnsupported type\n");
return cvtest::TS::OK;
}
static double reflect[2][3] = { {-1, 0, 0},
{ 0, -1, 0} };
reflect[0][2] = img.cols;
reflect[1][2] = img.rows;
Mat M(2, 3, CV_64F, (void*)reflect);
int flags[] = {INTER_NEAREST, INTER_LINEAR, INTER_CUBIC, INTER_NEAREST | WARP_INVERSE_MAP, INTER_LINEAR | WARP_INVERSE_MAP, INTER_CUBIC | WARP_INVERSE_MAP};
const char* flags_str[] = {"INTER_NEAREST", "INTER_LINEAR", "INTER_CUBIC", "INTER_NEAREST | WARP_INVERSE_MAP", "INTER_LINEAR | WARP_INVERSE_MAP", "INTER_CUBIC | WARP_INVERSE_MAP"};
int flags_num = sizeof(flags) / sizeof(int);
int test_res = cvtest::TS::OK;
for (int i = 0; i < flags_num; ++i)
{
ts->printf(cvtest::TS::LOG, "\nFlags: %s\n", flags_str[i]);
Mat cpudst;
cv::warpAffine(img, cpudst, M, img.size(), flags[i]);
GpuMat gpu1(img);
GpuMat gpudst;
cv::gpu::warpAffine(gpu1, gpudst, M, gpu1.size(), flags[i]);
// Check inner parts (ignoring 1 pixel width border)
if (CheckSimilarity(cpudst.rowRange(1, cpudst.rows - 1).colRange(1, cpudst.cols - 1),
gpudst.rowRange(1, gpudst.rows - 1).colRange(1, gpudst.cols - 1)) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// warpPerspective
struct CV_GpuNppImageWarpPerspectiveTest : public CV_GpuImageProcTest
{
CV_GpuNppImageWarpPerspectiveTest() {}
int test(const Mat& img)
{
if (img.type() == CV_32SC1)
{
ts->printf(cvtest::TS::LOG, "\nUnsupported type\n");
return cvtest::TS::OK;
}
static double reflect[3][3] = { { -1, 0, 0},
{ 0, -1, 0},
{ 0, 0, 1 }};
reflect[0][2] = img.cols;
reflect[1][2] = img.rows;
Mat M(3, 3, CV_64F, (void*)reflect);
int flags[] = {INTER_NEAREST, INTER_LINEAR, INTER_CUBIC, INTER_NEAREST | WARP_INVERSE_MAP, INTER_LINEAR | WARP_INVERSE_MAP, INTER_CUBIC | WARP_INVERSE_MAP};
const char* flags_str[] = {"INTER_NEAREST", "INTER_LINEAR", "INTER_CUBIC", "INTER_NEAREST | WARP_INVERSE_MAP", "INTER_LINEAR | WARP_INVERSE_MAP", "INTER_CUBIC | WARP_INVERSE_MAP"};
int flags_num = sizeof(flags) / sizeof(int);
int test_res = cvtest::TS::OK;
for (int i = 0; i < flags_num; ++i)
{
ts->printf(cvtest::TS::LOG, "\nFlags: %s\n", flags_str[i]);
Mat cpudst;
cv::warpPerspective(img, cpudst, M, img.size(), flags[i]);
GpuMat gpu1(img);
GpuMat gpudst;
cv::gpu::warpPerspective(gpu1, gpudst, M, gpu1.size(), flags[i]);
// Check inner parts (ignoring 1 pixel width border)
if (CheckSimilarity(cpudst.rowRange(1, cpudst.rows - 1).colRange(1, cpudst.cols - 1),
gpudst.rowRange(1, gpudst.rows - 1).colRange(1, gpudst.cols - 1)) != cvtest::TS::OK)
test_res = cvtest::TS::FAIL_GENERIC;
}
return test_res;
}
};
////////////////////////////////////////////////////////////////////////////////
// integral
struct CV_GpuNppImageIntegralTest : public CV_GpuImageProcTest
{
CV_GpuNppImageIntegralTest() {}
int test(const Mat& img)
{
if (img.type() != CV_8UC1)
{
ts->printf(cvtest::TS::LOG, "\nUnsupported type\n");
return cvtest::TS::OK;
}
Mat cpusum;
cv::integral(img, cpusum, CV_32S);
GpuMat gpu1(img);
GpuMat gpusum;
cv::gpu::integral(gpu1, gpusum);
return CheckNorm(cpusum, gpusum) == cvtest::TS::OK ? cvtest::TS::OK : cvtest::TS::FAIL_GENERIC;
}
};
////////////////////////////////////////////////////////////////////////////////
// Canny
//struct CV_GpuNppImageCannyTest : public CV_GpuImageProcTest
//{
// CV_GpuNppImageCannyTest() : CV_GpuImageProcTest( "GPU-NppImageCanny", "Canny" ) {}
//
// int test(const Mat& img)
// {
// if (img.type() != CV_8UC1)
// {
// ts->printf(cvtest::TS::LOG, "\nUnsupported type\n");
// return cvtest::TS::OK;
// }
//
// const double threshold1 = 1.0, threshold2 = 10.0;
//
// Mat cpudst;
// cv::Canny(img, cpudst, threshold1, threshold2);
//
// GpuMat gpu1(img);
// GpuMat gpudst;
// cv::gpu::Canny(gpu1, gpudst, threshold1, threshold2);
//
// return CheckNorm(cpudst, gpudst);
// }
//};
////////////////////////////////////////////////////////////////////////////////
// cvtColor
class CV_GpuCvtColorTest : public cvtest::BaseTest
{
public:
CV_GpuCvtColorTest() {}
~CV_GpuCvtColorTest() {};
protected:
void run(int);
int CheckNorm(const Mat& m1, const Mat& m2);
};
int CV_GpuCvtColorTest::CheckNorm(const Mat& m1, const Mat& m2)
{
double ret = norm(m1, m2, NORM_INF);
if (ret <= 3)
{
return cvtest::TS::OK;
}
else
{
ts->printf(cvtest::TS::LOG, "\nNorm: %f\n", ret);
return cvtest::TS::FAIL_GENERIC;
}
}
void CV_GpuCvtColorTest::run( int )
{
cv::Mat img = cv::imread(std::string(ts->get_data_path()) + "stereobp/aloe-L.png");
if (img.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
int testResult = cvtest::TS::OK;
cv::Mat cpuRes;
cv::gpu::GpuMat gpuImg(img), gpuRes;
int codes[] = { CV_BGR2RGB, CV_RGB2BGRA, CV_BGRA2RGB,
CV_RGB2BGR555, CV_BGR5552BGR, CV_BGR2BGR565, CV_BGR5652RGB,
CV_RGB2YCrCb, CV_YCrCb2BGR, CV_BGR2YUV, CV_YUV2RGB,
CV_RGB2XYZ, CV_XYZ2BGR, CV_BGR2XYZ, CV_XYZ2RGB,
CV_RGB2HSV, CV_HSV2BGR, CV_BGR2HSV_FULL, CV_HSV2RGB_FULL,
CV_RGB2HLS, CV_HLS2BGR, CV_BGR2HLS_FULL, CV_HLS2RGB_FULL,
CV_RGB2GRAY, CV_GRAY2BGRA, CV_BGRA2GRAY,
CV_GRAY2BGR555, CV_BGR5552GRAY, CV_GRAY2BGR565, CV_BGR5652GRAY};
const char* codes_str[] = { "CV_BGR2RGB", "CV_RGB2BGRA", "CV_BGRA2RGB",
"CV_RGB2BGR555", "CV_BGR5552BGR", "CV_BGR2BGR565", "CV_BGR5652RGB",
"CV_RGB2YCrCb", "CV_YCrCb2BGR", "CV_BGR2YUV", "CV_YUV2RGB",
"CV_RGB2XYZ", "CV_XYZ2BGR", "CV_BGR2XYZ", "CV_XYZ2RGB",
"CV_RGB2HSV", "CV_HSV2RGB", "CV_BGR2HSV_FULL", "CV_HSV2RGB_FULL",
"CV_RGB2HLS", "CV_HLS2RGB", "CV_BGR2HLS_FULL", "CV_HLS2RGB_FULL",
"CV_RGB2GRAY", "CV_GRAY2BGRA", "CV_BGRA2GRAY",
"CV_GRAY2BGR555", "CV_BGR5552GRAY", "CV_GRAY2BGR565", "CV_BGR5652GRAY"};
int codes_num = sizeof(codes) / sizeof(int);
for (int i = 0; i < codes_num; ++i)
{
ts->printf(cvtest::TS::LOG, "\n%s\n", codes_str[i]);
cv::cvtColor(img, cpuRes, codes[i]);
cv::gpu::cvtColor(gpuImg, gpuRes, codes[i]);
if (CheckNorm(cpuRes, gpuRes) == cvtest::TS::OK)
ts->printf(cvtest::TS::LOG, "\nSUCCESS\n");
else
{
ts->printf(cvtest::TS::LOG, "\nFAIL\n");
testResult = cvtest::TS::FAIL_GENERIC;
}
img = cpuRes;
gpuImg = gpuRes;
}
ts->set_failed_test_info(testResult);
}
////////////////////////////////////////////////////////////////////////////////
// Histograms
class CV_GpuHistogramsTest : public cvtest::BaseTest
{
public:
CV_GpuHistogramsTest() {}
~CV_GpuHistogramsTest() {};
protected:
void run(int);
int CheckNorm(const Mat& m1, const Mat& m2)
{
double ret = norm(m1, m2, NORM_INF);
if (ret < std::numeric_limits<double>::epsilon())
{
return cvtest::TS::OK;
}
else
{
ts->printf(cvtest::TS::LOG, "\nNorm: %f\n", ret);
return cvtest::TS::FAIL_GENERIC;
}
}
};
void CV_GpuHistogramsTest::run( int )
{
//load image
cv::Mat img = cv::imread(std::string(ts->get_data_path()) + "stereobp/aloe-L.png");
if (img.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
Mat hsv;
cv::cvtColor(img, hsv, CV_BGR2HSV);
int hbins = 30;
int histSize[] = {hbins};
float hranges[] = {0, 180};
const float* ranges[] = {hranges};
MatND hist;
int channels[] = {0};
calcHist(&hsv, 1, channels, Mat(), hist, 1, histSize, ranges);
GpuMat gpuHsv(hsv);
std::vector<GpuMat> srcs;
cv::gpu::split(gpuHsv, srcs);
GpuMat gpuHist;
histEven(srcs[0], gpuHist, hbins, (int)hranges[0], (int)hranges[1]);
Mat cpuHist = hist;
cpuHist = cpuHist.t();
cpuHist.convertTo(cpuHist, CV_32S);
ts->set_failed_test_info(CheckNorm(cpuHist, gpuHist));
}
////////////////////////////////////////////////////////////////////////
// Corner Harris feature detector
struct CV_GpuCornerHarrisTest: cvtest::BaseTest
{
CV_GpuCornerHarrisTest() {}
void run(int)
{
for (int i = 0; i < 5; ++i)
{
int rows = 25 + rand() % 300, cols = 25 + rand() % 300;
if (!compareToCpuTest(rows, cols, CV_32F, 1 + rand() % 5, 1 + 2 * (rand() % 4))) return;
if (!compareToCpuTest(rows, cols, CV_32F, 1 + rand() % 5, -1)) return;
if (!compareToCpuTest(rows, cols, CV_8U, 1 + rand() % 5, 1 + 2 * (rand() % 4))) return;
if (!compareToCpuTest(rows, cols, CV_8U, 1 + rand() % 5, -1)) return;
}
}
bool compareToCpuTest(int rows, int cols, int depth, int blockSize, int apertureSize)
{
RNG rng;
cv::Mat src(rows, cols, depth);
if (depth == CV_32F)
rng.fill(src, RNG::UNIFORM, cv::Scalar(0), cv::Scalar(1));
else if (depth == CV_8U)
rng.fill(src, RNG::UNIFORM, cv::Scalar(0), cv::Scalar(256));
double k = 0.1;
cv::Mat dst_gold;
cv::gpu::GpuMat dst;
cv::Mat dsth;
int borderType;
borderType = BORDER_REFLECT101;
cv::cornerHarris(src, dst_gold, blockSize, apertureSize, k, borderType);
cv::gpu::cornerHarris(cv::gpu::GpuMat(src), dst, blockSize, apertureSize, k, borderType);
dsth = dst;
for (int i = 0; i < dst.rows; ++i)
{
for (int j = 0; j < dst.cols; ++j)
{
float a = dst_gold.at<float>(i, j);
float b = dsth.at<float>(i, j);
if (fabs(a - b) > 1e-3f)
{
ts->printf(cvtest::TS::CONSOLE, "%d %d %f %f %d\n", i, j, a, b, apertureSize);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
};
}
}
borderType = BORDER_REPLICATE;
cv::cornerHarris(src, dst_gold, blockSize, apertureSize, k, borderType);
cv::gpu::cornerHarris(cv::gpu::GpuMat(src), dst, blockSize, apertureSize, k, borderType);
dsth = dst;
for (int i = 0; i < dst.rows; ++i)
{
for (int j = 0; j < dst.cols; ++j)
{
float a = dst_gold.at<float>(i, j);
float b = dsth.at<float>(i, j);
if (fabs(a - b) > 1e-3f)
{
ts->printf(cvtest::TS::CONSOLE, "%d %d %f %f %d\n", i, j, a, b, apertureSize);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
};
}
}
return true;
}
};
////////////////////////////////////////////////////////////////////////
// Corner Min Eigen Val
struct CV_GpuCornerMinEigenValTest: cvtest::BaseTest
{
CV_GpuCornerMinEigenValTest() {}
void run(int)
{
for (int i = 0; i < 3; ++i)
{
int rows = 25 + rand() % 300, cols = 25 + rand() % 300;
if (!compareToCpuTest(rows, cols, CV_32F, 1 + rand() % 5, -1)) return;
if (!compareToCpuTest(rows, cols, CV_32F, 1 + rand() % 5, 1 + 2 * (rand() % 4))) return;
if (!compareToCpuTest(rows, cols, CV_8U, 1 + rand() % 5, -1)) return;
if (!compareToCpuTest(rows, cols, CV_8U, 1 + rand() % 5, 1 + 2 * (rand() % 4))) return;
}
}
bool compareToCpuTest(int rows, int cols, int depth, int blockSize, int apertureSize)
{
RNG rng;
cv::Mat src(rows, cols, depth);
if (depth == CV_32F)
rng.fill(src, RNG::UNIFORM, cv::Scalar(0), cv::Scalar(1));
else if (depth == CV_8U)
rng.fill(src, RNG::UNIFORM, cv::Scalar(0), cv::Scalar(256));
cv::Mat dst_gold;
cv::gpu::GpuMat dst;
cv::Mat dsth;
int borderType;
borderType = BORDER_REFLECT101;
cv::cornerMinEigenVal(src, dst_gold, blockSize, apertureSize, borderType);
cv::gpu::cornerMinEigenVal(cv::gpu::GpuMat(src), dst, blockSize, apertureSize, borderType);
dsth = dst;
for (int i = 0; i < dst.rows; ++i)
{
for (int j = 0; j < dst.cols; ++j)
{
float a = dst_gold.at<float>(i, j);
float b = dsth.at<float>(i, j);
if (fabs(a - b) > 1e-2f)
{
ts->printf(cvtest::TS::CONSOLE, "%d %d %f %f %d %d\n", i, j, a, b, apertureSize, blockSize);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
};
}
}
borderType = BORDER_REPLICATE;
cv::cornerMinEigenVal(src, dst_gold, blockSize, apertureSize, borderType);
cv::gpu::cornerMinEigenVal(cv::gpu::GpuMat(src), dst, blockSize, apertureSize, borderType);
dsth = dst;
for (int i = 0; i < dst.rows; ++i)
{
for (int j = 0; j < dst.cols; ++j)
{
float a = dst_gold.at<float>(i, j);
float b = dsth.at<float>(i, j);
if (fabs(a - b) > 1e-2f)
{
ts->printf(cvtest::TS::CONSOLE, "%d %d %f %f %d %d\n", i, j, a, b, apertureSize, blockSize);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
};
}
}
return true;
}
};
struct CV_GpuColumnSumTest: cvtest::BaseTest
{
CV_GpuColumnSumTest() {}
void run(int)
{
int cols = 375;
int rows = 1072;
Mat src(rows, cols, CV_32F);
RNG rng(1);
rng.fill(src, RNG::UNIFORM, Scalar(0), Scalar(1));
GpuMat d_dst;
columnSum(GpuMat(src), d_dst);
Mat dst = d_dst;
for (int j = 0; j < src.cols; ++j)
{
float a = src.at<float>(0, j);
float b = dst.at<float>(0, j);
if (fabs(a - b) > 0.5f)
{
ts->printf(cvtest::TS::CONSOLE, "big diff at %d %d: %f %f\n", 0, j, a, b);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
for (int i = 1; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
float a = src.at<float>(i, j) += src.at<float>(i - 1, j);
float b = dst.at<float>(i, j);
if (fabs(a - b) > 0.5f)
{
ts->printf(cvtest::TS::CONSOLE, "big diff at %d %d: %f %f\n", i, j, a, b);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
}
}
};
struct CV_GpuNormTest : cvtest::BaseTest
{
CV_GpuNormTest() {}
void run(int)
{
RNG rng(0);
int rows = rng.uniform(1, 500);
int cols = rng.uniform(1, 500);
for (int cn = 1; cn <= 4; ++cn)
{
test(NORM_L1, rows, cols, CV_8U, cn, Scalar::all(0), Scalar::all(10));
test(NORM_L1, rows, cols, CV_8S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_L1, rows, cols, CV_16U, cn, Scalar::all(0), Scalar::all(10));
test(NORM_L1, rows, cols, CV_16S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_L1, rows, cols, CV_32S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_L1, rows, cols, CV_32F, cn, Scalar::all(0), Scalar::all(1));
test(NORM_L2, rows, cols, CV_8U, cn, Scalar::all(0), Scalar::all(10));
test(NORM_L2, rows, cols, CV_8S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_L2, rows, cols, CV_16U, cn, Scalar::all(0), Scalar::all(10));
test(NORM_L2, rows, cols, CV_16S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_L2, rows, cols, CV_32S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_L2, rows, cols, CV_32F, cn, Scalar::all(0), Scalar::all(1));
test(NORM_INF, rows, cols, CV_8U, cn, Scalar::all(0), Scalar::all(10));
test(NORM_INF, rows, cols, CV_8S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_INF, rows, cols, CV_16U, cn, Scalar::all(0), Scalar::all(10));
test(NORM_INF, rows, cols, CV_16S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_INF, rows, cols, CV_32S, cn, Scalar::all(-10), Scalar::all(10));
test(NORM_INF, rows, cols, CV_32F, cn, Scalar::all(0), Scalar::all(1));
}
}
void gen(Mat& mat, int rows, int cols, int type, Scalar low, Scalar high)
{
mat.create(rows, cols, type);
RNG rng(0);
rng.fill(mat, RNG::UNIFORM, low, high);
}
void test(int norm_type, int rows, int cols, int depth, int cn, Scalar low, Scalar high)
{
int type = CV_MAKE_TYPE(depth, cn);
Mat src;
gen(src, rows, cols, type, low, high);
double gold = norm(src, norm_type);
double mine = norm(GpuMat(src), norm_type);
if (abs(gold - mine) > 1e-3)
{
ts->printf(cvtest::TS::CONSOLE, "failed test: gold=%f, mine=%f, norm_type=%d, rows=%d, "
"cols=%d, depth=%d, cn=%d\n", gold, mine, norm_type, rows, cols, depth, cn);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
}
}
};
////////////////////////////////////////////////////////////////////////////////
// reprojectImageTo3D
class CV_GpuReprojectImageTo3DTest : public cvtest::BaseTest
{
public:
CV_GpuReprojectImageTo3DTest() {}
protected:
void run(int)
{
Mat disp(320, 240, CV_8UC1);
RNG& rng = ts->get_rng();
rng.fill(disp, RNG::UNIFORM, Scalar(5), Scalar(30));
Mat Q(4, 4, CV_32FC1);
rng.fill(Q, RNG::UNIFORM, Scalar(0.1), Scalar(1));
Mat cpures;
GpuMat gpures;
reprojectImageTo3D(disp, cpures, Q, false);
reprojectImageTo3D(GpuMat(disp), gpures, Q);
Mat temp = gpures;
for (int y = 0; y < cpures.rows; ++y)
{
const Vec3f* cpu_row = cpures.ptr<Vec3f>(y);
const Vec4f* gpu_row = temp.ptr<Vec4f>(y);
for (int x = 0; x < cpures.cols; ++x)
{
Vec3f a = cpu_row[x];
Vec4f b = gpu_row[x];
if (fabs(a[0] - b[0]) > 1e-5 || fabs(a[1] - b[1]) > 1e-5 || fabs(a[2] - b[2]) > 1e-5)
{
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
}
}
};
TEST(threshold, accuracy) { CV_GpuImageThresholdTest test; test.safe_run(); }
TEST(resize, accuracy) { CV_GpuNppImageResizeTest test; test.safe_run(); }
TEST(copyMakeBorder, accuracy) { CV_GpuNppImageCopyMakeBorderTest test; test.safe_run(); }
TEST(warpAffine, accuracy) { CV_GpuNppImageWarpAffineTest test; test.safe_run(); }
TEST(warpPerspective, accuracy) { CV_GpuNppImageWarpPerspectiveTest test; test.safe_run(); }
TEST(integral, accuracy) { CV_GpuNppImageIntegralTest test; test.safe_run(); }
//TEST(canny, accuracy) { CV_GpuNppImageCannyTest test; test.safe_run(); }
TEST(cvtColor, accuracy) { CV_GpuCvtColorTest test; test.safe_run(); }
TEST(histograms, accuracy) { CV_GpuHistogramsTest test; test.safe_run(); }
TEST(cornerHearris, accuracy) { CV_GpuCornerHarrisTest test; test.safe_run(); }
TEST(minEigen, accuracy) { CV_GpuCornerMinEigenValTest test; test.safe_run(); }
TEST(columnSum, accuracy) { CV_GpuColumnSumTest test; test.safe_run(); }
TEST(norm, accuracy) { CV_GpuNormTest test; test.safe_run(); }
TEST(reprojectImageTo3D, accuracy) { CV_GpuReprojectImageTo3DTest test; test.safe_run(); }
......@@ -5,4 +5,4 @@ CV_TEST_MAIN("gpu")
// Run test with --gtest_catch_exceptions flag to avoid runtime errors in
// the case when there is no GPU
// TODO Add other tests from tests/gpu folder
// TODO Add NVIDIA tests
/*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 GpuMaterials 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 bpied warranties, including, but not limited to, the bpied
// 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 "test_precomp.hpp"
#include <string>
#include <iostream>
//#define SHOW_TIME
#ifdef SHOW_TIME
#include <ctime>
#define F(x) x
#else
#define F(x)
#endif
using namespace cv;
using namespace std;
struct CV_GpuMatchTemplateTest: cvtest::BaseTest
{
CV_GpuMatchTemplateTest() {}
void run(int)
{
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
if (!double_ok)
{
// For sqrIntegral
ts->printf(cvtest::TS::CONSOLE, "\nCode and device double support is required (CC >= 1.3)");
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
Mat image, templ;
Mat dst_gold;
gpu::GpuMat dst;
int n, m, h, w;
F(clock_t t;)
RNG& rng = ts->get_rng();
for (int cn = 1; cn <= 4; ++cn)
{
F(ts->printf(cvtest::TS::CONSOLE, "cn: %d\n", cn);)
for (int i = 0; i <= 0; ++i)
{
n = rng.uniform(30, 100);
m = rng.uniform(30, 100);
h = rng.uniform(5, n - 1);
w = rng.uniform(5, m - 1);
gen(image, n, m, CV_8U, cn);
gen(templ, h, w, CV_8U, cn);
F(t = clock();)
matchTemplate(image, templ, dst_gold, CV_TM_SQDIFF);
F(cout << "depth: 8U cn: " << cn << " n: " << n << " m: " << m << " w: " << w << " h: " << h << endl;)
F(cout << "cpu:" << clock() - t << endl;)
F(t = clock();)
gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_SQDIFF);
F(cout << "gpu_block: " << clock() - t << endl;)
if (!check(dst_gold, Mat(dst), 5 * h * w * 1e-4f, "SQDIFF 8U")) return;
gen(image, n, m, CV_8U, cn);
gen(templ, h, w, CV_8U, cn);
F(t = clock();)
matchTemplate(image, templ, dst_gold, CV_TM_SQDIFF_NORMED);
F(cout << "depth: 8U cn: " << cn << " n: " << n << " m: " << m << " w: " << w << " h: " << h << endl;)
F(cout << "cpu:" << clock() - t << endl;)
F(t = clock();)
gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_SQDIFF_NORMED);
F(cout << "gpu_block: " << clock() - t << endl;)
if (!check(dst_gold, Mat(dst), h * w * 1e-5f, "SQDIFF_NOREMD 8U")) return;
gen(image, n, m, CV_8U, cn);
gen(templ, h, w, CV_8U, cn);
F(t = clock();)
matchTemplate(image, templ, dst_gold, CV_TM_CCORR);
F(cout << "depth: 8U cn: " << cn << " n: " << n << " m: " << m << " w: " << w << " h: " << h << endl;)
F(cout << "cpu:" << clock() - t << endl;)
F(t = clock();)
gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_CCORR);
F(cout << "gpu_block: " << clock() - t << endl;)
if (!check(dst_gold, Mat(dst), 5 * h * w * cn * cn * 1e-5f, "CCORR 8U")) return;
gen(image, n, m, CV_8U, cn);
gen(templ, h, w, CV_8U, cn);
F(t = clock();)
matchTemplate(image, templ, dst_gold, CV_TM_CCORR_NORMED);
F(cout << "depth: 8U cn: " << cn << " n: " << n << " m: " << m << " w: " << w << " h: " << h << endl;)
F(cout << "cpu:" << clock() - t << endl;)
F(t = clock();)
gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_CCORR_NORMED);
F(cout << "gpu_block: " << clock() - t << endl;)
if (!check(dst_gold, Mat(dst), h * w * 1e-6f, "CCORR_NORMED 8U")) return;
gen(image, n, m, CV_8U, cn);
gen(templ, h, w, CV_8U, cn);
F(t = clock();)
matchTemplate(image, templ, dst_gold, CV_TM_CCOEFF);
F(cout << "depth: 8U cn: " << cn << " n: " << n << " m: " << m << " w: " << w << " h: " << h << endl;)
F(cout << "cpu:" << clock() - t << endl;)
F(t = clock();)
gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_CCOEFF);
F(cout << "gpu_block: " << clock() - t << endl;)
if (!check(dst_gold, Mat(dst), 5 * h * w * cn * cn * 1e-5f, "CCOEFF 8U")) return;
gen(image, n, m, CV_8U, cn);
gen(templ, h, w, CV_8U, cn);
F(t = clock();)
matchTemplate(image, templ, dst_gold, CV_TM_CCOEFF_NORMED);
F(cout << "depth: 8U cn: " << cn << " n: " << n << " m: " << m << " w: " << w << " h: " << h << endl;)
F(cout << "cpu:" << clock() - t << endl;)
F(t = clock();)
gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_CCOEFF_NORMED);
F(cout << "gpu_block: " << clock() - t << endl;)
if (!check(dst_gold, Mat(dst), h * w * 1e-6f, "CCOEFF_NORMED 8U")) return;
gen(image, n, m, CV_32F, cn);
gen(templ, h, w, CV_32F, cn);
F(t = clock();)
matchTemplate(image, templ, dst_gold, CV_TM_SQDIFF);
F(cout << "depth: 32F cn: " << cn << " n: " << n << " m: " << m << " w: " << w << " h: " << h << endl;)
F(cout << "cpu:" << clock() - t << endl;)
F(t = clock();)
gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_SQDIFF);
F(cout << "gpu_block: " << clock() - t << endl;)
if (!check(dst_gold, Mat(dst), 0.25f * h * w * 1e-5f, "SQDIFF 32F")) return;
gen(image, n, m, CV_32F, cn);
gen(templ, h, w, CV_32F, cn);
F(t = clock();)
matchTemplate(image, templ, dst_gold, CV_TM_CCORR);
F(cout << "depth: 32F cn: " << cn << " n: " << n << " m: " << m << " w: " << w << " h: " << h << endl;)
F(cout << "cpu:" << clock() - t << endl;)
F(t = clock();)
gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_CCORR);
F(cout << "gpu_block: " << clock() - t << endl;)
if (!check(dst_gold, Mat(dst), 0.25f * h * w * 1e-5f, "CCORR 32F")) return;
}
}
}
void gen(Mat& a, int rows, int cols, int depth, int cn)
{
RNG rng;
a.create(rows, cols, CV_MAKETYPE(depth, cn));
if (depth == CV_8U)
rng.fill(a, RNG::UNIFORM, Scalar::all(1), Scalar::all(10));
else if (depth == CV_32F)
rng.fill(a, RNG::UNIFORM, Scalar::all(0.001f), Scalar::all(1.f));
}
bool check(const Mat& a, const Mat& b, float max_err, const string& method="")
{
if (a.size() != b.size())
{
ts->printf(cvtest::TS::CONSOLE, "bad size, method=%s\n", method.c_str());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
//for (int i = 0; i < a.rows; ++i)
//{
// for (int j = 0; j < a.cols; ++j)
// {
// float a_ = a.at<float>(i, j);
// float b_ = b.at<float>(i, j);
// if (fabs(a_ - b_) > max_err)
// {
// ts->printf(cvtest::TS::CONSOLE, "a=%f, b=%f, i=%d, j=%d\n", a_, b_, i, j);
// cin.get();
// }
// }
//}
float err = (float)norm(a, b, NORM_INF);
if (err > max_err)
{
ts->printf(cvtest::TS::CONSOLE, "bad accuracy: %f, method=%s\n", err, method.c_str());
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return false;
}
return true;
}
};
TEST(matchTemplate, accuracy) { CV_GpuMatchTemplateTest test; test.safe_run(); }
struct CV_GpuMatchTemplateFindPatternInBlackTest: cvtest::BaseTest
{
CV_GpuMatchTemplateFindPatternInBlackTest() {}
void run(int)
{
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
if (!double_ok)
{
// For sqrIntegral
ts->printf(cvtest::TS::CONSOLE, "\nCode and device double support is required (CC >= 1.3)");
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
Mat image = imread(std::string(ts->get_data_path()) + "matchtemplate/black.png");
if (image.empty())
{
ts->printf(cvtest::TS::CONSOLE, "can't open file '%s'", (std::string(ts->get_data_path())
+ "matchtemplate/black.png").c_str());
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
Mat pattern = imread(std::string(ts->get_data_path()) + "matchtemplate/cat.png");
if (pattern.empty())
{
ts->printf(cvtest::TS::CONSOLE, "can't open file '%s'", (std::string(ts->get_data_path())
+ "matchtemplate/cat.png").c_str());
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
gpu::GpuMat d_image(image);
gpu::GpuMat d_pattern(pattern);
gpu::GpuMat d_result;
double maxValue;
Point maxLoc;
Point maxLocGold(284, 12);
gpu::matchTemplate(d_image, d_pattern, d_result, CV_TM_CCOEFF_NORMED);
gpu::minMaxLoc(d_result, NULL, &maxValue, NULL, &maxLoc );
if (maxLoc != maxLocGold)
{
ts->printf(cvtest::TS::CONSOLE, "bad match (CV_TM_CCOEFF_NORMED): %d %d, must be at: %d %d",
maxLoc.x, maxLoc.y, maxLocGold.x, maxLocGold.y);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
gpu::matchTemplate(d_image, d_pattern, d_result, CV_TM_CCORR_NORMED);
gpu::minMaxLoc(d_result, NULL, &maxValue, NULL, &maxLoc );
if (maxLoc != maxLocGold)
{
ts->printf(cvtest::TS::CONSOLE, "bad match (CV_TM_CCORR_NORMED): %d %d, must be at: %d %d",
maxLoc.x, maxLoc.y, maxLocGold.x, maxLocGold.y);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
};
TEST(matchTemplate, find_pattern_in_black) { CV_GpuMatchTemplateFindPatternInBlackTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
#include <iostream>
#include <string>
using namespace cv;
using namespace cv::gpu;
struct CV_GpuMeanShiftTest : public cvtest::BaseTest
{
CV_GpuMeanShiftTest() {}
void run(int)
{
bool cc12_ok = TargetArchs::builtWith(FEATURE_SET_COMPUTE_12) && DeviceInfo().supports(FEATURE_SET_COMPUTE_12);
if (!cc12_ok)
{
ts->printf(cvtest::TS::CONSOLE, "\nCompute capability 1.2 is required");
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
int spatialRad = 30;
int colorRad = 30;
cv::Mat img = cv::imread(std::string(ts->get_data_path()) + "meanshift/cones.png");
cv::Mat img_template;
if (cv::gpu::TargetArchs::builtWith(cv::gpu::FEATURE_SET_COMPUTE_20) &&
cv::gpu::DeviceInfo().supports(cv::gpu::FEATURE_SET_COMPUTE_20))
img_template = cv::imread(std::string(ts->get_data_path()) + "meanshift/con_result.png");
else
img_template = cv::imread(std::string(ts->get_data_path()) + "meanshift/con_result_CC1X.png");
if (img.empty() || img_template.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
cv::Mat rgba;
cvtColor(img, rgba, CV_BGR2BGRA);
cv::gpu::GpuMat res;
cv::gpu::meanShiftFiltering( cv::gpu::GpuMat(rgba), res, spatialRad, colorRad );
if (res.type() != CV_8UC4)
{
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
cv::Mat result;
res.download(result);
uchar maxDiff = 0;
for (int j = 0; j < result.rows; ++j)
{
const uchar* res_line = result.ptr<uchar>(j);
const uchar* ref_line = img_template.ptr<uchar>(j);
for (int i = 0; i < result.cols; ++i)
{
for (int k = 0; k < 3; ++k)
{
const uchar& ch1 = res_line[result.channels()*i + k];
const uchar& ch2 = ref_line[img_template.channels()*i + k];
uchar diff = static_cast<uchar>(abs(ch1 - ch2));
if (maxDiff < diff)
maxDiff = diff;
}
}
}
if (maxDiff > 0)
{
ts->printf(cvtest::TS::LOG, "\nMeanShift maxDiff = %d\n", maxDiff);
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
ts->set_failed_test_info(cvtest::TS::OK);
}
};
/////////////////////////////////////////////////////////////////////////////
/////////////////// tests registration /////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
CV_GpuMeanShiftTest CV_GpuMeanShift_test;
struct CV_GpuMeanShiftProcTest : public cvtest::BaseTest
{
CV_GpuMeanShiftProcTest() {}
void run(int)
{
bool cc12_ok = TargetArchs::builtWith(FEATURE_SET_COMPUTE_12) && DeviceInfo().supports(FEATURE_SET_COMPUTE_12);
if (!cc12_ok)
{
ts->printf(cvtest::TS::CONSOLE, "\nCompute capability 1.2 is required");
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
int spatialRad = 30;
int colorRad = 30;
cv::Mat img = cv::imread(std::string(ts->get_data_path()) + "meanshift/cones.png");
if (img.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
cv::Mat rgba;
cvtColor(img, rgba, CV_BGR2BGRA);
cv::gpu::GpuMat h_rmap_filtered;
cv::gpu::meanShiftFiltering( cv::gpu::GpuMat(rgba), h_rmap_filtered, spatialRad, colorRad );
cv::gpu::GpuMat d_rmap;
cv::gpu::GpuMat d_spmap;
cv::gpu::meanShiftProc( cv::gpu::GpuMat(rgba), d_rmap, d_spmap, spatialRad, colorRad );
if (d_rmap.type() != CV_8UC4)
{
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
cv::Mat rmap_filtered;
h_rmap_filtered.download(rmap_filtered);
cv::Mat rmap;
d_rmap.download(rmap);
uchar maxDiff = 0;
for (int j = 0; j < rmap_filtered.rows; ++j)
{
const uchar* res_line = rmap_filtered.ptr<uchar>(j);
const uchar* ref_line = rmap.ptr<uchar>(j);
for (int i = 0; i < rmap_filtered.cols; ++i)
{
for (int k = 0; k < 3; ++k)
{
const uchar& ch1 = res_line[rmap_filtered.channels()*i + k];
const uchar& ch2 = ref_line[rmap.channels()*i + k];
uchar diff = static_cast<uchar>(abs(ch1 - ch2));
if (maxDiff < diff)
maxDiff = diff;
}
}
}
if (maxDiff > 0)
{
ts->printf(cvtest::TS::LOG, "\nMeanShiftProc maxDiff = %d\n", maxDiff);
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
cv::Mat spmap;
d_spmap.download(spmap);
cv::Mat spmap_template;
cv::FileStorage fs;
if (cv::gpu::TargetArchs::builtWith(cv::gpu::FEATURE_SET_COMPUTE_20) &&
cv::gpu::DeviceInfo().supports(cv::gpu::FEATURE_SET_COMPUTE_20))
fs.open(std::string(ts->get_data_path()) + "meanshift/spmap.yaml", cv::FileStorage::READ);
else
fs.open(std::string(ts->get_data_path()) + "meanshift/spmap_CC1X.yaml", cv::FileStorage::READ);
fs["spmap"] >> spmap_template;
for (int y = 0; y < spmap.rows; ++y) {
for (int x = 0; x < spmap.cols; ++x) {
cv::Point_<short> expected = spmap_template.at<cv::Point_<short> >(y, x);
cv::Point_<short> actual = spmap.at<cv::Point_<short> >(y, x);
int diff = (expected - actual).dot(expected - actual);
if (actual != expected) {
ts->printf(cvtest::TS::LOG, "\nMeanShiftProc SpMap is bad, diff=%d\n", diff);
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
}
}
ts->set_failed_test_info(cvtest::TS::OK);
}
};
TEST(meanShiftProc, accuracy) { CV_GpuMeanShiftProcTest test; test.safe_run(); }
/*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 <iostream>
#include <string>
#include <iosfwd>
#include "test_precomp.hpp"
using namespace cv;
using namespace cv::gpu;
using namespace std;
struct CV_GpuMeanShiftSegmentationTest : public cvtest::BaseTest {
CV_GpuMeanShiftSegmentationTest() {}
void run(int)
{
bool cc12_ok = TargetArchs::builtWith(FEATURE_SET_COMPUTE_12) && DeviceInfo().supports(FEATURE_SET_COMPUTE_12);
if (!cc12_ok)
{
ts->printf(cvtest::TS::CONSOLE, "\nCompute capability 1.2 is required");
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
Mat img_rgb = imread(string(ts->get_data_path()) + "meanshift/cones.png");
if (img_rgb.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
Mat img;
cvtColor(img_rgb, img, CV_BGR2BGRA);
for (int minsize = 0; minsize < 2000; minsize = (minsize + 1) * 4)
{
stringstream path;
path << ts->get_data_path() << "meanshift/cones_segmented_sp10_sr10_minsize" << minsize;
if (TargetArchs::builtWith(FEATURE_SET_COMPUTE_20) && DeviceInfo().supports(FEATURE_SET_COMPUTE_20))
path << ".png";
else
path << "_CC1X.png";
Mat dst;
meanShiftSegmentation((GpuMat)img, dst, 10, 10, minsize);
Mat dst_rgb;
cvtColor(dst, dst_rgb, CV_BGRA2BGR);
//imwrite(path.str(), dst_rgb);
Mat dst_ref = imread(path.str());
if (dst_ref.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
if (CheckSimilarity(dst_rgb, dst_ref, 1e-3f) != cvtest::TS::OK)
{
ts->printf(cvtest::TS::LOG, "\ndiffers from image *minsize%d.png\n", minsize);
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
}
}
ts->set_failed_test_info(cvtest::TS::OK);
}
int CheckSimilarity(const Mat& m1, const Mat& m2, float max_err)
{
Mat diff;
cv::matchTemplate(m1, m2, diff, CV_TM_CCORR_NORMED);
float err = abs(diff.at<float>(0, 0) - 1.f);
if (err > max_err)
return cvtest::TS::FAIL_INVALID_OUTPUT;
return cvtest::TS::OK;
}
};
TEST(meanShiftSegmentation, regression) { CV_GpuMeanShiftSegmentationTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
using namespace std;
using namespace cv;
using namespace cv::gpu;
struct CV_AsyncGpuMatTest : public cvtest::BaseTest
{
CV_AsyncGpuMatTest() {}
void run(int)
{
CudaMem src(Mat::zeros(100, 100, CV_8UC1));
GpuMat gpusrc;
GpuMat gpudst0, gpudst1(100, 100, CV_8UC1);
CudaMem cpudst0;
CudaMem cpudst1;
Stream stream0, stream1;
stream0.enqueueUpload(src, gpusrc);
bitwise_not(gpusrc, gpudst0, GpuMat(), stream0);
stream0.enqueueDownload(gpudst0, cpudst0);
stream1.enqueueMemSet(gpudst1, Scalar::all(128));
stream1.enqueueDownload(gpudst1, cpudst1);
stream0.waitForCompletion();
stream1.waitForCompletion();
Mat cpu_gold0(100, 100, CV_8UC1, Scalar::all(255));
Mat cpu_gold1(100, 100, CV_8UC1, Scalar::all(128));
if (norm(cpudst0, cpu_gold0, NORM_INF) > 0 || norm(cpudst1, cpu_gold1, NORM_INF) > 0)
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
else
ts->set_failed_test_info(cvtest::TS::OK);
}
};
TEST(GpuMat, async) { CV_AsyncGpuMatTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
#include <fstream>
#include <iterator>
#include <numeric>
using namespace cv;
using namespace std;
using namespace gpu;
class CV_GpuMatOpConvertToTest : public cvtest::BaseTest
{
public:
CV_GpuMatOpConvertToTest() {}
~CV_GpuMatOpConvertToTest() {}
protected:
void run(int);
};
void CV_GpuMatOpConvertToTest::run(int /* start_from */)
{
const Size img_size(67, 35);
const char* types_str[] = {"CV_8U", "CV_8S", "CV_16U", "CV_16S", "CV_32S", "CV_32F", "CV_64F"};
bool passed = true;
int lastType = CV_32F;
if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))
lastType = CV_64F;
for (int i = 0; i <= lastType && passed; ++i)
{
for (int j = 0; j <= lastType && passed; ++j)
{
for (int c = 1; c < 5 && passed; ++c)
{
const int src_type = CV_MAKETYPE(i, c);
const int dst_type = j;
cv::RNG& rng = ts->get_rng();
Mat cpumatsrc(img_size, src_type);
rng.fill(cpumatsrc, RNG::UNIFORM, Scalar::all(0), Scalar::all(300));
GpuMat gpumatsrc(cpumatsrc);
Mat cpumatdst;
GpuMat gpumatdst;
cpumatsrc.convertTo(cpumatdst, dst_type, 0.5, 3.0);
gpumatsrc.convertTo(gpumatdst, dst_type, 0.5, 3.0);
double r = norm(cpumatdst, gpumatdst, NORM_INF);
if (r > 1)
{
ts->printf(cvtest::TS::LOG,
"\nFAILED: SRC_TYPE=%sC%d DST_TYPE=%s NORM = %f\n",
types_str[i], c, types_str[j], r);
passed = false;
}
}
}
}
ts->set_failed_test_info(passed ? cvtest::TS::OK : cvtest::TS::FAIL_GENERIC);
}
TEST(GpuMat_convertTo, accuracy) { CV_GpuMatOpConvertToTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
#include <fstream>
#include <iterator>
#include <numeric>
#include <iomanip> // for cout << setw()
using namespace cv;
using namespace std;
using namespace gpu;
class CV_GpuMatOpCopyToTest : public cvtest::BaseTest
{
public:
CV_GpuMatOpCopyToTest()
{
rows = 234;
cols = 123;
}
~CV_GpuMatOpCopyToTest() {}
protected:
void run(int);
template <typename T>
void print_mat(const T & mat, const std::string & name) const;
bool compare_matrix(cv::Mat & cpumat, gpu::GpuMat & gpumat);
private:
int rows;
int cols;
};
template<typename T>
void CV_GpuMatOpCopyToTest::print_mat(const T & mat, const std::string & name) const { cv::imshow(name, mat); }
bool CV_GpuMatOpCopyToTest::compare_matrix(cv::Mat & cpumat, gpu::GpuMat & gpumat)
{
Mat cmat(cpumat.size(), cpumat.type(), Scalar::all(0));
GpuMat gmat(cmat);
Mat cpumask(cpumat.size(), CV_8U);
cv::RNG& rng = ts->get_rng();
rng.fill(cpumask, RNG::NORMAL, Scalar::all(0), Scalar::all(127));
threshold(cpumask, cpumask, 0, 127, THRESH_BINARY);
GpuMat gpumask(cpumask);
//int64 time = getTickCount();
cpumat.copyTo(cmat, cpumask);
//int64 time1 = getTickCount();
gpumat.copyTo(gmat, gpumask);
//int64 time2 = getTickCount();
//std::cout << "\ntime cpu: " << std::fixed << std::setprecision(12) << 1.0 / double((time1 - time) / (double)getTickFrequency());
//std::cout << "\ntime gpu: " << std::fixed << std::setprecision(12) << 1.0 / double((time2 - time1) / (double)getTickFrequency());
//std::cout << "\n";
#ifdef PRINT_MATRIX
print_mat(cmat, "cpu mat");
print_mat(gmat, "gpu mat");
print_mat(cpumask, "cpu mask");
print_mat(gpumask, "gpu mask");
cv::waitKey(0);
#endif
double ret = norm(cmat, gmat);
if (ret < 1.0)
return true;
else
{
ts->printf(cvtest::TS::LOG, "\nNorm: %f\n", ret);
return false;
}
}
void CV_GpuMatOpCopyToTest::run( int /* start_from */)
{
bool is_test_good = true;
int lastType = CV_32F;
if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))
lastType = CV_64F;
for (int i = 0 ; i <= lastType; i++)
{
Mat cpumat(rows, cols, i);
cpumat.setTo(Scalar::all(127));
GpuMat gpumat(cpumat);
is_test_good &= compare_matrix(cpumat, gpumat);
}
if (is_test_good == true)
ts->set_failed_test_info(cvtest::TS::OK);
else
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
}
TEST(GpuMat_copyTo, accuracy) { CV_GpuMatOpCopyToTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
using namespace cv;
using namespace std;
using namespace gpu;
class CV_GpuMatOpSetToTest : public cvtest::BaseTest
{
public:
CV_GpuMatOpSetToTest();
~CV_GpuMatOpSetToTest() {}
protected:
void run(int);
bool testSetTo(cv::Mat& cpumat, gpu::GpuMat& gpumat, const cv::Mat& cpumask = cv::Mat(), const cv::gpu::GpuMat& gpumask = cv::gpu::GpuMat());
private:
int rows;
int cols;
Scalar s;
};
CV_GpuMatOpSetToTest::CV_GpuMatOpSetToTest()
{
rows = 35;
cols = 67;
s.val[0] = 127.0;
s.val[1] = 127.0;
s.val[2] = 127.0;
s.val[3] = 127.0;
}
bool CV_GpuMatOpSetToTest::testSetTo(cv::Mat& cpumat, gpu::GpuMat& gpumat, const cv::Mat& cpumask, const cv::gpu::GpuMat& gpumask)
{
cpumat.setTo(s, cpumask);
gpumat.setTo(s, gpumask);
double ret = norm(cpumat, gpumat, NORM_INF);
if (ret < std::numeric_limits<double>::epsilon())
return true;
else
{
ts->printf(cvtest::TS::LOG, "\nNorm: %f\n", ret);
return false;
}
}
void CV_GpuMatOpSetToTest::run( int /* start_from */)
{
bool is_test_good = true;
cv::Mat cpumask(rows, cols, CV_8UC1);
cv::RNG& rng = ts->get_rng();
rng.fill(cpumask, RNG::UNIFORM, cv::Scalar::all(0.0), cv::Scalar(1.5));
cv::gpu::GpuMat gpumask(cpumask);
int lastType = CV_32F;
if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))
lastType = CV_64F;
for (int i = 0; i <= lastType; i++)
{
for (int cn = 1; cn <= 4; ++cn)
{
int mat_type = CV_MAKETYPE(i, cn);
Mat cpumat(rows, cols, mat_type, Scalar::all(0));
GpuMat gpumat(cpumat);
is_test_good &= testSetTo(cpumat, gpumat, cpumask, gpumask);
}
}
if (is_test_good == true)
ts->set_failed_test_info(cvtest::TS::OK);
else
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
}
TEST(GpuMat_setTo, accuracy) { CV_GpuMatOpSetToTest test; test.safe_run(); }
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include <limits>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ts/ts.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/highgui/highgui.hpp"
#endif
/*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 GpuMaterials 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 bpied warranties, including, but not limited to, the bpied
// 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 "test_precomp.hpp"
using namespace std;
using namespace cv;
////////////////////////////////////////////////////////////////////////////////
// Merge
struct CV_MergeTest : public cvtest::BaseTest
{
void can_merge(size_t rows, size_t cols);
void can_merge_submatrixes(size_t rows, size_t cols);
void run(int);
};
void CV_MergeTest::can_merge(size_t rows, size_t cols)
{
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
size_t depth_end = double_ok ? CV_64F : CV_32F;
for (size_t num_channels = 1; num_channels <= 4; ++num_channels)
for (size_t depth = CV_8U; depth <= depth_end; ++depth)
{
vector<Mat> src;
for (size_t i = 0; i < num_channels; ++i)
src.push_back(Mat(rows, cols, depth, Scalar::all(static_cast<double>(i))));
Mat dst(rows, cols, CV_MAKETYPE(depth, num_channels));
cv::merge(src, dst);
vector<gpu::GpuMat> dev_src;
for (size_t i = 0; i < num_channels; ++i)
dev_src.push_back(gpu::GpuMat(src[i]));
gpu::GpuMat dev_dst(rows, cols, CV_MAKETYPE(depth, num_channels));
cv::gpu::merge(dev_src, dev_dst);
Mat host_dst = dev_dst;
double err = norm(dst, host_dst, NORM_INF);
if (err > 1e-3)
{
//ts->printf(cvtest::TS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(cvtest::TS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(cvtest::TS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(cvtest::TS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(cvtest::TS::CONSOLE, "NumChannels: %d\n", num_channels);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
}
void CV_MergeTest::can_merge_submatrixes(size_t rows, size_t cols)
{
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
size_t depth_end = double_ok ? CV_64F : CV_32F;
for (size_t num_channels = 1; num_channels <= 4; ++num_channels)
for (size_t depth = CV_8U; depth <= depth_end; ++depth)
{
vector<Mat> src;
for (size_t i = 0; i < num_channels; ++i)
{
Mat m(rows * 2, cols * 2, depth, Scalar::all(static_cast<double>(i)));
src.push_back(m(Range(rows / 2, rows / 2 + rows), Range(cols / 2, cols / 2 + cols)));
}
Mat dst(rows, cols, CV_MAKETYPE(depth, num_channels));
cv::merge(src, dst);
vector<gpu::GpuMat> dev_src;
for (size_t i = 0; i < num_channels; ++i)
dev_src.push_back(gpu::GpuMat(src[i]));
gpu::GpuMat dev_dst(rows, cols, CV_MAKETYPE(depth, num_channels));
cv::gpu::merge(dev_src, dev_dst);
Mat host_dst = dev_dst;
double err = norm(dst, host_dst, NORM_INF);
if (err > 1e-3)
{
//ts->printf(cvtest::TS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(cvtest::TS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(cvtest::TS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(cvtest::TS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(cvtest::TS::CONSOLE, "NumChannels: %d\n", num_channels);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
}
void CV_MergeTest::run(int)
{
can_merge(1, 1);
can_merge(1, 7);
can_merge(53, 7);
can_merge_submatrixes(1, 1);
can_merge_submatrixes(1, 7);
can_merge_submatrixes(53, 7);
}
////////////////////////////////////////////////////////////////////////////////
// Split
struct CV_SplitTest : public cvtest::BaseTest
{
void can_split(size_t rows, size_t cols);
void can_split_submatrix(size_t rows, size_t cols);
void run(int);
};
void CV_SplitTest::can_split(size_t rows, size_t cols)
{
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
size_t depth_end = double_ok ? CV_64F : CV_32F;
for (size_t num_channels = 1; num_channels <= 4; ++num_channels)
for (size_t depth = CV_8U; depth <= depth_end; ++depth)
{
Mat src(rows, cols, CV_MAKETYPE(depth, num_channels), Scalar(1.0, 2.0, 3.0, 4.0));
vector<Mat> dst;
cv::split(src, dst);
gpu::GpuMat dev_src(src);
vector<gpu::GpuMat> dev_dst;
cv::gpu::split(dev_src, dev_dst);
if (dev_dst.size() != dst.size())
{
ts->printf(cvtest::TS::CONSOLE, "Bad output sizes");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
}
for (size_t i = 0; i < num_channels; ++i)
{
Mat host_dst = dev_dst[i];
double err = norm(dst[i], host_dst, NORM_INF);
if (err > 1e-3)
{
//ts->printf(cvtest::TS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(cvtest::TS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(cvtest::TS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(cvtest::TS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(cvtest::TS::CONSOLE, "NumChannels: %d\n", num_channels);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
}
}
void CV_SplitTest::can_split_submatrix(size_t rows, size_t cols)
{
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
size_t depth_end = double_ok ? CV_64F : CV_32F;
for (size_t num_channels = 1; num_channels <= 4; ++num_channels)
for (size_t depth = CV_8U; depth <= depth_end; ++depth)
{
Mat src_data(rows * 2, cols * 2, CV_MAKETYPE(depth, num_channels), Scalar(1.0, 2.0, 3.0, 4.0));
Mat src(src_data(Range(rows / 2, rows / 2 + rows), Range(cols / 2, cols / 2 + cols)));
vector<Mat> dst;
cv::split(src, dst);
gpu::GpuMat dev_src(src);
vector<gpu::GpuMat> dev_dst;
cv::gpu::split(dev_src, dev_dst);
if (dev_dst.size() != dst.size())
{
ts->printf(cvtest::TS::CONSOLE, "Bad output sizes");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
}
for (size_t i = 0; i < num_channels; ++i)
{
Mat host_dst = dev_dst[i];
double err = norm(dst[i], host_dst, NORM_INF);
if (err > 1e-3)
{
//ts->printf(cvtest::TS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(cvtest::TS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(cvtest::TS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(cvtest::TS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(cvtest::TS::CONSOLE, "NumChannels: %d\n", num_channels);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
}
}
void CV_SplitTest::run(int)
{
can_split(1, 1);
can_split(1, 7);
can_split(7, 53);
can_split_submatrix(1, 1);
can_split_submatrix(1, 7);
can_split_submatrix(7, 53);
}
////////////////////////////////////////////////////////////////////////////////
// Split and merge
struct CV_SplitMergeTest : public cvtest::BaseTest
{
void can_split_merge(size_t rows, size_t cols);
void run(int);
};
void CV_SplitMergeTest::can_split_merge(size_t rows, size_t cols) {
bool double_ok = gpu::TargetArchs::builtWith(gpu::NATIVE_DOUBLE) &&
gpu::DeviceInfo().supports(gpu::NATIVE_DOUBLE);
size_t depth_end = double_ok ? CV_64F : CV_32F;
for (size_t num_channels = 1; num_channels <= 4; ++num_channels)
for (size_t depth = CV_8U; depth <= depth_end; ++depth)
{
Mat orig(rows, cols, CV_MAKETYPE(depth, num_channels), Scalar(1.0, 2.0, 3.0, 4.0));
gpu::GpuMat dev_orig(orig);
vector<gpu::GpuMat> dev_vec;
cv::gpu::split(dev_orig, dev_vec);
gpu::GpuMat dev_final(rows, cols, CV_MAKETYPE(depth, num_channels));
cv::gpu::merge(dev_vec, dev_final);
double err = cv::norm((Mat)dev_orig, (Mat)dev_final, NORM_INF);
if (err > 1e-3)
{
//ts->printf(cvtest::TS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(cvtest::TS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(cvtest::TS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(cvtest::TS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(cvtest::TS::CONSOLE, "NumChannels: %d\n", num_channels);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
}
}
void CV_SplitMergeTest::run(int)
{
can_split_merge(1, 1);
can_split_merge(1, 7);
can_split_merge(7, 53);
}
TEST(merge, accuracy) { CV_MergeTest test; test.safe_run(); }
TEST(split, accuracy) { CV_SplitTest test; test.safe_run(); }
TEST(split, merge_consistency) { CV_SplitMergeTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
using namespace cv;
using namespace cv::gpu;
struct CV_GpuStereoBMTest : public cvtest::BaseTest
{
void run_stress()
{
RNG rng;
for(int i = 0; i < 10; ++i)
{
int winSize = cvRound(rng.uniform(2, 11)) * 2 + 1;
for(int j = 0; j < 10; ++j)
{
int ndisp = cvRound(rng.uniform(5, 32)) * 8;
for(int s = 0; s < 10; ++s)
{
int w = cvRound(rng.uniform(1024, 2048));
int h = cvRound(rng.uniform(768, 1152));
for(int p = 0; p < 2; ++p)
{
//int winSize = winsz[i];
//int disp = disps[j];
Size imgSize(w, h);//res[s];
int preset = p;
printf("Preset = %d, nidsp = %d, winsz = %d, width = %d, height = %d\n", p, ndisp, winSize, imgSize.width, imgSize.height);
GpuMat l(imgSize, CV_8U);
GpuMat r(imgSize, CV_8U);
GpuMat disparity;
StereoBM_GPU bm(preset, ndisp, winSize);
bm(l, r, disparity);
}
}
}
}
}
void run(int )
{
/*run_stress();
return;*/
cv::Mat img_l = cv::imread(std::string(ts->get_data_path()) + "stereobm/aloe-L.png", 0);
cv::Mat img_r = cv::imread(std::string(ts->get_data_path()) + "stereobm/aloe-R.png", 0);
cv::Mat img_reference = cv::imread(std::string(ts->get_data_path()) + "stereobm/aloe-disp.png", 0);
if (img_l.empty() || img_r.empty() || img_reference.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
cv::gpu::GpuMat disp;
cv::gpu::StereoBM_GPU bm(0, 128, 19);
bm(cv::gpu::GpuMat(img_l), cv::gpu::GpuMat(img_r), disp);
disp.convertTo(disp, img_reference.type());
double norm = cv::norm(disp, img_reference, cv::NORM_INF);
//cv::imwrite(std::string(ts->get_data_path()) + "stereobm/aloe-disp.png", disp);
/*cv::imshow("disp", disp);
cv::imshow("img_reference", img_reference);
cv::Mat diff = (cv::Mat)disp - (cv::Mat)img_reference;
cv::imshow("diff", diff);
cv::waitKey();*/
if (norm >= 100)
{
ts->printf(cvtest::TS::LOG, "\nStereoBM norm = %f\n", norm);
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
ts->set_failed_test_info(cvtest::TS::OK);
}
};
TEST(StereoBM, regression) { CV_GpuStereoBMTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
using namespace cv;
using namespace std;
struct CV_AsyncStereoBMTest : public cvtest::BaseTest
{
void run( int /* start_from */)
{
cv::Mat img_l = cv::imread(std::string(ts->get_data_path()) + "stereobm/aloe-L.png", 0);
cv::Mat img_r = cv::imread(std::string(ts->get_data_path()) + "stereobm/aloe-R.png", 0);
cv::Mat img_reference = cv::imread(std::string(ts->get_data_path()) + "stereobm/aloe-disp.png", 0);
if (img_l.empty() || img_r.empty() || img_reference.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
cv::gpu::GpuMat disp;
cv::gpu::StereoBM_GPU bm(0, 128, 19);
cv::gpu::Stream stream;
for (size_t i = 0; i < 50; i++)
{
bm(cv::gpu::GpuMat(img_l), cv::gpu::GpuMat(img_r), disp, stream);
}
stream.waitForCompletion();
disp.convertTo(disp, img_reference.type());
double norm = cv::norm(disp, img_reference, cv::NORM_INF);
if (norm >= 100)
{
ts->printf(cvtest::TS::LOG, "\nStereoBM norm = %f\n", norm);
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
ts->set_failed_test_info(cvtest::TS::OK);
}
};
TEST(StereoBM, async) { CV_AsyncStereoBMTest test; test.safe_run(); }
......@@ -79,4 +79,4 @@ struct CV_GpuStereoBPTest : public cvtest::BaseTest
}
};
TEST(StereoBP, StereoBP) { CV_GpuStereoBPTest test; test.safe_run(); }
\ No newline at end of file
TEST(StereoBP, regression) { CV_GpuStereoBPTest test; test.safe_run(); }
/*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 "test_precomp.hpp"
struct CV_GpuStereoCSBPTest : public cvtest::BaseTest
{
void run(int )
{
cv::Mat img_l = cv::imread(std::string(ts->get_data_path()) + "csstereobp/aloe-L.png");
cv::Mat img_r = cv::imread(std::string(ts->get_data_path()) + "csstereobp/aloe-R.png");
cv::Mat img_template = cv::imread(std::string(ts->get_data_path()) + "csstereobp/aloe-disp.png", 0);
if (img_l.empty() || img_r.empty() || img_template.empty())
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
{cv::Mat temp; cv::cvtColor(img_l, temp, CV_BGR2BGRA); cv::swap(temp, img_l);}
{cv::Mat temp; cv::cvtColor(img_r, temp, CV_BGR2BGRA); cv::swap(temp, img_r);}
cv::gpu::GpuMat disp;
cv::gpu::StereoConstantSpaceBP bpm(128, 16, 4, 4);
bpm(cv::gpu::GpuMat(img_l), cv::gpu::GpuMat(img_r), disp);
//cv::imwrite(std::string(ts->get_data_path()) + "csstereobp/aloe-disp.png", disp);
disp.convertTo(disp, img_template.type());
double norm = cv::norm(disp, img_template, cv::NORM_INF);
if (norm >= 0.5)
{
ts->printf(cvtest::TS::LOG, "\nConstantSpaceStereoBP norm = %f\n", norm);
ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
return;
}
ts->set_failed_test_info(cvtest::TS::OK);
}
};
TEST(StereoConstantSpaceBP, regression) { CV_GpuStereoCSBPTest test; test.safe_run(); }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册