reworked nearly all of the OpenCV tests (except for opencv_gpu tests) - they now use the Google Test engine.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
2122
modules/core/test/test_ds.cpp
Normal file
2122
modules/core/test/test_ds.cpp
Normal file
File diff suppressed because it is too large
Load Diff
829
modules/core/test/test_dxt.cpp
Normal file
829
modules/core/test/test_dxt.cpp
Normal file
@@ -0,0 +1,829 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
namespace cvtest
|
||||
{
|
||||
|
||||
static Mat initDFTWave( int n, bool inv )
|
||||
{
|
||||
int i;
|
||||
double angle = (inv ? 1 : -1)*CV_PI*2/n;
|
||||
Complexd wi, w1;
|
||||
Mat wave(1, n, CV_64FC2);
|
||||
Complexd* w = wave.ptr<Complexd>();
|
||||
|
||||
w1.re = cos(angle);
|
||||
w1.im = sin(angle);
|
||||
w[0].re = wi.re = 1.;
|
||||
w[0].im = wi.im = 0.;
|
||||
|
||||
for( i = 1; i < n; i++ )
|
||||
{
|
||||
double t = wi.re*w1.re - wi.im*w1.im;
|
||||
wi.im = wi.re*w1.im + wi.im*w1.re;
|
||||
wi.re = t;
|
||||
w[i] = wi;
|
||||
}
|
||||
|
||||
return wave;
|
||||
}
|
||||
|
||||
|
||||
static void DFT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat())
|
||||
{
|
||||
_dst.create(_src.size(), _src.type());
|
||||
int i, j, k, n = _dst.cols + _dst.rows - 1;
|
||||
Mat wave = _wave;
|
||||
double scale = (flags & DFT_SCALE) ? 1./n : 1.;
|
||||
size_t esz = _src.elemSize();
|
||||
size_t srcstep = esz, dststep = esz;
|
||||
const uchar* src0 = _src.data;
|
||||
uchar* dst0 = _dst.data;
|
||||
|
||||
CV_Assert( _src.cols + _src.rows - 1 == n );
|
||||
|
||||
if( wave.empty() )
|
||||
wave = initDFTWave( n, (flags & DFT_INVERSE) != 0 );
|
||||
|
||||
const Complexd* w = wave.ptr<Complexd>();
|
||||
if( !_src.isContinuous() )
|
||||
srcstep = _src.step;
|
||||
if( !_dst.isContinuous() )
|
||||
dststep = _dst.step;
|
||||
|
||||
if( _src.type() == CV_32FC2 )
|
||||
{
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
Complexf* dst = (Complexf*)(dst0 + i*dststep);
|
||||
Complexd sum(0,0);
|
||||
int delta = i;
|
||||
k = 0;
|
||||
|
||||
for( j = 0; j < n; j++ )
|
||||
{
|
||||
const Complexf* src = (const Complexf*)(src0 + j*srcstep);
|
||||
sum.re += src->re*w[k].re - src->im*w[k].im;
|
||||
sum.im += src->re*w[k].im + src->im*w[k].re;
|
||||
k += delta;
|
||||
k -= (k >= n ? n : 0);
|
||||
}
|
||||
|
||||
dst->re = (float)(sum.re*scale);
|
||||
dst->im = (float)(sum.im*scale);
|
||||
}
|
||||
}
|
||||
else if( _src.type() == CV_64FC2 )
|
||||
{
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
Complexd* dst = (Complexd*)(dst0 + i*dststep);
|
||||
Complexd sum(0,0);
|
||||
int delta = i;
|
||||
k = 0;
|
||||
|
||||
for( j = 0; j < n; j++ )
|
||||
{
|
||||
const Complexd* src = (const Complexd*)(src0 + j*srcstep);
|
||||
sum.re += src->re*w[k].re - src->im*w[k].im;
|
||||
sum.im += src->re*w[k].im + src->im*w[k].re;
|
||||
k += delta;
|
||||
k -= (k >= n ? n : 0);
|
||||
}
|
||||
|
||||
dst->re = sum.re*scale;
|
||||
dst->im = sum.im*scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
CV_Error(CV_StsUnsupportedFormat, "");
|
||||
}
|
||||
|
||||
|
||||
static void DFT_2D( const Mat& src, Mat& dst, int flags )
|
||||
{
|
||||
const int cn = 2;
|
||||
int i;
|
||||
dst.create(src.size(), src.type());
|
||||
Mat tmp( src.cols, src.rows, src.type());
|
||||
Mat wave = initDFTWave( dst.cols, (flags & DFT_INVERSE) != 0 );
|
||||
|
||||
// 1. row-wise transform
|
||||
for( i = 0; i < dst.rows; i++ )
|
||||
{
|
||||
Mat srci = src.row(i).reshape(cn, src.cols), dsti = tmp.col(i);
|
||||
DFT_1D(srci, dsti, flags, wave );
|
||||
}
|
||||
|
||||
if( (flags & DFT_ROWS) == 0 )
|
||||
{
|
||||
if( dst.cols != dst.rows )
|
||||
wave = initDFTWave( dst.rows, (flags & DFT_INVERSE) != 0 );
|
||||
|
||||
// 2. column-wise transform
|
||||
for( i = 0; i < dst.cols; i++ )
|
||||
{
|
||||
Mat srci = tmp.row(i).reshape(cn, tmp.cols), dsti = dst.col(i);
|
||||
DFT_1D(srci, dsti, flags, wave );
|
||||
}
|
||||
}
|
||||
else
|
||||
cvtest::transpose(tmp, dst);
|
||||
}
|
||||
|
||||
|
||||
static Mat initDCTWave( int n, bool inv )
|
||||
{
|
||||
int i, k;
|
||||
double angle = CV_PI*0.5/n;
|
||||
Mat wave(n, n, CV_64F);
|
||||
|
||||
double scale = sqrt(1./n);
|
||||
for( k = 0; k < n; k++ )
|
||||
wave.at<double>(0, k) = scale;
|
||||
scale *= sqrt(2.);
|
||||
for( i = 1; i < n; i++ )
|
||||
for( k = 0; k < n; k++ )
|
||||
wave.at<double>(i, k) = scale*cos( angle*i*(2*k + 1) );
|
||||
|
||||
if( inv )
|
||||
cv::transpose( wave, wave );
|
||||
|
||||
return wave;
|
||||
}
|
||||
|
||||
|
||||
static void DCT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat() )
|
||||
{
|
||||
_dst.create( _src.size(), _src.type() );
|
||||
int i, j, n = _dst.cols + _dst.rows - 1;
|
||||
Mat wave = _wave;
|
||||
int srcstep = 1, dststep = 1;
|
||||
double* w;
|
||||
|
||||
CV_Assert( _src.cols + _src.rows - 1 == n);
|
||||
|
||||
if( wave.empty() )
|
||||
wave = initDCTWave( n, (flags & DFT_INVERSE) != 0 );
|
||||
w = wave.ptr<double>();
|
||||
|
||||
if( !_src.isContinuous() )
|
||||
srcstep = _src.step/_src.elemSize();
|
||||
if( !_dst.isContinuous() )
|
||||
dststep = _dst.step/_dst.elemSize();
|
||||
|
||||
if( _src.type() == CV_32FC1 )
|
||||
{
|
||||
float *dst = _dst.ptr<float>();
|
||||
|
||||
for( i = 0; i < n; i++, dst += dststep )
|
||||
{
|
||||
const float* src = _src.ptr<float>();
|
||||
double sum = 0;
|
||||
|
||||
for( j = 0; j < n; j++, src += srcstep )
|
||||
sum += src[0]*w[j];
|
||||
w += n;
|
||||
dst[0] = (float)sum;
|
||||
}
|
||||
}
|
||||
else if( _src.type() == CV_64FC1 )
|
||||
{
|
||||
double *dst = _dst.ptr<double>();
|
||||
|
||||
for( i = 0; i < n; i++, dst += dststep )
|
||||
{
|
||||
const double* src = _src.ptr<double>();
|
||||
double sum = 0;
|
||||
|
||||
for( j = 0; j < n; j++, src += srcstep )
|
||||
sum += src[0]*w[j];
|
||||
w += n;
|
||||
dst[0] = sum;
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
static void DCT_2D( const Mat& src, Mat& dst, int flags )
|
||||
{
|
||||
const int cn = 1;
|
||||
int i;
|
||||
dst.create( src.size(), src.type() );
|
||||
Mat tmp(dst.cols, dst.rows, dst.type() );
|
||||
Mat wave = initDCTWave( dst.cols, (flags & DCT_INVERSE) != 0 );
|
||||
|
||||
// 1. row-wise transform
|
||||
for( i = 0; i < dst.rows; i++ )
|
||||
{
|
||||
Mat srci = src.row(i).reshape(cn, src.cols);
|
||||
Mat dsti = tmp.col(i);
|
||||
DCT_1D(srci, dsti, flags, wave);
|
||||
}
|
||||
|
||||
if( (flags & DCT_ROWS) == 0 )
|
||||
{
|
||||
if( dst.cols != dst.rows )
|
||||
wave = initDCTWave( dst.rows, (flags & DCT_INVERSE) != 0 );
|
||||
|
||||
// 2. column-wise transform
|
||||
for( i = 0; i < dst.cols; i++ )
|
||||
{
|
||||
Mat srci = tmp.row(i).reshape(cn, tmp.cols);
|
||||
Mat dsti = dst.col(i);
|
||||
DCT_1D( srci, dsti, flags, wave );
|
||||
}
|
||||
}
|
||||
else
|
||||
cvtest::transpose( tmp, dst );
|
||||
}
|
||||
|
||||
|
||||
static void convertFromCCS( const Mat& _src0, const Mat& _src1, Mat& _dst, int flags )
|
||||
{
|
||||
if( _dst.rows > 1 && (_dst.cols > 1 || (flags & DFT_ROWS)) )
|
||||
{
|
||||
int i, count = _dst.rows, len = _dst.cols;
|
||||
bool is2d = (flags & DFT_ROWS) == 0;
|
||||
Mat src0row, src1row, dstrow;
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
int j = !is2d || i == 0 ? i : count - i;
|
||||
src0row = _src0.row(i);
|
||||
src1row = _src1.row(j);
|
||||
dstrow = _dst.row(i);
|
||||
convertFromCCS( src0row, src1row, dstrow, 0 );
|
||||
}
|
||||
|
||||
if( is2d )
|
||||
{
|
||||
src0row = _src0.col(0);
|
||||
dstrow = _dst.col(0);
|
||||
convertFromCCS( src0row, src0row, dstrow, 0 );
|
||||
if( (len & 1) == 0 )
|
||||
{
|
||||
src0row = _src0.col(_src0.cols - 1);
|
||||
dstrow = _dst.col(len/2);
|
||||
convertFromCCS( src0row, src0row, dstrow, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, n = _dst.cols + _dst.rows - 1, n2 = (n+1) >> 1;
|
||||
int cn = _src0.channels();
|
||||
int srcstep = cn, dststep = 1;
|
||||
|
||||
if( !_dst.isContinuous() )
|
||||
dststep = _dst.step/_dst.elemSize();
|
||||
|
||||
if( !_src0.isContinuous() )
|
||||
srcstep = _src0.step/_src0.elemSize1();
|
||||
|
||||
if( _dst.depth() == CV_32F )
|
||||
{
|
||||
Complexf* dst = _dst.ptr<Complexf>();
|
||||
const float* src0 = _src0.ptr<float>();
|
||||
const float* src1 = _src1.ptr<float>();
|
||||
int delta0, delta1;
|
||||
|
||||
dst->re = src0[0];
|
||||
dst->im = 0;
|
||||
|
||||
if( (n & 1) == 0 )
|
||||
{
|
||||
dst[n2*dststep].re = src0[(cn == 1 ? n-1 : n2)*srcstep];
|
||||
dst[n2*dststep].im = 0;
|
||||
}
|
||||
|
||||
delta0 = srcstep;
|
||||
delta1 = delta0 + (cn == 1 ? srcstep : 1);
|
||||
if( cn == 1 )
|
||||
srcstep *= 2;
|
||||
|
||||
for( i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep )
|
||||
{
|
||||
float t0 = src0[delta0];
|
||||
float t1 = src0[delta1];
|
||||
|
||||
dst[i*dststep].re = t0;
|
||||
dst[i*dststep].im = t1;
|
||||
|
||||
t0 = src1[delta0];
|
||||
t1 = -src1[delta1];
|
||||
|
||||
dst[(n-i)*dststep].re = t0;
|
||||
dst[(n-i)*dststep].im = t1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Complexd* dst = _dst.ptr<Complexd>();
|
||||
const double* src0 = _src0.ptr<double>();
|
||||
const double* src1 = _src1.ptr<double>();
|
||||
int delta0, delta1;
|
||||
|
||||
dst->re = src0[0];
|
||||
dst->im = 0;
|
||||
|
||||
if( (n & 1) == 0 )
|
||||
{
|
||||
dst[n2*dststep].re = src0[(cn == 1 ? n-1 : n2)*srcstep];
|
||||
dst[n2*dststep].im = 0;
|
||||
}
|
||||
|
||||
delta0 = srcstep;
|
||||
delta1 = delta0 + (cn == 1 ? srcstep : 1);
|
||||
if( cn == 1 )
|
||||
srcstep *= 2;
|
||||
|
||||
for( i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep )
|
||||
{
|
||||
double t0 = src0[delta0];
|
||||
double t1 = src0[delta1];
|
||||
|
||||
dst[i*dststep].re = t0;
|
||||
dst[i*dststep].im = t1;
|
||||
|
||||
t0 = src1[delta0];
|
||||
t1 = -src1[delta1];
|
||||
|
||||
dst[(n-i)*dststep].re = t0;
|
||||
dst[(n-i)*dststep].im = t1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fixCCS( Mat& mat, int cols, int flags )
|
||||
{
|
||||
int i, rows = mat.rows;
|
||||
int rows2 = (flags & DFT_ROWS) ? rows : rows/2 + 1, cols2 = cols/2 + 1;
|
||||
|
||||
CV_Assert( cols2 == mat.cols );
|
||||
|
||||
if( mat.type() == CV_32FC2 )
|
||||
{
|
||||
for( i = 0; i < rows2; i++ )
|
||||
{
|
||||
Complexf* row = mat.ptr<Complexf>(i);
|
||||
if( (flags & DFT_ROWS) || i == 0 || (i == rows2 - 1 && rows % 2 == 0) )
|
||||
{
|
||||
row[0].im = 0;
|
||||
if( cols % 2 == 0 )
|
||||
row[cols2-1].im = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Complexf* row2 = mat.ptr<Complexf>(rows-i);
|
||||
row2[0].re = row[0].re;
|
||||
row2[0].im = -row[0].im;
|
||||
|
||||
if( cols % 2 == 0 )
|
||||
{
|
||||
row2[cols2-1].re = row[cols2-1].re;
|
||||
row2[cols2-1].im = -row[cols2-1].im;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( mat.type() == CV_64FC2 )
|
||||
{
|
||||
for( i = 0; i < rows2; i++ )
|
||||
{
|
||||
Complexd* row = mat.ptr<Complexd>(i);
|
||||
if( (flags & DFT_ROWS) || i == 0 || (i == rows2 - 1 && rows % 2 == 0) )
|
||||
{
|
||||
row[0].im = 0;
|
||||
if( cols % 2 == 0 )
|
||||
row[cols2-1].im = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Complexd* row2 = mat.ptr<Complexd>(rows-i);
|
||||
row2[0].re = row[0].re;
|
||||
row2[0].im = -row[0].im;
|
||||
|
||||
if( cols % 2 == 0 )
|
||||
{
|
||||
row2[cols2-1].re = row[cols2-1].re;
|
||||
row2[cols2-1].im = -row[cols2-1].im;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void mulComplex( const Mat& src1, const Mat& src2, Mat& dst, int flags )
|
||||
{
|
||||
dst.create(src1.rows, src1.cols, src1.type());
|
||||
int i, j, depth = src1.depth(), cols = src1.cols*2;
|
||||
|
||||
CV_Assert( src1.size == src2.size && src1.type() == src2.type() &&
|
||||
(src1.type() == CV_32FC2 || src1.type() == CV_64FC2) );
|
||||
|
||||
for( i = 0; i < dst.rows; i++ )
|
||||
{
|
||||
if( depth == CV_32F )
|
||||
{
|
||||
const float* a = src1.ptr<float>(i);
|
||||
const float* b = src2.ptr<float>(i);
|
||||
float* c = dst.ptr<float>(i);
|
||||
|
||||
if( !(flags & CV_DXT_MUL_CONJ) )
|
||||
for( j = 0; j < cols; j += 2 )
|
||||
{
|
||||
double re = (double)a[j]*b[j] - (double)a[j+1]*b[j+1];
|
||||
double im = (double)a[j+1]*b[j] + (double)a[j]*b[j+1];
|
||||
|
||||
c[j] = (float)re;
|
||||
c[j+1] = (float)im;
|
||||
}
|
||||
else
|
||||
for( j = 0; j < cols; j += 2 )
|
||||
{
|
||||
double re = (double)a[j]*b[j] + (double)a[j+1]*b[j+1];
|
||||
double im = (double)a[j+1]*b[j] - (double)a[j]*b[j+1];
|
||||
|
||||
c[j] = (float)re;
|
||||
c[j+1] = (float)im;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double* a = src1.ptr<double>(i);
|
||||
const double* b = src2.ptr<double>(i);
|
||||
double* c = dst.ptr<double>(i);
|
||||
|
||||
if( !(flags & CV_DXT_MUL_CONJ) )
|
||||
for( j = 0; j < cols; j += 2 )
|
||||
{
|
||||
double re = a[j]*b[j] - a[j+1]*b[j+1];
|
||||
double im = a[j+1]*b[j] + a[j]*b[j+1];
|
||||
|
||||
c[j] = re;
|
||||
c[j+1] = im;
|
||||
}
|
||||
else
|
||||
for( j = 0; j < cols; j += 2 )
|
||||
{
|
||||
double re = a[j]*b[j] + a[j+1]*b[j+1];
|
||||
double im = a[j+1]*b[j] - a[j]*b[j+1];
|
||||
|
||||
c[j] = re;
|
||||
c[j+1] = im;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class CxCore_DXTBaseTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
typedef cvtest::ArrayTest Base;
|
||||
CxCore_DXTBaseTest( bool _allow_complex=false, bool _allow_odd=false,
|
||||
bool _spectrum_mode=false );
|
||||
protected:
|
||||
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
|
||||
int prepare_test_case( int test_case_idx );
|
||||
double get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ );
|
||||
int flags; // transformation flags
|
||||
bool allow_complex; // whether input/output may be complex or not:
|
||||
// true for DFT and MulSpectrums, false for DCT
|
||||
bool allow_odd; // whether input/output may be have odd (!=1) dimensions:
|
||||
// true for DFT and MulSpectrums, false for DCT
|
||||
bool spectrum_mode; // (2 complex/ccs inputs, 1 complex/ccs output):
|
||||
// true for MulSpectrums, false for DFT and DCT
|
||||
bool inplace; // inplace operation (set for each individual test case)
|
||||
bool temp_dst; // use temporary destination (for real->ccs DFT and ccs MulSpectrums)
|
||||
};
|
||||
|
||||
|
||||
CxCore_DXTBaseTest::CxCore_DXTBaseTest( bool _allow_complex, bool _allow_odd, bool _spectrum_mode )
|
||||
: Base(), flags(0), allow_complex(_allow_complex), allow_odd(_allow_odd),
|
||||
spectrum_mode(_spectrum_mode), inplace(false), temp_dst(false)
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
if( spectrum_mode )
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
test_array[TEMP].push_back(NULL);
|
||||
test_array[TEMP].push_back(NULL);
|
||||
|
||||
max_log_array_size = 9;
|
||||
element_wise_relative_error = spectrum_mode;
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DXTBaseTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes,
|
||||
vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int bits = cvtest::randInt(rng);
|
||||
int depth = cvtest::randInt(rng)%2 + CV_32F;
|
||||
int cn = !allow_complex || !(bits & 256) ? 1 : 2;
|
||||
Size size;
|
||||
Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
|
||||
flags = bits & (CV_DXT_INVERSE | CV_DXT_SCALE | CV_DXT_ROWS | CV_DXT_MUL_CONJ);
|
||||
if( spectrum_mode )
|
||||
flags &= ~CV_DXT_INVERSE;
|
||||
types[TEMP][0] = types[TEMP][1] = types[INPUT][0] =
|
||||
types[OUTPUT][0] = CV_MAKETYPE(depth, cn);
|
||||
size = sizes[INPUT][0];
|
||||
|
||||
temp_dst = false;
|
||||
|
||||
if( flags & CV_DXT_ROWS && (bits&1024) )
|
||||
{
|
||||
if( bits&16 )
|
||||
size.width = 1;
|
||||
else
|
||||
size.height = 1;
|
||||
flags &= ~CV_DXT_ROWS;
|
||||
}
|
||||
|
||||
const int P2_MIN_SIZE = 32;
|
||||
if( ((bits >> 10) & 1) == 0 )
|
||||
{
|
||||
size.width = (size.width / P2_MIN_SIZE)*P2_MIN_SIZE;
|
||||
size.width = MAX(size.width, 1);
|
||||
size.height = (size.height / P2_MIN_SIZE)*P2_MIN_SIZE;
|
||||
size.height = MAX(size.height, 1);
|
||||
}
|
||||
|
||||
if( !allow_odd )
|
||||
{
|
||||
if( size.width > 1 && (size.width&1) != 0 )
|
||||
size.width = (size.width + 1) & -2;
|
||||
|
||||
if( size.height > 1 && (size.height&1) != 0 && !(flags & CV_DXT_ROWS) )
|
||||
size.height = (size.height + 1) & -2;
|
||||
}
|
||||
|
||||
sizes[INPUT][0] = sizes[OUTPUT][0] = size;
|
||||
sizes[TEMP][0] = sizes[TEMP][1] = cvSize(0,0);
|
||||
|
||||
if( spectrum_mode )
|
||||
{
|
||||
if( cn == 1 )
|
||||
{
|
||||
types[OUTPUT][0] = depth + 8;
|
||||
sizes[TEMP][0] = size;
|
||||
}
|
||||
sizes[INPUT][0] = sizes[INPUT][1] = size;
|
||||
types[INPUT][1] = types[INPUT][0];
|
||||
}
|
||||
else if( /*(cn == 2 && (bits&32)) ||*/ (cn == 1 && allow_complex) )
|
||||
{
|
||||
types[TEMP][0] = depth + 8; // CV_??FC2
|
||||
sizes[TEMP][0] = size;
|
||||
size = cvSize(size.width/2+1, size.height);
|
||||
|
||||
if( flags & CV_DXT_INVERSE )
|
||||
{
|
||||
if( cn == 2 )
|
||||
{
|
||||
types[OUTPUT][0] = depth;
|
||||
sizes[INPUT][0] = size;
|
||||
}
|
||||
types[TEMP][1] = types[TEMP][0];
|
||||
sizes[TEMP][1] = sizes[TEMP][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if( allow_complex )
|
||||
types[OUTPUT][0] = depth + 8;
|
||||
|
||||
if( cn == 2 )
|
||||
{
|
||||
types[INPUT][0] = depth;
|
||||
types[TEMP][1] = types[TEMP][0];
|
||||
sizes[TEMP][1] = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
types[TEMP][1] = depth;
|
||||
sizes[TEMP][1] = sizes[TEMP][0];
|
||||
}
|
||||
temp_dst = true;
|
||||
}
|
||||
}
|
||||
|
||||
inplace = false;
|
||||
if( spectrum_mode ||
|
||||
(!temp_dst && types[INPUT][0] == types[OUTPUT][0]) ||
|
||||
(temp_dst && types[INPUT][0] == types[TEMP][1]) )
|
||||
inplace = (bits & 64) != 0;
|
||||
|
||||
types[REF_OUTPUT][0] = types[OUTPUT][0];
|
||||
sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
|
||||
}
|
||||
|
||||
|
||||
double CxCore_DXTBaseTest::get_success_error_level( int test_case_idx, int i, int j )
|
||||
{
|
||||
return Base::get_success_error_level( test_case_idx, i, j );
|
||||
}
|
||||
|
||||
|
||||
int CxCore_DXTBaseTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int code = Base::prepare_test_case( test_case_idx );
|
||||
if( code > 0 )
|
||||
{
|
||||
int in_type = test_mat[INPUT][0].type();
|
||||
int out_type = test_mat[OUTPUT][0].type();
|
||||
|
||||
if( CV_MAT_CN(in_type) == 2 && CV_MAT_CN(out_type) == 1 )
|
||||
cvtest::fixCCS( test_mat[INPUT][0], test_mat[OUTPUT][0].cols, flags );
|
||||
|
||||
if( inplace )
|
||||
cvtest::copy( test_mat[INPUT][test_case_idx & (int)spectrum_mode],
|
||||
temp_dst ? test_mat[TEMP][1] :
|
||||
in_type == out_type ? test_mat[OUTPUT][0] :
|
||||
test_mat[TEMP][0] );
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// FFT ////////////////////////
|
||||
class CxCore_DFTTest : public CxCore_DXTBaseTest
|
||||
{
|
||||
public:
|
||||
CxCore_DFTTest();
|
||||
protected:
|
||||
void run_func();
|
||||
void prepare_to_validation( int test_case_idx );
|
||||
};
|
||||
|
||||
|
||||
CxCore_DFTTest::CxCore_DFTTest() : CxCore_DXTBaseTest( true, true, false )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DFTTest::run_func()
|
||||
{
|
||||
Mat& dst = temp_dst ? test_mat[TEMP][1] : test_mat[OUTPUT][0];
|
||||
const Mat& src = inplace ? dst : test_mat[INPUT][0];
|
||||
|
||||
if(!(flags & CV_DXT_INVERSE))
|
||||
cv::dft( src, dst, flags );
|
||||
else
|
||||
cv::idft(src, dst, flags & ~CV_DXT_INVERSE);
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DFTTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
Mat& src = test_mat[INPUT][0];
|
||||
Mat& dst = test_mat[REF_OUTPUT][0];
|
||||
Mat* tmp_src = &src;
|
||||
Mat* tmp_dst = &dst;
|
||||
int src_cn = src.channels();
|
||||
int dst_cn = dst.channels();
|
||||
|
||||
if( src_cn != 2 || dst_cn != 2 )
|
||||
{
|
||||
tmp_src = &test_mat[TEMP][0];
|
||||
|
||||
if( !(flags & CV_DXT_INVERSE ) )
|
||||
{
|
||||
Mat& cvdft_dst = test_mat[TEMP][1];
|
||||
cvtest::convertFromCCS( cvdft_dst, cvdft_dst,
|
||||
test_mat[OUTPUT][0], flags );
|
||||
*tmp_src = Scalar::all(0);
|
||||
cvtest::insert( src, *tmp_src, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
cvtest::convertFromCCS( src, src, *tmp_src, flags );
|
||||
tmp_dst = &test_mat[TEMP][1];
|
||||
}
|
||||
}
|
||||
|
||||
if( src.rows == 1 || (src.cols == 1 && !(flags & CV_DXT_ROWS)) )
|
||||
cvtest::DFT_1D( *tmp_src, *tmp_dst, flags );
|
||||
else
|
||||
cvtest::DFT_2D( *tmp_src, *tmp_dst, flags );
|
||||
|
||||
if( tmp_dst != &dst )
|
||||
cvtest::extract( *tmp_dst, dst, 0 );
|
||||
}
|
||||
|
||||
////////////////////// DCT ////////////////////////
|
||||
class CxCore_DCTTest : public CxCore_DXTBaseTest
|
||||
{
|
||||
public:
|
||||
CxCore_DCTTest();
|
||||
protected:
|
||||
void run_func();
|
||||
void prepare_to_validation( int test_case_idx );
|
||||
};
|
||||
|
||||
|
||||
CxCore_DCTTest::CxCore_DCTTest() : CxCore_DXTBaseTest( false, false, false )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DCTTest::run_func()
|
||||
{
|
||||
Mat& dst = test_mat[OUTPUT][0];
|
||||
const Mat& src = inplace ? dst : test_mat[INPUT][0];
|
||||
|
||||
if(!(flags & CV_DXT_INVERSE))
|
||||
cv::dct( src, dst, flags );
|
||||
else
|
||||
cv::idct( src, dst, flags & ~CV_DXT_INVERSE);
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DCTTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
const Mat& src = test_mat[INPUT][0];
|
||||
Mat& dst = test_mat[REF_OUTPUT][0];
|
||||
|
||||
if( src.rows == 1 || (src.cols == 1 && !(flags & CV_DXT_ROWS)) )
|
||||
cvtest::DCT_1D( src, dst, flags );
|
||||
else
|
||||
cvtest::DCT_2D( src, dst, flags );
|
||||
}
|
||||
|
||||
|
||||
////////////////////// MulSpectrums ////////////////////////
|
||||
class CxCore_MulSpectrumsTest : public CxCore_DXTBaseTest
|
||||
{
|
||||
public:
|
||||
CxCore_MulSpectrumsTest();
|
||||
protected:
|
||||
void run_func();
|
||||
void prepare_to_validation( int test_case_idx );
|
||||
};
|
||||
|
||||
|
||||
CxCore_MulSpectrumsTest::CxCore_MulSpectrumsTest() : CxCore_DXTBaseTest( true, true, true )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CxCore_MulSpectrumsTest::run_func()
|
||||
{
|
||||
Mat& dst = !test_mat[TEMP].empty() && !test_mat[TEMP][0].empty() ?
|
||||
test_mat[TEMP][0] : test_mat[OUTPUT][0];
|
||||
const Mat* src1 = &test_mat[INPUT][0], *src2 = &test_mat[INPUT][1];
|
||||
|
||||
if( inplace )
|
||||
{
|
||||
if( ts->get_current_test_info()->test_case_idx & 1 )
|
||||
src2 = &dst;
|
||||
else
|
||||
src1 = &dst;
|
||||
}
|
||||
|
||||
cv::mulSpectrums( *src1, *src2, dst, flags, (flags & CV_DXT_MUL_CONJ) != 0 );
|
||||
}
|
||||
|
||||
|
||||
void CxCore_MulSpectrumsTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
Mat* src1 = &test_mat[INPUT][0];
|
||||
Mat* src2 = &test_mat[INPUT][1];
|
||||
Mat& dst = test_mat[OUTPUT][0];
|
||||
Mat& dst0 = test_mat[REF_OUTPUT][0];
|
||||
int cn = src1->channels();
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
cvtest::convertFromCCS( *src1, *src1, dst, flags );
|
||||
cvtest::convertFromCCS( *src2, *src2, dst0, flags );
|
||||
src1 = &dst;
|
||||
src2 = &dst0;
|
||||
}
|
||||
|
||||
cvtest::mulComplex( *src1, *src2, dst0, flags );
|
||||
if( cn == 1 )
|
||||
{
|
||||
Mat& temp = test_mat[TEMP][0];
|
||||
cvtest::convertFromCCS( temp, temp, dst, flags );
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_DCT, accuracy) { CxCore_DCTTest test; test.safe_run(); }
|
||||
TEST(Core_DFT, accuracy) { CxCore_DFTTest test; test.safe_run(); }
|
||||
TEST(Core_MulSpectrums, accuracy) { CxCore_MulSpectrumsTest test; test.safe_run(); }
|
||||
|
382
modules/core/test/test_io.cpp
Normal file
382
modules/core/test/test_io.cpp
Normal file
@@ -0,0 +1,382 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static SparseMat cvTsGetRandomSparseMat(int dims, const int* sz, int type,
|
||||
int nzcount, double a, double b, RNG& rng)
|
||||
{
|
||||
SparseMat m(dims, sz, type);
|
||||
int i, j;
|
||||
CV_Assert(CV_MAT_CN(type) == 1);
|
||||
for( i = 0; i < nzcount; i++ )
|
||||
{
|
||||
int idx[CV_MAX_DIM];
|
||||
for( j = 0; j < dims; j++ )
|
||||
idx[j] = cvtest::randInt(rng) % sz[j];
|
||||
double val = cvtest::randReal(rng)*(b - a) + a;
|
||||
uchar* ptr = m.ptr(idx, true, 0);
|
||||
if( type == CV_8U )
|
||||
*(uchar*)ptr = saturate_cast<uchar>(val);
|
||||
else if( type == CV_8S )
|
||||
*(schar*)ptr = saturate_cast<schar>(val);
|
||||
else if( type == CV_16U )
|
||||
*(ushort*)ptr = saturate_cast<ushort>(val);
|
||||
else if( type == CV_16S )
|
||||
*(short*)ptr = saturate_cast<short>(val);
|
||||
else if( type == CV_32S )
|
||||
*(int*)ptr = saturate_cast<int>(val);
|
||||
else if( type == CV_32F )
|
||||
*(float*)ptr = saturate_cast<float>(val);
|
||||
else
|
||||
*(double*)ptr = saturate_cast<double>(val);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
static bool cvTsCheckSparse(const CvSparseMat* m1, const CvSparseMat* m2, double eps)
|
||||
{
|
||||
CvSparseMatIterator it1;
|
||||
CvSparseNode* node1;
|
||||
int depth = CV_MAT_DEPTH(m1->type);
|
||||
|
||||
if( m1->heap->active_count != m2->heap->active_count ||
|
||||
m1->dims != m2->dims || CV_MAT_TYPE(m1->type) != CV_MAT_TYPE(m2->type) )
|
||||
return false;
|
||||
|
||||
for( node1 = cvInitSparseMatIterator( m1, &it1 );
|
||||
node1 != 0; node1 = cvGetNextSparseNode( &it1 ))
|
||||
{
|
||||
uchar* v1 = (uchar*)CV_NODE_VAL(m1,node1);
|
||||
uchar* v2 = cvPtrND( m2, CV_NODE_IDX(m1,node1), 0, 0, &node1->hashval );
|
||||
if( !v2 )
|
||||
return false;
|
||||
if( depth == CV_8U || depth == CV_8S )
|
||||
{
|
||||
if( *v1 != *v2 )
|
||||
return false;
|
||||
}
|
||||
else if( depth == CV_16U || depth == CV_16S )
|
||||
{
|
||||
if( *(ushort*)v1 != *(ushort*)v2 )
|
||||
return false;
|
||||
}
|
||||
else if( depth == CV_32S )
|
||||
{
|
||||
if( *(int*)v1 != *(int*)v2 )
|
||||
return false;
|
||||
}
|
||||
else if( depth == CV_32F )
|
||||
{
|
||||
if( fabs(*(float*)v1 - *(float*)v2) > eps*(fabs(*(float*)v2) + 1) )
|
||||
return false;
|
||||
}
|
||||
else if( fabs(*(double*)v1 - *(double*)v2) > eps*(fabs(*(double*)v2) + 1) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class Core_IOTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_IOTest() {};
|
||||
protected:
|
||||
void run(int)
|
||||
{
|
||||
double ranges[][2] = {{0, 256}, {-128, 128}, {0, 65536}, {-32768, 32768},
|
||||
{-1000000, 1000000}, {-10, 10}, {-10, 10}};
|
||||
RNG& rng = ts->get_rng();
|
||||
RNG rng0;
|
||||
test_case_count = 2;
|
||||
int progress = 0;
|
||||
MemStorage storage(cvCreateMemStorage(0));
|
||||
|
||||
for( int idx = 0; idx < test_case_count; idx++ )
|
||||
{
|
||||
ts->update_context( this, idx, false );
|
||||
progress = update_progress( progress, idx, test_case_count, 0 );
|
||||
|
||||
cvClearMemStorage(storage);
|
||||
|
||||
char buf[L_tmpnam+16];
|
||||
char* filename = tmpnam(buf);
|
||||
strcat(filename, idx % 2 ? ".yml" : ".xml");
|
||||
if(filename[0] == '\\')
|
||||
filename++;
|
||||
|
||||
FileStorage fs(filename, FileStorage::WRITE);
|
||||
|
||||
int test_int = (int)cvtest::randInt(rng);
|
||||
double test_real = (cvtest::randInt(rng)%2?1:-1)*exp(cvtest::randReal(rng)*18-9);
|
||||
string test_string = "vw wv23424rt\"&<>&'@#$@$%$%&%IJUKYILFD@#$@%$&*&() ";
|
||||
|
||||
int depth = cvtest::randInt(rng) % (CV_64F+1);
|
||||
int cn = cvtest::randInt(rng) % 4 + 1;
|
||||
Mat test_mat(cvtest::randInt(rng)%30+1, cvtest::randInt(rng)%30+1, CV_MAKETYPE(depth, cn));
|
||||
|
||||
rng0.fill(test_mat, CV_RAND_UNI, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1]));
|
||||
if( depth >= CV_32F )
|
||||
{
|
||||
exp(test_mat, test_mat);
|
||||
Mat test_mat_scale(test_mat.size(), test_mat.type());
|
||||
rng0.fill(test_mat_scale, CV_RAND_UNI, Scalar::all(-1), Scalar::all(1));
|
||||
multiply(test_mat, test_mat_scale, test_mat);
|
||||
}
|
||||
|
||||
CvSeq* seq = cvCreateSeq(test_mat.type(), (int)sizeof(CvSeq),
|
||||
(int)test_mat.elemSize(), storage);
|
||||
cvSeqPushMulti(seq, test_mat.data, test_mat.cols*test_mat.rows);
|
||||
|
||||
CvGraph* graph = cvCreateGraph( CV_ORIENTED_GRAPH,
|
||||
sizeof(CvGraph), sizeof(CvGraphVtx),
|
||||
sizeof(CvGraphEdge), storage );
|
||||
int edges[][2] = {{0,1},{1,2},{2,0},{0,3},{3,4},{4,1}};
|
||||
int i, vcount = 5, ecount = 6;
|
||||
for( i = 0; i < vcount; i++ )
|
||||
cvGraphAddVtx(graph);
|
||||
for( i = 0; i < ecount; i++ )
|
||||
{
|
||||
CvGraphEdge* edge;
|
||||
cvGraphAddEdge(graph, edges[i][0], edges[i][1], 0, &edge);
|
||||
edge->weight = (float)(i+1);
|
||||
}
|
||||
|
||||
depth = cvtest::randInt(rng) % (CV_64F+1);
|
||||
cn = cvtest::randInt(rng) % 4 + 1;
|
||||
int sz[] = {cvtest::randInt(rng)%10+1, cvtest::randInt(rng)%10+1, cvtest::randInt(rng)%10+1};
|
||||
MatND test_mat_nd(3, sz, CV_MAKETYPE(depth, cn));
|
||||
|
||||
rng0.fill(test_mat_nd, CV_RAND_UNI, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1]));
|
||||
if( depth >= CV_32F )
|
||||
{
|
||||
exp(test_mat_nd, test_mat_nd);
|
||||
MatND test_mat_scale(test_mat_nd.dims, test_mat_nd.size, test_mat_nd.type());
|
||||
rng0.fill(test_mat_scale, CV_RAND_UNI, Scalar::all(-1), Scalar::all(1));
|
||||
multiply(test_mat_nd, test_mat_scale, test_mat_nd);
|
||||
}
|
||||
|
||||
int ssz[] = {cvtest::randInt(rng)%10+1, cvtest::randInt(rng)%10+1,
|
||||
cvtest::randInt(rng)%10+1,cvtest::randInt(rng)%10+1};
|
||||
SparseMat test_sparse_mat = cvTsGetRandomSparseMat(4, ssz, cvtest::randInt(rng)%(CV_64F+1),
|
||||
cvtest::randInt(rng) % 10000, 0, 100, rng);
|
||||
|
||||
fs << "test_int" << test_int << "test_real" << test_real << "test_string" << test_string;
|
||||
fs << "test_mat" << test_mat;
|
||||
fs << "test_mat_nd" << test_mat_nd;
|
||||
fs << "test_sparse_mat" << test_sparse_mat;
|
||||
|
||||
fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" <<
|
||||
"{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]";
|
||||
fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
|
||||
|
||||
const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
|
||||
fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
|
||||
|
||||
fs << "]" << "}";
|
||||
cvWriteComment(*fs, "test comment", 0);
|
||||
|
||||
fs.writeObj("test_seq", seq);
|
||||
fs.writeObj("test_graph",graph);
|
||||
CvGraph* graph2 = (CvGraph*)cvClone(graph);
|
||||
|
||||
fs.release();
|
||||
|
||||
if(!fs.open(filename, FileStorage::READ))
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "filename %s can not be read\n", filename );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
|
||||
return;
|
||||
}
|
||||
|
||||
int real_int = (int)fs["test_int"];
|
||||
double real_real = (double)fs["test_real"];
|
||||
string real_string = (string)fs["test_string"];
|
||||
|
||||
if( real_int != test_int ||
|
||||
fabs(real_real - test_real) > DBL_EPSILON*(fabs(test_real)+1) ||
|
||||
real_string != test_string )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the read scalars are not correct\n" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
CvMat* m = (CvMat*)fs["test_mat"].readObj();
|
||||
CvMat _test_mat = test_mat;
|
||||
double max_diff = 0;
|
||||
CvMat stub1, _test_stub1;
|
||||
cvReshape(m, &stub1, 1, 0);
|
||||
cvReshape(&_test_mat, &_test_stub1, 1, 0);
|
||||
vector<int> pt;
|
||||
|
||||
if( !m || !CV_IS_MAT(m) || m->rows != test_mat.rows || m->cols != test_mat.cols ||
|
||||
cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the read matrix is not correct: (%.20g vs %.20g) at (%d,%d)\n",
|
||||
cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]),
|
||||
pt[0], pt[1] );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
if( m && CV_IS_MAT(m))
|
||||
cvReleaseMat(&m);
|
||||
|
||||
CvMatND* m_nd = (CvMatND*)fs["test_mat_nd"].readObj();
|
||||
CvMatND _test_mat_nd = test_mat_nd;
|
||||
|
||||
if( !m_nd || !CV_IS_MATND(m_nd) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the read nd-matrix is not correct\n" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
CvMat stub, _test_stub;
|
||||
cvGetMat(m_nd, &stub, 0, 1);
|
||||
cvGetMat(&_test_mat_nd, &_test_stub, 0, 1);
|
||||
cvReshape(&stub, &stub1, 1, 0);
|
||||
cvReshape(&_test_stub, &_test_stub1, 1, 0);
|
||||
|
||||
if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) ||
|
||||
!CV_ARE_SIZES_EQ(&stub, &_test_stub) ||
|
||||
//cvNorm(&stub, &_test_stub, CV_L2) != 0 )
|
||||
cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "readObj method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n",
|
||||
cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]),
|
||||
pt[0], pt[1] );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
MatND mat_nd2;
|
||||
fs["test_mat_nd"] >> mat_nd2;
|
||||
CvMatND m_nd2 = mat_nd2;
|
||||
cvGetMat(&m_nd2, &stub, 0, 1);
|
||||
cvReshape(&stub, &stub1, 1, 0);
|
||||
|
||||
if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) ||
|
||||
!CV_ARE_SIZES_EQ(&stub, &_test_stub) ||
|
||||
//cvNorm(&stub, &_test_stub, CV_L2) != 0 )
|
||||
cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "C++ method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n",
|
||||
cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[1], pt[0]),
|
||||
pt[0], pt[1] );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
cvRelease((void**)&m_nd);
|
||||
|
||||
Ptr<CvSparseMat> m_s = (CvSparseMat*)fs["test_sparse_mat"].readObj();
|
||||
Ptr<CvSparseMat> _test_sparse_ = (CvSparseMat*)test_sparse_mat;
|
||||
Ptr<CvSparseMat> _test_sparse = (CvSparseMat*)cvClone(_test_sparse_);
|
||||
SparseMat m_s2;
|
||||
fs["test_sparse_mat"] >> m_s2;
|
||||
Ptr<CvSparseMat> _m_s2 = (CvSparseMat*)m_s2;
|
||||
|
||||
if( !m_s || !CV_IS_SPARSE_MAT(m_s) ||
|
||||
!cvTsCheckSparse(m_s, _test_sparse,0) ||
|
||||
!cvTsCheckSparse(_m_s2, _test_sparse,0))
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the read sparse matrix is not correct\n" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
FileNode tl = fs["test_list"];
|
||||
if( tl.type() != FileNode::SEQ || tl.size() != 6 ||
|
||||
fabs((double)tl[0] - 0.0000000000001) >= DBL_EPSILON ||
|
||||
(int)tl[1] != 2 ||
|
||||
fabs((double)tl[2] - CV_PI) >= DBL_EPSILON ||
|
||||
(int)tl[3] != -3435345 ||
|
||||
(string)tl[4] != "2-502 2-029 3egegeg" ||
|
||||
tl[5].type() != FileNode::MAP || tl[5].size() != 3 ||
|
||||
(int)tl[5]["month"] != 12 ||
|
||||
(int)tl[5]["day"] != 31 ||
|
||||
(int)tl[5]["year"] != 1969 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the test list is incorrect\n" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
FileNode tm = fs["test_map"];
|
||||
FileNode tm_lbp = tm["lbp"];
|
||||
|
||||
int real_x = (int)tm["x"];
|
||||
int real_y = (int)tm["y"];
|
||||
int real_width = (int)tm["width"];
|
||||
int real_height = (int)tm["height"];
|
||||
|
||||
|
||||
int real_lbp_val = 0;
|
||||
FileNodeIterator it;
|
||||
it = tm_lbp.begin();
|
||||
real_lbp_val |= (int)*it << 0;
|
||||
++it;
|
||||
real_lbp_val |= (int)*it << 1;
|
||||
it++;
|
||||
real_lbp_val |= (int)*it << 2;
|
||||
it += 1;
|
||||
real_lbp_val |= (int)*it << 3;
|
||||
FileNodeIterator it2(it);
|
||||
it2 += 4;
|
||||
real_lbp_val |= (int)*it2 << 7;
|
||||
--it2;
|
||||
real_lbp_val |= (int)*it2 << 6;
|
||||
it2--;
|
||||
real_lbp_val |= (int)*it2 << 5;
|
||||
it2 -= 1;
|
||||
real_lbp_val |= (int)*it2 << 4;
|
||||
it2 += -1;
|
||||
CV_Assert( it == it2 );
|
||||
|
||||
if( tm.type() != FileNode::MAP || tm.size() != 5 ||
|
||||
real_x != 1 ||
|
||||
real_y != 2 ||
|
||||
real_width != 100 ||
|
||||
real_height != 200 ||
|
||||
tm_lbp.type() != FileNode::SEQ ||
|
||||
tm_lbp.size() != 8 ||
|
||||
real_lbp_val != 0xb6 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the test map is incorrect\n" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
CvGraph* graph3 = (CvGraph*)fs["test_graph"].readObj();
|
||||
if(graph2->active_count != vcount || graph3->active_count != vcount ||
|
||||
graph2->edges->active_count != ecount || graph3->edges->active_count != ecount)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the cloned or read graph have wrong number of vertices or edges\n" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0; i < ecount; i++ )
|
||||
{
|
||||
CvGraphEdge* edge2 = cvFindGraphEdge(graph2, edges[i][0], edges[i][1]);
|
||||
CvGraphEdge* edge3 = cvFindGraphEdge(graph3, edges[i][0], edges[i][1]);
|
||||
if( !edge2 || edge2->weight != (float)(i+1) ||
|
||||
!edge3 || edge3->weight != (float)(i+1) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the cloned or read graph do not have the edge (%d, %d)\n", edges[i][0], edges[i][1] );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fs.release();
|
||||
remove(filename);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Core_InputOutput, write_read_consistency) { Core_IOTest test; test.safe_run(); }
|
@@ -1,2 +1,3 @@
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/gtest/gtest_main.hpp"
|
||||
|
||||
CV_TEST_MAIN("cv")
|
||||
|
811
modules/core/test/test_mat.cpp
Normal file
811
modules/core/test/test_mat.cpp
Normal file
@@ -0,0 +1,811 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
|
||||
class Core_ReduceTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_ReduceTest() {};
|
||||
protected:
|
||||
void run( int);
|
||||
int checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim, double eps );
|
||||
int checkCase( int srcType, int dstType, int dim, Size sz );
|
||||
int checkDim( int dim, Size sz );
|
||||
int checkSize( Size sz );
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim )
|
||||
{
|
||||
assert( src.channels() == 1 );
|
||||
if( dim == 0 ) // row
|
||||
{
|
||||
sum.create( 1, src.cols, CV_64FC1 );
|
||||
max.create( 1, src.cols, CV_64FC1 );
|
||||
min.create( 1, src.cols, CV_64FC1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
sum.create( src.rows, 1, CV_64FC1 );
|
||||
max.create( src.rows, 1, CV_64FC1 );
|
||||
min.create( src.rows, 1, CV_64FC1 );
|
||||
}
|
||||
sum.setTo(Scalar(0));
|
||||
max.setTo(Scalar(-DBL_MAX));
|
||||
min.setTo(Scalar(DBL_MAX));
|
||||
|
||||
const Mat_<Type>& src_ = src;
|
||||
Mat_<double>& sum_ = (Mat_<double>&)sum;
|
||||
Mat_<double>& min_ = (Mat_<double>&)min;
|
||||
Mat_<double>& max_ = (Mat_<double>&)max;
|
||||
|
||||
if( dim == 0 )
|
||||
{
|
||||
for( int ri = 0; ri < src.rows; ri++ )
|
||||
{
|
||||
for( int ci = 0; ci < src.cols; ci++ )
|
||||
{
|
||||
sum_(0, ci) += src_(ri, ci);
|
||||
max_(0, ci) = std::max( max_(0, ci), (double)src_(ri, ci) );
|
||||
min_(0, ci) = std::min( min_(0, ci), (double)src_(ri, ci) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int ci = 0; ci < src.cols; ci++ )
|
||||
{
|
||||
for( int ri = 0; ri < src.rows; ri++ )
|
||||
{
|
||||
sum_(ri, 0) += src_(ri, ci);
|
||||
max_(ri, 0) = std::max( max_(ri, 0), (double)src_(ri, ci) );
|
||||
min_(ri, 0) = std::min( min_(ri, 0), (double)src_(ri, ci) );
|
||||
}
|
||||
}
|
||||
}
|
||||
sum.convertTo( avg, CV_64FC1 );
|
||||
avg = avg * (1.0 / (dim==0 ? (double)src.rows : (double)src.cols));
|
||||
}
|
||||
|
||||
void getMatTypeStr( int type, string& str)
|
||||
{
|
||||
str = type == CV_8UC1 ? "CV_8UC1" :
|
||||
type == CV_8SC1 ? "CV_8SC1" :
|
||||
type == CV_16UC1 ? "CV_16UC1" :
|
||||
type == CV_16SC1 ? "CV_16SC1" :
|
||||
type == CV_32SC1 ? "CV_32SC1" :
|
||||
type == CV_32FC1 ? "CV_32FC1" :
|
||||
type == CV_64FC1 ? "CV_64FC1" : "unsupported matrix type";
|
||||
}
|
||||
|
||||
int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim, double eps )
|
||||
{
|
||||
int srcType = src.type();
|
||||
bool support = false;
|
||||
if( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG )
|
||||
{
|
||||
if( srcType == CV_8U && (dstType == CV_32S || dstType == CV_32F || dstType == CV_64F) )
|
||||
support = true;
|
||||
if( srcType == CV_16U && (dstType == CV_32F || dstType == CV_64F) )
|
||||
support = true;
|
||||
if( srcType == CV_16S && (dstType == CV_32F || dstType == CV_64F) )
|
||||
support = true;
|
||||
if( srcType == CV_32F && (dstType == CV_32F || dstType == CV_64F) )
|
||||
support = true;
|
||||
if( srcType == CV_64F && dstType == CV_64F)
|
||||
support = true;
|
||||
}
|
||||
else if( opType == CV_REDUCE_MAX )
|
||||
{
|
||||
if( srcType == CV_8U && dstType == CV_8U )
|
||||
support = true;
|
||||
if( srcType == CV_32F && dstType == CV_32F )
|
||||
support = true;
|
||||
if( srcType == CV_64F && dstType == CV_64F )
|
||||
support = true;
|
||||
}
|
||||
else if( opType == CV_REDUCE_MIN )
|
||||
{
|
||||
if( srcType == CV_8U && dstType == CV_8U)
|
||||
support = true;
|
||||
if( srcType == CV_32F && dstType == CV_32F)
|
||||
support = true;
|
||||
if( srcType == CV_64F && dstType == CV_64F)
|
||||
support = true;
|
||||
}
|
||||
if( !support )
|
||||
return cvtest::TS::OK;
|
||||
|
||||
assert( opRes.type() == CV_64FC1 );
|
||||
Mat _dst, dst;
|
||||
reduce( src, _dst, dim, opType, dstType );
|
||||
_dst.convertTo( dst, CV_64FC1 );
|
||||
if( norm( opRes, dst, NORM_INF ) > eps )
|
||||
{
|
||||
char msg[100];
|
||||
const char* opTypeStr = opType == CV_REDUCE_SUM ? "CV_REDUCE_SUM" :
|
||||
opType == CV_REDUCE_AVG ? "CV_REDUCE_AVG" :
|
||||
opType == CV_REDUCE_MAX ? "CV_REDUCE_MAX" :
|
||||
opType == CV_REDUCE_MIN ? "CV_REDUCE_MIN" : "unknown operation type";
|
||||
string srcTypeStr, dstTypeStr;
|
||||
getMatTypeStr( src.type(), srcTypeStr );
|
||||
getMatTypeStr( dstType, dstTypeStr );
|
||||
const char* dimStr = dim == 0 ? "ROWS" : "COLS";
|
||||
|
||||
sprintf( msg, "bad accuracy with srcType = %s, dstType = %s, opType = %s, dim = %s",
|
||||
srcTypeStr.c_str(), dstTypeStr.c_str(), opTypeStr, dimStr );
|
||||
ts->printf( cvtest::TS::LOG, msg );
|
||||
return cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
}
|
||||
return cvtest::TS::OK;
|
||||
}
|
||||
|
||||
int Core_ReduceTest::checkCase( int srcType, int dstType, int dim, Size sz )
|
||||
{
|
||||
int code = cvtest::TS::OK, tempCode;
|
||||
Mat src, sum, avg, max, min;
|
||||
|
||||
src.create( sz, srcType );
|
||||
randu( src, Scalar(0), Scalar(100) );
|
||||
|
||||
if( srcType == CV_8UC1 )
|
||||
testReduce<uchar>( src, sum, avg, max, min, dim );
|
||||
else if( srcType == CV_8SC1 )
|
||||
testReduce<char>( src, sum, avg, max, min, dim );
|
||||
else if( srcType == CV_16UC1 )
|
||||
testReduce<unsigned short int>( src, sum, avg, max, min, dim );
|
||||
else if( srcType == CV_16SC1 )
|
||||
testReduce<short int>( src, sum, avg, max, min, dim );
|
||||
else if( srcType == CV_32SC1 )
|
||||
testReduce<int>( src, sum, avg, max, min, dim );
|
||||
else if( srcType == CV_32FC1 )
|
||||
testReduce<float>( src, sum, avg, max, min, dim );
|
||||
else if( srcType == CV_64FC1 )
|
||||
testReduce<double>( src, sum, avg, max, min, dim );
|
||||
else
|
||||
assert( 0 );
|
||||
|
||||
// 1. sum
|
||||
tempCode = checkOp( src, dstType, CV_REDUCE_SUM, sum, dim,
|
||||
srcType == CV_32FC1 && dstType == CV_32FC1 ? 0.05 : FLT_EPSILON );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
// 2. avg
|
||||
tempCode = checkOp( src, dstType, CV_REDUCE_AVG, avg, dim,
|
||||
dstType == CV_32SC1 ? 0.6 : 0.00007 );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
// 3. max
|
||||
tempCode = checkOp( src, dstType, CV_REDUCE_MAX, max, dim, FLT_EPSILON );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
// 4. min
|
||||
tempCode = checkOp( src, dstType, CV_REDUCE_MIN, min, dim, FLT_EPSILON );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int Core_ReduceTest::checkDim( int dim, Size sz )
|
||||
{
|
||||
int code = cvtest::TS::OK, tempCode;
|
||||
|
||||
// CV_8UC1
|
||||
tempCode = checkCase( CV_8UC1, CV_8UC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkCase( CV_8UC1, CV_32SC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkCase( CV_8UC1, CV_32FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkCase( CV_8UC1, CV_64FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
// CV_16UC1
|
||||
tempCode = checkCase( CV_16UC1, CV_32FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkCase( CV_16UC1, CV_64FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
// CV_16SC1
|
||||
tempCode = checkCase( CV_16SC1, CV_32FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkCase( CV_16SC1, CV_64FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
// CV_32FC1
|
||||
tempCode = checkCase( CV_32FC1, CV_32FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkCase( CV_32FC1, CV_64FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
// CV_64FC1
|
||||
tempCode = checkCase( CV_64FC1, CV_64FC1, dim, sz );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int Core_ReduceTest::checkSize( Size sz )
|
||||
{
|
||||
int code = cvtest::TS::OK, tempCode;
|
||||
|
||||
tempCode = checkDim( 0, sz ); // rows
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkDim( 1, sz ); // cols
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void Core_ReduceTest::run( int )
|
||||
{
|
||||
int code = cvtest::TS::OK, tempCode;
|
||||
|
||||
tempCode = checkSize( Size(1,1) );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkSize( Size(1,100) );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkSize( Size(100,1) );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
tempCode = checkSize( Size(1000,500) );
|
||||
code = tempCode != cvtest::TS::OK ? tempCode : code;
|
||||
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
|
||||
|
||||
#define CHECK_C
|
||||
|
||||
Size sz(200, 500);
|
||||
|
||||
class Core_PCATest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_PCATest() {}
|
||||
protected:
|
||||
void run(int)
|
||||
{
|
||||
int code = cvtest::TS::OK;
|
||||
|
||||
double diffPrjEps, diffBackPrjEps,
|
||||
prjEps, backPrjEps,
|
||||
evalEps, evecEps;
|
||||
int maxComponents = 100;
|
||||
Mat rPoints(sz, CV_32FC1), rTestPoints(sz, CV_32FC1);
|
||||
RNG& rng = ts->get_rng();
|
||||
|
||||
rng.fill( rPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );
|
||||
rng.fill( rTestPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );
|
||||
|
||||
PCA rPCA( rPoints, Mat(), CV_PCA_DATA_AS_ROW, maxComponents ), cPCA;
|
||||
|
||||
// 1. check C++ PCA & ROW
|
||||
Mat rPrjTestPoints = rPCA.project( rTestPoints );
|
||||
Mat rBackPrjTestPoints = rPCA.backProject( rPrjTestPoints );
|
||||
|
||||
Mat avg(1, sz.width, CV_32FC1 );
|
||||
reduce( rPoints, avg, 0, CV_REDUCE_AVG );
|
||||
Mat Q = rPoints - repeat( avg, rPoints.rows, 1 ), Qt = Q.t(), eval, evec;
|
||||
Q = Qt * Q;
|
||||
Q = Q /(float)rPoints.rows;
|
||||
|
||||
eigen( Q, eval, evec );
|
||||
/*SVD svd(Q);
|
||||
evec = svd.vt;
|
||||
eval = svd.w;*/
|
||||
|
||||
Mat subEval( maxComponents, 1, eval.type(), eval.data ),
|
||||
subEvec( maxComponents, evec.cols, evec.type(), evec.data );
|
||||
|
||||
#ifdef CHECK_C
|
||||
Mat prjTestPoints, backPrjTestPoints, cPoints = rPoints.t(), cTestPoints = rTestPoints.t();
|
||||
CvMat _points, _testPoints, _avg, _eval, _evec, _prjTestPoints, _backPrjTestPoints;
|
||||
#endif
|
||||
|
||||
// check eigen()
|
||||
double eigenEps = 1e-6;
|
||||
double err;
|
||||
for(int i = 0; i < Q.rows; i++ )
|
||||
{
|
||||
Mat v = evec.row(i).t();
|
||||
Mat Qv = Q * v;
|
||||
|
||||
Mat lv = eval.at<float>(i,0) * v;
|
||||
err = norm( Qv, lv );
|
||||
if( err > eigenEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of eigen(); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
}
|
||||
// check pca eigenvalues
|
||||
evalEps = 1e-6, evecEps = 1;
|
||||
err = norm( rPCA.eigenvalues, subEval );
|
||||
if( err > evalEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "pca.eigenvalues is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
// check pca eigenvectors
|
||||
err = norm( rPCA.eigenvectors, subEvec, CV_RELATIVE_L2 );
|
||||
if( err > evecEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
prjEps = 1.265, backPrjEps = 1.265;
|
||||
for( int i = 0; i < rTestPoints.rows; i++ )
|
||||
{
|
||||
// check pca project
|
||||
Mat subEvec_t = subEvec.t();
|
||||
Mat prj = rTestPoints.row(i) - avg; prj *= subEvec_t;
|
||||
err = norm(rPrjTestPoints.row(i), prj, CV_RELATIVE_L2);
|
||||
if( err > prjEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
// check pca backProject
|
||||
Mat backPrj = rPrjTestPoints.row(i) * subEvec + avg;
|
||||
err = norm( rBackPrjTestPoints.row(i), backPrj, CV_RELATIVE_L2 );
|
||||
if( err > backPrjEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. check C++ PCA & COL
|
||||
cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents );
|
||||
diffPrjEps = 1, diffBackPrjEps = 1;
|
||||
err = norm(cPCA.project(rTestPoints.t()), rPrjTestPoints.t(), CV_RELATIVE_L2 );
|
||||
if( err > diffPrjEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_COL); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
err = norm(cPCA.backProject(rPrjTestPoints.t()), rBackPrjTestPoints.t(), CV_RELATIVE_L2 );
|
||||
if( err > diffBackPrjEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
#ifdef CHECK_C
|
||||
// 3. check C PCA & ROW
|
||||
_points = rPoints;
|
||||
_testPoints = rTestPoints;
|
||||
_avg = avg;
|
||||
_eval = eval;
|
||||
_evec = evec;
|
||||
prjTestPoints.create(rTestPoints.rows, maxComponents, rTestPoints.type() );
|
||||
backPrjTestPoints.create(rPoints.size(), rPoints.type() );
|
||||
_prjTestPoints = prjTestPoints;
|
||||
_backPrjTestPoints = backPrjTestPoints;
|
||||
|
||||
cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_ROW );
|
||||
cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
|
||||
cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
|
||||
|
||||
err = norm(prjTestPoints, rPrjTestPoints, CV_RELATIVE_L2);
|
||||
if( err > diffPrjEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
err = norm(backPrjTestPoints, rBackPrjTestPoints, CV_RELATIVE_L2);
|
||||
if( err > diffBackPrjEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
// 3. check C PCA & COL
|
||||
_points = cPoints;
|
||||
_testPoints = cTestPoints;
|
||||
avg = avg.t(); _avg = avg;
|
||||
eval = eval.t(); _eval = eval;
|
||||
evec = evec.t(); _evec = evec;
|
||||
prjTestPoints = prjTestPoints.t(); _prjTestPoints = prjTestPoints;
|
||||
backPrjTestPoints = backPrjTestPoints.t(); _backPrjTestPoints = backPrjTestPoints;
|
||||
|
||||
cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_COL );
|
||||
cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
|
||||
cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
|
||||
|
||||
err = norm(prjTestPoints, rPrjTestPoints.t(), CV_RELATIVE_L2 );
|
||||
if( err > diffPrjEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
err = norm(backPrjTestPoints, rBackPrjTestPoints.t(), CV_RELATIVE_L2);
|
||||
if( err > diffBackPrjEps )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto exit_func;
|
||||
}
|
||||
#endif
|
||||
|
||||
exit_func:
|
||||
|
||||
RNG& _rng = ts->get_rng();
|
||||
_rng = rng;
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
};
|
||||
|
||||
class Core_ArrayOpTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_ArrayOpTest();
|
||||
~Core_ArrayOpTest();
|
||||
protected:
|
||||
void run(int);
|
||||
};
|
||||
|
||||
|
||||
Core_ArrayOpTest::Core_ArrayOpTest()
|
||||
{
|
||||
}
|
||||
Core_ArrayOpTest::~Core_ArrayOpTest() {}
|
||||
|
||||
static string idx2string(const int* idx, int dims)
|
||||
{
|
||||
char buf[256];
|
||||
char* ptr = buf;
|
||||
for( int k = 0; k < dims; k++ )
|
||||
{
|
||||
sprintf(ptr, "%4d ", idx[k]);
|
||||
ptr += strlen(ptr);
|
||||
}
|
||||
ptr[-1] = '\0';
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
static const int* string2idx(const string& s, int* idx, int dims)
|
||||
{
|
||||
const char* ptr = s.c_str();
|
||||
for( int k = 0; k < dims; k++ )
|
||||
{
|
||||
int n = 0;
|
||||
sscanf(ptr, "%d%n", idx + k, &n);
|
||||
ptr += n;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
static double getValue(SparseMat& M, const int* idx, RNG& rng)
|
||||
{
|
||||
int d = M.dims();
|
||||
size_t hv = 0, *phv = 0;
|
||||
if( (unsigned)rng % 2 )
|
||||
{
|
||||
hv = d == 2 ? M.hash(idx[0], idx[1]) :
|
||||
d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
|
||||
phv = &hv;
|
||||
}
|
||||
|
||||
const uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], false, phv) :
|
||||
d == 3 ? M.ptr(idx[0], idx[1], idx[2], false, phv) :
|
||||
M.ptr(idx, false, phv);
|
||||
return !ptr ? 0 : M.type() == CV_32F ? *(float*)ptr : M.type() == CV_64F ? *(double*)ptr : 0;
|
||||
}
|
||||
|
||||
static double getValue(const CvSparseMat* M, const int* idx)
|
||||
{
|
||||
int type = 0;
|
||||
const uchar* ptr = cvPtrND(M, idx, &type, 0);
|
||||
return !ptr ? 0 : type == CV_32F ? *(float*)ptr : type == CV_64F ? *(double*)ptr : 0;
|
||||
}
|
||||
|
||||
static void eraseValue(SparseMat& M, const int* idx, RNG& rng)
|
||||
{
|
||||
int d = M.dims();
|
||||
size_t hv = 0, *phv = 0;
|
||||
if( (unsigned)rng % 2 )
|
||||
{
|
||||
hv = d == 2 ? M.hash(idx[0], idx[1]) :
|
||||
d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
|
||||
phv = &hv;
|
||||
}
|
||||
|
||||
if( d == 2 )
|
||||
M.erase(idx[0], idx[1], phv);
|
||||
else if( d == 3 )
|
||||
M.erase(idx[0], idx[1], idx[2], phv);
|
||||
else
|
||||
M.erase(idx, phv);
|
||||
}
|
||||
|
||||
static void eraseValue(CvSparseMat* M, const int* idx)
|
||||
{
|
||||
cvClearND(M, idx);
|
||||
}
|
||||
|
||||
static void setValue(SparseMat& M, const int* idx, double value, RNG& rng)
|
||||
{
|
||||
int d = M.dims();
|
||||
size_t hv = 0, *phv = 0;
|
||||
if( (unsigned)rng % 2 )
|
||||
{
|
||||
hv = d == 2 ? M.hash(idx[0], idx[1]) :
|
||||
d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
|
||||
phv = &hv;
|
||||
}
|
||||
|
||||
uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], true, phv) :
|
||||
d == 3 ? M.ptr(idx[0], idx[1], idx[2], true, phv) :
|
||||
M.ptr(idx, true, phv);
|
||||
if( M.type() == CV_32F )
|
||||
*(float*)ptr = (float)value;
|
||||
else if( M.type() == CV_64F )
|
||||
*(double*)ptr = value;
|
||||
else
|
||||
CV_Error(CV_StsUnsupportedFormat, "");
|
||||
}
|
||||
|
||||
void Core_ArrayOpTest::run( int /* start_from */)
|
||||
{
|
||||
int errcount = 0;
|
||||
|
||||
// dense matrix operations
|
||||
{
|
||||
int sz3[] = {5, 10, 15};
|
||||
MatND A(3, sz3, CV_32F), B(3, sz3, CV_16SC4);
|
||||
CvMatND matA = A, matB = B;
|
||||
RNG rng;
|
||||
rng.fill(A, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
|
||||
rng.fill(B, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
|
||||
|
||||
int idx0[] = {3,4,5}, idx1[] = {0, 9, 7};
|
||||
float val0 = 130;
|
||||
Scalar val1(-1000, 30, 3, 8);
|
||||
cvSetRealND(&matA, idx0, val0);
|
||||
cvSetReal3D(&matA, idx1[0], idx1[1], idx1[2], -val0);
|
||||
cvSetND(&matB, idx0, val1);
|
||||
cvSet3D(&matB, idx1[0], idx1[1], idx1[2], -val1);
|
||||
Ptr<CvMatND> matC = cvCloneMatND(&matB);
|
||||
|
||||
if( A.at<float>(idx0[0], idx0[1], idx0[2]) != val0 ||
|
||||
A.at<float>(idx1[0], idx1[1], idx1[2]) != -val0 ||
|
||||
cvGetReal3D(&matA, idx0[0], idx0[1], idx0[2]) != val0 ||
|
||||
cvGetRealND(&matA, idx1) != -val0 ||
|
||||
|
||||
Scalar(B.at<Vec4s>(idx0[0], idx0[1], idx0[2])) != val1 ||
|
||||
Scalar(B.at<Vec4s>(idx1[0], idx1[1], idx1[2])) != -val1 ||
|
||||
Scalar(cvGet3D(matC, idx0[0], idx0[1], idx0[2])) != val1 ||
|
||||
Scalar(cvGetND(matC, idx1)) != -val1 )
|
||||
{
|
||||
ts->printf(cvtest::TS::LOG, "one of cvSetReal3D, cvSetRealND, cvSet3D, cvSetND "
|
||||
"or the corresponding *Get* functions is not correct\n");
|
||||
errcount++;
|
||||
}
|
||||
}
|
||||
|
||||
RNG rng;
|
||||
const int MAX_DIM = 5, MAX_DIM_SZ = 10;
|
||||
// sparse matrix operations
|
||||
for( int si = 0; si < 10; si++ )
|
||||
{
|
||||
int depth = (unsigned)rng % 2 == 0 ? CV_32F : CV_64F;
|
||||
int dims = ((unsigned)rng % MAX_DIM) + 1;
|
||||
int i, k, size[MAX_DIM]={0}, idx[MAX_DIM]={0};
|
||||
vector<string> all_idxs;
|
||||
vector<double> all_vals;
|
||||
vector<double> all_vals2;
|
||||
string sidx, min_sidx, max_sidx;
|
||||
double min_val=0, max_val=0;
|
||||
|
||||
int p = 1;
|
||||
for( k = 0; k < dims; k++ )
|
||||
{
|
||||
size[k] = ((unsigned)rng % MAX_DIM_SZ) + 1;
|
||||
p *= size[k];
|
||||
}
|
||||
SparseMat M( dims, size, depth );
|
||||
map<string, double> M0;
|
||||
|
||||
int nz0 = (unsigned)rng % max(p/5,10);
|
||||
nz0 = min(max(nz0, 1), p);
|
||||
all_vals.resize(nz0);
|
||||
all_vals2.resize(nz0);
|
||||
Mat_<double> _all_vals(all_vals), _all_vals2(all_vals2);
|
||||
rng.fill(_all_vals, CV_RAND_UNI, Scalar(-1000), Scalar(1000));
|
||||
if( depth == CV_32F )
|
||||
{
|
||||
Mat _all_vals_f;
|
||||
_all_vals.convertTo(_all_vals_f, CV_32F);
|
||||
_all_vals_f.convertTo(_all_vals, CV_64F);
|
||||
}
|
||||
_all_vals.convertTo(_all_vals2, _all_vals2.type(), 2);
|
||||
if( depth == CV_32F )
|
||||
{
|
||||
Mat _all_vals2_f;
|
||||
_all_vals2.convertTo(_all_vals2_f, CV_32F);
|
||||
_all_vals2_f.convertTo(_all_vals2, CV_64F);
|
||||
}
|
||||
|
||||
minMaxLoc(_all_vals, &min_val, &max_val);
|
||||
double _norm0 = norm(_all_vals, CV_C);
|
||||
double _norm1 = norm(_all_vals, CV_L1);
|
||||
double _norm2 = norm(_all_vals, CV_L2);
|
||||
|
||||
for( i = 0; i < nz0; i++ )
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
for( k = 0; k < dims; k++ )
|
||||
idx[k] = (unsigned)rng % size[k];
|
||||
sidx = idx2string(idx, dims);
|
||||
if( M0.count(sidx) == 0 )
|
||||
break;
|
||||
}
|
||||
all_idxs.push_back(sidx);
|
||||
M0[sidx] = all_vals[i];
|
||||
if( all_vals[i] == min_val )
|
||||
min_sidx = sidx;
|
||||
if( all_vals[i] == max_val )
|
||||
max_sidx = sidx;
|
||||
setValue(M, idx, all_vals[i], rng);
|
||||
double v = getValue(M, idx, rng);
|
||||
if( v != all_vals[i] )
|
||||
{
|
||||
ts->printf(cvtest::TS::LOG, "%d. immediately after SparseMat[%s]=%.20g the current value is %.20g\n",
|
||||
i, sidx.c_str(), all_vals[i], v);
|
||||
errcount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<CvSparseMat> M2 = (CvSparseMat*)M;
|
||||
MatND Md;
|
||||
M.copyTo(Md);
|
||||
SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2);
|
||||
|
||||
int nz1 = (int)M.nzcount(), nz2 = (int)M3.nzcount();
|
||||
double norm0 = norm(M, CV_C);
|
||||
double norm1 = norm(M, CV_L1);
|
||||
double norm2 = norm(M, CV_L2);
|
||||
double eps = depth == CV_32F ? FLT_EPSILON*100 : DBL_EPSILON*1000;
|
||||
|
||||
if( nz1 != nz0 || nz2 != nz0)
|
||||
{
|
||||
errcount++;
|
||||
ts->printf(cvtest::TS::LOG, "%d: The number of non-zero elements before/after converting to/from dense matrix is not correct: %d/%d (while it should be %d)\n",
|
||||
si, nz1, nz2, nz0 );
|
||||
break;
|
||||
}
|
||||
|
||||
if( fabs(norm0 - _norm0) > fabs(_norm0)*eps ||
|
||||
fabs(norm1 - _norm1) > fabs(_norm1)*eps ||
|
||||
fabs(norm2 - _norm2) > fabs(_norm2)*eps )
|
||||
{
|
||||
errcount++;
|
||||
ts->printf(cvtest::TS::LOG, "%d: The norms are different: %.20g/%.20g/%.20g vs %.20g/%.20g/%.20g\n",
|
||||
si, norm0, norm1, norm2, _norm0, _norm1, _norm2 );
|
||||
break;
|
||||
}
|
||||
|
||||
int n = (unsigned)rng % max(p/5,10);
|
||||
n = min(max(n, 1), p) + nz0;
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
double val1, val2, val3, val0;
|
||||
if(i < nz0)
|
||||
{
|
||||
sidx = all_idxs[i];
|
||||
string2idx(sidx, idx, dims);
|
||||
val0 = all_vals[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for( k = 0; k < dims; k++ )
|
||||
idx[k] = (unsigned)rng % size[k];
|
||||
sidx = idx2string(idx, dims);
|
||||
val0 = M0[sidx];
|
||||
}
|
||||
val1 = getValue(M, idx, rng);
|
||||
val2 = getValue(M2, idx);
|
||||
val3 = getValue(M3, idx, rng);
|
||||
|
||||
if( val1 != val0 || val2 != val0 || fabs(val3 - val0*2) > fabs(val0*2)*FLT_EPSILON )
|
||||
{
|
||||
errcount++;
|
||||
ts->printf(cvtest::TS::LOG, "SparseMat M[%s] = %g/%g/%g (while it should be %g)\n", sidx.c_str(), val1, val2, val3, val0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
double val1, val2;
|
||||
if(i < nz0)
|
||||
{
|
||||
sidx = all_idxs[i];
|
||||
string2idx(sidx, idx, dims);
|
||||
}
|
||||
else
|
||||
{
|
||||
for( k = 0; k < dims; k++ )
|
||||
idx[k] = (unsigned)rng % size[k];
|
||||
sidx = idx2string(idx, dims);
|
||||
}
|
||||
eraseValue(M, idx, rng);
|
||||
eraseValue(M2, idx);
|
||||
val1 = getValue(M, idx, rng);
|
||||
val2 = getValue(M2, idx);
|
||||
if( val1 != 0 || val2 != 0 )
|
||||
{
|
||||
errcount++;
|
||||
ts->printf(cvtest::TS::LOG, "SparseMat: after deleting M[%s], it is =%g/%g (while it should be 0)\n", sidx.c_str(), val1, val2 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int nz = (int)M.nzcount();
|
||||
if( nz != 0 )
|
||||
{
|
||||
errcount++;
|
||||
ts->printf(cvtest::TS::LOG, "The number of non-zero elements after removing all the elements = %d (while it should be 0)\n", nz );
|
||||
break;
|
||||
}
|
||||
|
||||
int idx1[MAX_DIM], idx2[MAX_DIM];
|
||||
double val1 = 0, val2 = 0;
|
||||
M3 = SparseMat(Md);
|
||||
minMaxLoc(M3, &val1, &val2, idx1, idx2);
|
||||
string s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
|
||||
if( val1 != min_val || val2 != max_val || s1 != min_sidx || s2 != max_sidx )
|
||||
{
|
||||
errcount++;
|
||||
ts->printf(cvtest::TS::LOG, "%d. Sparse: The value and positions of minimum/maximum elements are different from the reference values and positions:\n\t"
|
||||
"(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
|
||||
min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
minMaxLoc(Md, &val1, &val2, idx1, idx2);
|
||||
s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
|
||||
if( (min_val < 0 && (val1 != min_val || s1 != min_sidx)) ||
|
||||
(max_val > 0 && (val2 != max_val || s2 != max_sidx)) )
|
||||
{
|
||||
errcount++;
|
||||
ts->printf(cvtest::TS::LOG, "%d. Dense: The value and positions of minimum/maximum elements are different from the reference values and positions:\n\t"
|
||||
"(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
|
||||
min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ts->set_failed_test_info(errcount == 0 ? cvtest::TS::OK : cvtest::TS::FAIL_INVALID_OUTPUT);
|
||||
}
|
||||
|
||||
TEST(Core_PCA, accuracy) { Core_PCATest test; test.safe_run(); }
|
||||
TEST(Core_Reduce, accuracy) { Core_ReduceTest test; test.safe_run(); }
|
||||
TEST(Core_Array, basic_operations) { Core_ArrayOpTest test; test.safe_run(); }
|
2372
modules/core/test/test_math.cpp
Normal file
2372
modules/core/test/test_math.cpp
Normal file
File diff suppressed because it is too large
Load Diff
829
modules/core/test/test_operations.cpp
Normal file
829
modules/core/test/test_operations.cpp
Normal file
@@ -0,0 +1,829 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
|
||||
class CV_OperationsTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_OperationsTest();
|
||||
~CV_OperationsTest();
|
||||
protected:
|
||||
void run(int);
|
||||
|
||||
struct test_excep
|
||||
{
|
||||
test_excep(const string& _s=string("")) : s(_s) {};
|
||||
string s;
|
||||
};
|
||||
|
||||
bool SomeMatFunctions();
|
||||
bool TestMat();
|
||||
bool TestTemplateMat();
|
||||
bool TestMatND();
|
||||
bool TestSparseMat();
|
||||
bool operations1();
|
||||
|
||||
void checkDiff(const Mat& m1, const Mat& m2, const string& s) { if (norm(m1, m2, NORM_INF) != 0) throw test_excep(s); }
|
||||
void checkDiffF(const Mat& m1, const Mat& m2, const string& s) { if (norm(m1, m2, NORM_INF) > 1e-5) throw test_excep(s); }
|
||||
|
||||
};
|
||||
|
||||
CV_OperationsTest::CV_OperationsTest()
|
||||
{
|
||||
}
|
||||
|
||||
CV_OperationsTest::~CV_OperationsTest() {}
|
||||
|
||||
#define STR(a) STR2(a)
|
||||
#define STR2(a) #a
|
||||
|
||||
#define CHECK_DIFF(a, b) checkDiff(a, b, "(" #a ") != (" #b ") at l." STR(__LINE__))
|
||||
#define CHECK_DIFF_FLT(a, b) checkDiffF(a, b, "(" #a ") !=(eps) (" #b ") at l." STR(__LINE__))
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER < 1400
|
||||
#define MSVC_OLD 1
|
||||
#else
|
||||
#define MSVC_OLD 0
|
||||
#endif
|
||||
|
||||
bool CV_OperationsTest::TestMat()
|
||||
{
|
||||
try
|
||||
{
|
||||
Mat one_3x1(3, 1, CV_32F, Scalar(1.0));
|
||||
Mat shi_3x1(3, 1, CV_32F, Scalar(1.2));
|
||||
Mat shi_2x1(2, 1, CV_32F, Scalar(-1));
|
||||
Scalar shift = Scalar::all(15);
|
||||
|
||||
float data[] = { sqrt(2.f)/2, -sqrt(2.f)/2, 1.f, sqrt(2.f)/2, sqrt(2.f)/2, 10.f };
|
||||
Mat rot_2x3(2, 3, CV_32F, data);
|
||||
|
||||
Mat res = one_3x1 + shi_3x1 + shi_3x1 + shi_3x1;
|
||||
res = Mat(Mat(2 * rot_2x3) * res - shi_2x1) + shift;
|
||||
|
||||
Mat tmp, res2;
|
||||
add(one_3x1, shi_3x1, tmp);
|
||||
add(tmp, shi_3x1, tmp);
|
||||
add(tmp, shi_3x1, tmp);
|
||||
gemm(rot_2x3, tmp, 2, shi_2x1, -1, res2, 0);
|
||||
add(res2, Mat(2, 1, CV_32F, shift), res2);
|
||||
|
||||
CHECK_DIFF(res, res2);
|
||||
|
||||
Mat mat4x4(4, 4, CV_32F);
|
||||
randu(mat4x4, Scalar(0), Scalar(10));
|
||||
|
||||
Mat roi1 = mat4x4(Rect(Point(1, 1), Size(2, 2)));
|
||||
Mat roi2 = mat4x4(Range(1, 3), Range(1, 3));
|
||||
|
||||
CHECK_DIFF(roi1, roi2);
|
||||
CHECK_DIFF(mat4x4, mat4x4(Rect(Point(0,0), mat4x4.size())));
|
||||
|
||||
Mat intMat10(3, 3, CV_32S, Scalar(10));
|
||||
Mat intMat11(3, 3, CV_32S, Scalar(11));
|
||||
Mat resMat(3, 3, CV_8U, Scalar(255));
|
||||
|
||||
CHECK_DIFF(resMat, intMat10 == intMat10);
|
||||
CHECK_DIFF(resMat, intMat10 < intMat11);
|
||||
CHECK_DIFF(resMat, intMat11 > intMat10);
|
||||
CHECK_DIFF(resMat, intMat10 <= intMat11);
|
||||
CHECK_DIFF(resMat, intMat11 >= intMat10);
|
||||
CHECK_DIFF(resMat, intMat11 != intMat10);
|
||||
|
||||
CHECK_DIFF(resMat, intMat10 == 10.0);
|
||||
CHECK_DIFF(resMat, 10.0 == intMat10);
|
||||
CHECK_DIFF(resMat, intMat10 < 11.0);
|
||||
CHECK_DIFF(resMat, 11.0 > intMat10);
|
||||
CHECK_DIFF(resMat, 10.0 < intMat11);
|
||||
CHECK_DIFF(resMat, 11.0 >= intMat10);
|
||||
CHECK_DIFF(resMat, 10.0 <= intMat11);
|
||||
CHECK_DIFF(resMat, 10.0 != intMat11);
|
||||
CHECK_DIFF(resMat, intMat11 != 10.0);
|
||||
|
||||
Mat eye = Mat::eye(3, 3, CV_16S);
|
||||
Mat maskMat4(3, 3, CV_16S, Scalar(4));
|
||||
Mat maskMat1(3, 3, CV_16S, Scalar(1));
|
||||
Mat maskMat5(3, 3, CV_16S, Scalar(5));
|
||||
Mat maskMat0(3, 3, CV_16S, Scalar(0));
|
||||
|
||||
CHECK_DIFF(maskMat0, maskMat4 & maskMat1);
|
||||
CHECK_DIFF(maskMat0, Scalar(1) & maskMat4);
|
||||
CHECK_DIFF(maskMat0, maskMat4 & Scalar(1));
|
||||
|
||||
Mat m;
|
||||
m = maskMat4.clone(); m &= maskMat1; CHECK_DIFF(maskMat0, m);
|
||||
m = maskMat4.clone(); m &= maskMat1 | maskMat1; CHECK_DIFF(maskMat0, m);
|
||||
m = maskMat4.clone(); m &= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat0, m);
|
||||
|
||||
m = maskMat4.clone(); m &= Scalar(1); CHECK_DIFF(maskMat0, m);
|
||||
m = maskMat4.clone(); m |= maskMat1; CHECK_DIFF(maskMat5, m);
|
||||
m = maskMat5.clone(); m ^= maskMat1; CHECK_DIFF(maskMat4, m);
|
||||
m = maskMat4.clone(); m |= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat5, m);
|
||||
m = maskMat5.clone(); m ^= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat4, m);
|
||||
|
||||
m = maskMat4.clone(); m |= Scalar(1); CHECK_DIFF(maskMat5, m);
|
||||
m = maskMat5.clone(); m ^= Scalar(1); CHECK_DIFF(maskMat4, m);
|
||||
|
||||
|
||||
|
||||
CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & (maskMat1 | maskMat1));
|
||||
CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & maskMat1);
|
||||
CHECK_DIFF(maskMat0, maskMat4 & (maskMat1 | maskMat1));
|
||||
CHECK_DIFF(maskMat0, (maskMat1 | maskMat1) & Scalar(4));
|
||||
CHECK_DIFF(maskMat0, Scalar(4) & (maskMat1 | maskMat1));
|
||||
|
||||
CHECK_DIFF(maskMat0, maskMat5 ^ (maskMat4 | maskMat1));
|
||||
CHECK_DIFF(maskMat0, (maskMat4 | maskMat1) ^ maskMat5);
|
||||
CHECK_DIFF(maskMat0, (maskMat4 + maskMat1) ^ (maskMat4 + maskMat1));
|
||||
CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 | Scalar(1)));
|
||||
CHECK_DIFF(maskMat1, Scalar(5) ^ maskMat4);
|
||||
CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 + maskMat1));
|
||||
CHECK_DIFF(maskMat5, Scalar(5) | (maskMat4 + maskMat1));
|
||||
CHECK_DIFF(maskMat0, (maskMat4 + maskMat1) ^ Scalar(5));
|
||||
|
||||
CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ maskMat1));
|
||||
CHECK_DIFF(maskMat5, (maskMat4 ^ maskMat1) | maskMat5);
|
||||
CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ Scalar(1)));
|
||||
CHECK_DIFF(maskMat5, (maskMat4 | maskMat4) | Scalar(1));
|
||||
CHECK_DIFF(maskMat5, Scalar(1) | (maskMat4 | maskMat4));
|
||||
CHECK_DIFF(maskMat5, Scalar(1) | maskMat4);
|
||||
CHECK_DIFF(maskMat5, (maskMat5 | maskMat5) | (maskMat4 ^ maskMat1));
|
||||
|
||||
CHECK_DIFF(maskMat1, min(maskMat1, maskMat5));
|
||||
CHECK_DIFF(maskMat1, min(Mat(maskMat1 | maskMat1), maskMat5 | maskMat5));
|
||||
CHECK_DIFF(maskMat5, max(maskMat1, maskMat5));
|
||||
CHECK_DIFF(maskMat5, max(Mat(maskMat1 | maskMat1), maskMat5 | maskMat5));
|
||||
|
||||
CHECK_DIFF(maskMat1, min(maskMat1, maskMat5 | maskMat5));
|
||||
CHECK_DIFF(maskMat1, min(maskMat1 | maskMat1, maskMat5));
|
||||
CHECK_DIFF(maskMat5, max(maskMat1 | maskMat1, maskMat5));
|
||||
CHECK_DIFF(maskMat5, max(maskMat1, maskMat5 | maskMat5));
|
||||
|
||||
CHECK_DIFF(~maskMat1, maskMat1 ^ -1);
|
||||
CHECK_DIFF(~(maskMat1 | maskMat1), maskMat1 ^ -1);
|
||||
|
||||
CHECK_DIFF(maskMat1, maskMat4/4.0);
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
CHECK_DIFF(1.0 - (maskMat5 | maskMat5), -maskMat4);
|
||||
CHECK_DIFF((maskMat4 | maskMat4) * 1.0 + 1.0, maskMat5);
|
||||
CHECK_DIFF(1.0 + (maskMat4 | maskMat4) * 1.0, maskMat5);
|
||||
CHECK_DIFF((maskMat5 | maskMat5) * 1.0 - 1.0, maskMat4);
|
||||
CHECK_DIFF(5.0 - (maskMat4 | maskMat4) * 1.0, maskMat1);
|
||||
CHECK_DIFF((maskMat4 | maskMat4) * 1.0 + 0.5 + 0.5, maskMat5);
|
||||
CHECK_DIFF(0.5 + ((maskMat4 | maskMat4) * 1.0 + 0.5), maskMat5);
|
||||
CHECK_DIFF(((maskMat4 | maskMat4) * 1.0 + 2.0) - 1.0, maskMat5);
|
||||
CHECK_DIFF(5.0 - ((maskMat1 | maskMat1) * 1.0 + 3.0), maskMat1);
|
||||
CHECK_DIFF( ( (maskMat1 | maskMat1) * 2.0 + 2.0) * 1.25, maskMat5);
|
||||
CHECK_DIFF( 1.25 * ( (maskMat1 | maskMat1) * 2.0 + 2.0), maskMat5);
|
||||
CHECK_DIFF( -( (maskMat1 | maskMat1) * (-2.0) + 1.0), maskMat1);
|
||||
CHECK_DIFF( maskMat1 * 1.0 + maskMat4 * 0.5 + 2.0, maskMat5);
|
||||
CHECK_DIFF( 1.0 + (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat5);
|
||||
CHECK_DIFF( (maskMat1 * 1.0 + maskMat4 * 0.5 + 2.0) - 1.0, maskMat4);
|
||||
CHECK_DIFF(5.0 - (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat1);
|
||||
CHECK_DIFF((maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0)*1.25, maskMat5);
|
||||
CHECK_DIFF(1.25 * (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat5);
|
||||
CHECK_DIFF(-(maskMat1 * 2.0 + maskMat4 * (-1) + 1.0), maskMat1);
|
||||
CHECK_DIFF((maskMat1 * 1.0 + maskMat4), maskMat5);
|
||||
CHECK_DIFF((maskMat4 + maskMat1 * 1.0), maskMat5);
|
||||
CHECK_DIFF((maskMat1 * 3.0 + 1.0) + maskMat1, maskMat5);
|
||||
CHECK_DIFF(maskMat1 + (maskMat1 * 3.0 + 1.0), maskMat5);
|
||||
CHECK_DIFF(maskMat1*4.0 + (maskMat1 | maskMat1), maskMat5);
|
||||
CHECK_DIFF((maskMat1 | maskMat1) + maskMat1*4.0, maskMat5);
|
||||
CHECK_DIFF((maskMat1*3.0 + 1.0) + (maskMat1 | maskMat1), maskMat5);
|
||||
CHECK_DIFF((maskMat1 | maskMat1) + (maskMat1*3.0 + 1.0), maskMat5);
|
||||
CHECK_DIFF(maskMat1*4.0 + maskMat4*2.0, maskMat1 * 12);
|
||||
CHECK_DIFF((maskMat1*3.0 + 1.0) + maskMat4*2.0, maskMat1 * 12);
|
||||
CHECK_DIFF(maskMat4*2.0 + (maskMat1*3.0 + 1.0), maskMat1 * 12);
|
||||
CHECK_DIFF((maskMat1*3.0 + 1.0) + (maskMat1*2.0 + 2.0), maskMat1 * 8);
|
||||
|
||||
CHECK_DIFF(maskMat5*1.0 - maskMat4, maskMat1);
|
||||
CHECK_DIFF(maskMat5 - maskMat1 * 4.0, maskMat1);
|
||||
CHECK_DIFF((maskMat4 * 1.0 + 4.0)- maskMat4, maskMat4);
|
||||
CHECK_DIFF(maskMat5 - (maskMat1 * 2.0 + 2.0), maskMat1);
|
||||
CHECK_DIFF(maskMat5*1.0 - (maskMat4 | maskMat4), maskMat1);
|
||||
CHECK_DIFF((maskMat5 | maskMat5) - maskMat1 * 4.0, maskMat1);
|
||||
CHECK_DIFF((maskMat4 * 1.0 + 4.0)- (maskMat4 | maskMat4), maskMat4);
|
||||
CHECK_DIFF((maskMat5 | maskMat5) - (maskMat1 * 2.0 + 2.0), maskMat1);
|
||||
CHECK_DIFF(maskMat1*5.0 - maskMat4 * 1.0, maskMat1);
|
||||
CHECK_DIFF((maskMat1*5.0 + 3.0)- maskMat4 * 1.0, maskMat4);
|
||||
CHECK_DIFF(maskMat4 * 2.0 - (maskMat1*4.0 + 3.0), maskMat1);
|
||||
CHECK_DIFF((maskMat1 * 2.0 + 3.0) - (maskMat1*3.0 + 1.0), maskMat1);
|
||||
|
||||
CHECK_DIFF((maskMat5 - maskMat4)* 4.0, maskMat4);
|
||||
CHECK_DIFF(4.0 * (maskMat5 - maskMat4), maskMat4);
|
||||
|
||||
CHECK_DIFF(-((maskMat4 | maskMat4) - (maskMat5 | maskMat5)), maskMat1);
|
||||
|
||||
CHECK_DIFF(4.0 * (maskMat1 | maskMat1), maskMat4);
|
||||
CHECK_DIFF((maskMat4 | maskMat4)/4.0, maskMat1);
|
||||
|
||||
#if !MSVC_OLD
|
||||
CHECK_DIFF(2.0 * (maskMat1 * 2.0) , maskMat4);
|
||||
#endif
|
||||
CHECK_DIFF((maskMat4 / 2.0) / 2.0 , maskMat1);
|
||||
CHECK_DIFF(-(maskMat4 - maskMat5) , maskMat1);
|
||||
CHECK_DIFF(-((maskMat4 - maskMat5) * 1.0), maskMat1);
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
CHECK_DIFF(maskMat4 / maskMat4, maskMat1);
|
||||
|
||||
///// Element-wise multiplication
|
||||
|
||||
CHECK_DIFF(maskMat4.mul(maskMat4, 0.25), maskMat4);
|
||||
CHECK_DIFF(maskMat4.mul(maskMat1 * 4, 0.25), maskMat4);
|
||||
CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
|
||||
CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
|
||||
CHECK_DIFF(maskMat4.mul(maskMat4) * 0.25, maskMat4);
|
||||
CHECK_DIFF(0.25 * maskMat4.mul(maskMat4), maskMat4);
|
||||
|
||||
////// Element-wise division
|
||||
|
||||
CHECK_DIFF(maskMat4 / maskMat4, maskMat1);
|
||||
CHECK_DIFF((maskMat4 & maskMat4) / (maskMat1 * 4), maskMat1);
|
||||
|
||||
CHECK_DIFF((maskMat4 & maskMat4) / maskMat4, maskMat1);
|
||||
CHECK_DIFF(maskMat4 / (maskMat4 & maskMat4), maskMat1);
|
||||
CHECK_DIFF((maskMat1 * 4) / maskMat4, maskMat1);
|
||||
|
||||
CHECK_DIFF(maskMat4 / (maskMat1 * 4), maskMat1);
|
||||
CHECK_DIFF((maskMat4 * 0.5 )/ (maskMat1 * 2), maskMat1);
|
||||
|
||||
CHECK_DIFF(maskMat4 / maskMat4.mul(maskMat1), maskMat1);
|
||||
CHECK_DIFF((maskMat4 & maskMat4) / maskMat4.mul(maskMat1), maskMat1);
|
||||
|
||||
CHECK_DIFF(4.0 / maskMat4, maskMat1);
|
||||
CHECK_DIFF(4.0 / (maskMat4 | maskMat4), maskMat1);
|
||||
CHECK_DIFF(4.0 / (maskMat1 * 4.0), maskMat1);
|
||||
CHECK_DIFF(4.0 / (maskMat4 / maskMat1), maskMat1);
|
||||
|
||||
m = maskMat4.clone(); m/=4.0; CHECK_DIFF(m, maskMat1);
|
||||
m = maskMat4.clone(); m/=maskMat4; CHECK_DIFF(m, maskMat1);
|
||||
m = maskMat4.clone(); m/=(maskMat1 * 4.0); CHECK_DIFF(m, maskMat1);
|
||||
m = maskMat4.clone(); m/=(maskMat4 / maskMat1); CHECK_DIFF(m, maskMat1);
|
||||
|
||||
/////////////////////////////
|
||||
float matrix_data[] = { 3, 1, -4, -5, 1, 0, 0, 1.1f, 1.5f};
|
||||
Mat mt(3, 3, CV_32F, matrix_data);
|
||||
Mat mi = mt.inv();
|
||||
Mat d1 = Mat::eye(3, 3, CV_32F);
|
||||
Mat d2 = d1 * 2;
|
||||
MatExpr mt_tr = mt.t();
|
||||
MatExpr mi_tr = mi.t();
|
||||
Mat mi2 = mi * 2;
|
||||
|
||||
|
||||
CHECK_DIFF_FLT( mi2 * mt, d2 );
|
||||
CHECK_DIFF_FLT( mi * mt, d1 );
|
||||
CHECK_DIFF_FLT( mt_tr * mi_tr, d1 );
|
||||
|
||||
m = mi.clone(); m*=mt; CHECK_DIFF_FLT(m, d1);
|
||||
m = mi.clone(); m*= (2 * mt - mt) ; CHECK_DIFF_FLT(m, d1);
|
||||
|
||||
m = maskMat4.clone(); m+=(maskMat1 * 1.0); CHECK_DIFF(m, maskMat5);
|
||||
m = maskMat5.clone(); m-=(maskMat1 * 4.0); CHECK_DIFF(m, maskMat1);
|
||||
|
||||
m = maskMat1.clone(); m+=(maskMat1 * 3.0 + 1.0); CHECK_DIFF(m, maskMat5);
|
||||
m = maskMat5.clone(); m-=(maskMat1 * 3.0 + 1.0); CHECK_DIFF(m, maskMat1);
|
||||
#if !MSVC_OLD
|
||||
m = mi.clone(); m+=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi + d1 * 4);
|
||||
m = mi.clone(); m-=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi - d1 * 4);
|
||||
m = mi.clone(); m*=(mt * 1.0); CHECK_DIFF_FLT(m, d1);
|
||||
m = mi.clone(); m*=(mt * 1.0 + Mat::eye(m.size(), m.type())); CHECK_DIFF_FLT(m, d1 + mi);
|
||||
m = mi.clone(); m*=mt_tr.t(); CHECK_DIFF_FLT(m, d1);
|
||||
|
||||
CHECK_DIFF_FLT( (mi * 2) * mt, d2);
|
||||
CHECK_DIFF_FLT( mi * (2 * mt), d2);
|
||||
CHECK_DIFF_FLT( mt.t() * mi_tr, d1 );
|
||||
CHECK_DIFF_FLT( mt_tr * mi.t(), d1 );
|
||||
CHECK_DIFF_FLT( (mi * 0.4) * (mt * 5), d2);
|
||||
|
||||
CHECK_DIFF_FLT( mt.t() * (mi_tr * 2), d2 );
|
||||
CHECK_DIFF_FLT( (mt_tr * 2) * mi.t(), d2 );
|
||||
|
||||
CHECK_DIFF_FLT(mt.t() * mi.t(), d1);
|
||||
CHECK_DIFF_FLT( (mi * mt) * 2.0, d2);
|
||||
CHECK_DIFF_FLT( 2.0 * (mi * mt), d2);
|
||||
CHECK_DIFF_FLT( -(mi * mt), -d1);
|
||||
|
||||
CHECK_DIFF_FLT( (mi * mt) / 2.0, d1 / 2);
|
||||
|
||||
Mat mt_mul_2_plus_1;
|
||||
gemm(mt, d1, 2, Mat::ones(3, 3, CV_32F), 1, mt_mul_2_plus_1);
|
||||
|
||||
CHECK_DIFF( (mt * 2.0 + 1.0) * mi, mt_mul_2_plus_1 * mi); // (A*alpha + beta)*B
|
||||
CHECK_DIFF( mi * (mt * 2.0 + 1.0), mi * mt_mul_2_plus_1); // A*(B*alpha + beta)
|
||||
CHECK_DIFF( (mt * 2.0 + 1.0) * (mi * 2), mt_mul_2_plus_1 * mi2); // (A*alpha + beta)*(B*gamma)
|
||||
CHECK_DIFF( (mi *2)* (mt * 2.0 + 1.0), mi2 * mt_mul_2_plus_1); // (A*gamma)*(B*alpha + beta)
|
||||
CHECK_DIFF_FLT( (mt * 2.0 + 1.0) * mi.t(), mt_mul_2_plus_1 * mi_tr); // (A*alpha + beta)*B^t
|
||||
CHECK_DIFF_FLT( mi.t() * (mt * 2.0 + 1.0), mi_tr * mt_mul_2_plus_1); // A^t*(B*alpha + beta)
|
||||
|
||||
CHECK_DIFF_FLT( (mi * mt + d2)*5, d1 * 3 * 5);
|
||||
CHECK_DIFF_FLT( mi * mt + d2, d1 * 3);
|
||||
CHECK_DIFF_FLT( -(mi * mt) + d2, d1);
|
||||
CHECK_DIFF_FLT( (mi * mt) + d1, d2);
|
||||
CHECK_DIFF_FLT( d1 + (mi * mt), d2);
|
||||
CHECK_DIFF_FLT( (mi * mt) - d2, -d1);
|
||||
CHECK_DIFF_FLT( d2 - (mi * mt), d1);
|
||||
|
||||
CHECK_DIFF_FLT( (mi * mt) + d2 * 0.5, d2);
|
||||
CHECK_DIFF_FLT( d2 * 0.5 + (mi * mt), d2);
|
||||
CHECK_DIFF_FLT( (mi * mt) - d1 * 2, -d1);
|
||||
CHECK_DIFF_FLT( d1 * 2 - (mi * mt), d1);
|
||||
|
||||
CHECK_DIFF_FLT( (mi * mt) + mi.t(), mi_tr + d1);
|
||||
CHECK_DIFF_FLT( mi.t() + (mi * mt), mi_tr + d1);
|
||||
CHECK_DIFF_FLT( (mi * mt) - mi.t(), d1 - mi_tr);
|
||||
CHECK_DIFF_FLT( mi.t() - (mi * mt), mi_tr - d1);
|
||||
|
||||
CHECK_DIFF_FLT( 2.0 *(mi * mt + d2), d1 * 6);
|
||||
CHECK_DIFF_FLT( -(mi * mt + d2), d1 * -3);
|
||||
|
||||
CHECK_DIFF_FLT(mt.inv() * mt, d1);
|
||||
|
||||
CHECK_DIFF_FLT(mt.inv() * (2*mt - mt), d1);
|
||||
#endif
|
||||
}
|
||||
catch (const test_excep& e)
|
||||
{
|
||||
ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CV_OperationsTest::SomeMatFunctions()
|
||||
{
|
||||
try
|
||||
{
|
||||
Mat rgba( 10, 10, CV_8UC4, Scalar(1,2,3,4) );
|
||||
Mat bgr( rgba.rows, rgba.cols, CV_8UC3 );
|
||||
Mat alpha( rgba.rows, rgba.cols, CV_8UC1 );
|
||||
Mat out[] = { bgr, alpha };
|
||||
// rgba[0] -> bgr[2], rgba[1] -> bgr[1],
|
||||
// rgba[2] -> bgr[0], rgba[3] -> alpha[0]
|
||||
int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
|
||||
mixChannels( &rgba, 1, out, 2, from_to, 4 );
|
||||
|
||||
Mat bgr_exp( rgba.size(), CV_8UC3, Scalar(3,2,1));
|
||||
Mat alpha_exp( rgba.size(), CV_8UC1, Scalar(4));
|
||||
|
||||
CHECK_DIFF(bgr_exp, bgr);
|
||||
CHECK_DIFF(alpha_exp, alpha);
|
||||
}
|
||||
catch (const test_excep& e)
|
||||
{
|
||||
ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool CV_OperationsTest::TestTemplateMat()
|
||||
{
|
||||
try
|
||||
{
|
||||
Mat_<float> one_3x1(3, 1, 1.0f);
|
||||
Mat_<float> shi_3x1(3, 1, 1.2f);
|
||||
Mat_<float> shi_2x1(2, 1, -2);
|
||||
Scalar shift = Scalar::all(15);
|
||||
|
||||
float data[] = { sqrt(2.f)/2, -sqrt(2.f)/2, 1.f, sqrt(2.f)/2, sqrt(2.f)/2, 10.f };
|
||||
Mat_<float> rot_2x3(2, 3, data);
|
||||
|
||||
Mat_<float> res = Mat(Mat(2 * rot_2x3) * Mat(one_3x1 + shi_3x1 + shi_3x1 + shi_3x1) - shi_2x1) + shift;
|
||||
Mat_<float> resS = rot_2x3 * one_3x1;
|
||||
|
||||
Mat_<float> tmp, res2, resS2;
|
||||
add(one_3x1, shi_3x1, tmp);
|
||||
add(tmp, shi_3x1, tmp);
|
||||
add(tmp, shi_3x1, tmp);
|
||||
gemm(rot_2x3, tmp, 2, shi_2x1, -1, res2, 0);
|
||||
add(res2, Mat(2, 1, CV_32F, shift), res2);
|
||||
|
||||
gemm(rot_2x3, one_3x1, 1, shi_2x1, 0, resS2, 0);
|
||||
CHECK_DIFF(res, res2);
|
||||
CHECK_DIFF(resS, resS2);
|
||||
|
||||
|
||||
Mat_<float> mat4x4(4, 4);
|
||||
randu(mat4x4, Scalar(0), Scalar(10));
|
||||
|
||||
Mat_<float> roi1 = mat4x4(Rect(Point(1, 1), Size(2, 2)));
|
||||
Mat_<float> roi2 = mat4x4(Range(1, 3), Range(1, 3));
|
||||
|
||||
CHECK_DIFF(roi1, roi2);
|
||||
CHECK_DIFF(mat4x4, mat4x4(Rect(Point(0,0), mat4x4.size())));
|
||||
|
||||
Mat_<int> intMat10(3, 3, 10);
|
||||
Mat_<int> intMat11(3, 3, 11);
|
||||
Mat_<uchar> resMat(3, 3, 255);
|
||||
|
||||
CHECK_DIFF(resMat, intMat10 == intMat10);
|
||||
CHECK_DIFF(resMat, intMat10 < intMat11);
|
||||
CHECK_DIFF(resMat, intMat11 > intMat10);
|
||||
CHECK_DIFF(resMat, intMat10 <= intMat11);
|
||||
CHECK_DIFF(resMat, intMat11 >= intMat10);
|
||||
|
||||
CHECK_DIFF(resMat, intMat10 == 10.0);
|
||||
CHECK_DIFF(resMat, intMat10 < 11.0);
|
||||
CHECK_DIFF(resMat, intMat11 > 10.0);
|
||||
CHECK_DIFF(resMat, intMat10 <= 11.0);
|
||||
CHECK_DIFF(resMat, intMat11 >= 10.0);
|
||||
|
||||
Mat_<uchar> maskMat4(3, 3, 4);
|
||||
Mat_<uchar> maskMat1(3, 3, 1);
|
||||
Mat_<uchar> maskMat5(3, 3, 5);
|
||||
Mat_<uchar> maskMat0(3, 3, (uchar)0);
|
||||
|
||||
CHECK_DIFF(maskMat0, maskMat4 & maskMat1);
|
||||
CHECK_DIFF(maskMat0, Scalar(1) & maskMat4);
|
||||
CHECK_DIFF(maskMat0, maskMat4 & Scalar(1));
|
||||
|
||||
Mat_<uchar> m;
|
||||
m = maskMat4.clone(); m&=maskMat1; CHECK_DIFF(maskMat0, m);
|
||||
m = maskMat4.clone(); m&=Scalar(1); CHECK_DIFF(maskMat0, m);
|
||||
|
||||
m = maskMat4.clone(); m|=maskMat1; CHECK_DIFF(maskMat5, m);
|
||||
m = maskMat4.clone(); m^=maskMat1; CHECK_DIFF(maskMat5, m);
|
||||
|
||||
CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & (maskMat1 | maskMat1));
|
||||
CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & maskMat1);
|
||||
CHECK_DIFF(maskMat0, maskMat4 & (maskMat1 | maskMat1));
|
||||
|
||||
CHECK_DIFF(maskMat0, maskMat5 ^ (maskMat4 | maskMat1));
|
||||
CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 | Scalar(1)));
|
||||
|
||||
CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ maskMat1));
|
||||
CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ Scalar(1)));
|
||||
|
||||
CHECK_DIFF(~maskMat1, maskMat1 ^ 0xFF);
|
||||
CHECK_DIFF(~(maskMat1 | maskMat1), maskMat1 ^ 0xFF);
|
||||
|
||||
CHECK_DIFF(maskMat1 + maskMat4, maskMat5);
|
||||
CHECK_DIFF(maskMat1 + Scalar(4), maskMat5);
|
||||
CHECK_DIFF(Scalar(4) + maskMat1, maskMat5);
|
||||
CHECK_DIFF(Scalar(4) + (maskMat1 & maskMat1), maskMat5);
|
||||
|
||||
CHECK_DIFF(maskMat1 + 4.0, maskMat5);
|
||||
CHECK_DIFF((maskMat1 & 0xFF) + 4.0, maskMat5);
|
||||
CHECK_DIFF(4.0 + maskMat1, maskMat5);
|
||||
|
||||
m = maskMat4.clone(); m+=Scalar(1); CHECK_DIFF(m, maskMat5);
|
||||
m = maskMat4.clone(); m+=maskMat1; CHECK_DIFF(m, maskMat5);
|
||||
m = maskMat4.clone(); m+=(maskMat1 | maskMat1); CHECK_DIFF(m, maskMat5);
|
||||
|
||||
CHECK_DIFF(maskMat5 - maskMat1, maskMat4);
|
||||
CHECK_DIFF(maskMat5 - Scalar(1), maskMat4);
|
||||
CHECK_DIFF((maskMat5 | maskMat5) - Scalar(1), maskMat4);
|
||||
CHECK_DIFF(maskMat5 - 1, maskMat4);
|
||||
CHECK_DIFF((maskMat5 | maskMat5) - 1, maskMat4);
|
||||
CHECK_DIFF((maskMat5 | maskMat5) - (maskMat1 | maskMat1), maskMat4);
|
||||
|
||||
CHECK_DIFF(maskMat1, min(maskMat1, maskMat5));
|
||||
CHECK_DIFF(maskMat5, max(maskMat1, maskMat5));
|
||||
|
||||
m = maskMat5.clone(); m-=Scalar(1); CHECK_DIFF(m, maskMat4);
|
||||
m = maskMat5.clone(); m-=maskMat1; CHECK_DIFF(m, maskMat4);
|
||||
m = maskMat5.clone(); m-=(maskMat1 | maskMat1); CHECK_DIFF(m, maskMat4);
|
||||
|
||||
m = maskMat4.clone(); m |= Scalar(1); CHECK_DIFF(maskMat5, m);
|
||||
m = maskMat5.clone(); m ^= Scalar(1); CHECK_DIFF(maskMat4, m);
|
||||
|
||||
CHECK_DIFF(maskMat1, maskMat4/4.0);
|
||||
|
||||
Mat_<float> negf(3, 3, -3.0);
|
||||
Mat_<float> posf = -negf;
|
||||
Mat_<float> posf2 = posf * 2;
|
||||
Mat_<int> negi(3, 3, -3);
|
||||
|
||||
CHECK_DIFF(abs(negf), -negf);
|
||||
CHECK_DIFF(abs(posf - posf2), -negf);
|
||||
CHECK_DIFF(abs(negi), -(negi & negi));
|
||||
|
||||
CHECK_DIFF(5.0 - maskMat4, maskMat1);
|
||||
|
||||
|
||||
CHECK_DIFF(maskMat4.mul(maskMat4, 0.25), maskMat4);
|
||||
CHECK_DIFF(maskMat4.mul(maskMat1 * 4, 0.25), maskMat4);
|
||||
CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
|
||||
|
||||
|
||||
////// Element-wise division
|
||||
|
||||
CHECK_DIFF(maskMat4 / maskMat4, maskMat1);
|
||||
CHECK_DIFF(4.0 / maskMat4, maskMat1);
|
||||
m = maskMat4.clone(); m/=4.0; CHECK_DIFF(m, maskMat1);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
typedef Mat_<int> TestMat_t;
|
||||
|
||||
const TestMat_t cnegi = negi.clone();
|
||||
|
||||
TestMat_t::iterator beg = negi.begin();
|
||||
TestMat_t::iterator end = negi.end();
|
||||
|
||||
TestMat_t::const_iterator cbeg = cnegi.begin();
|
||||
TestMat_t::const_iterator cend = cnegi.end();
|
||||
|
||||
int sum = 0;
|
||||
for(; beg!=end; ++beg)
|
||||
sum+=*beg;
|
||||
|
||||
for(; cbeg!=cend; ++cbeg)
|
||||
sum-=*cbeg;
|
||||
|
||||
if (sum != 0) throw test_excep();
|
||||
|
||||
CHECK_DIFF(negi.col(1), negi.col(2));
|
||||
CHECK_DIFF(negi.row(1), negi.row(2));
|
||||
CHECK_DIFF(negi.col(1), negi.diag());
|
||||
|
||||
if (Mat_<Point2f>(1, 1).elemSize1() != sizeof(float)) throw test_excep();
|
||||
if (Mat_<Point2f>(1, 1).elemSize() != 2 * sizeof(float)) throw test_excep();
|
||||
if (Mat_<Point2f>(1, 1).depth() != CV_32F) throw test_excep();
|
||||
if (Mat_<float>(1, 1).depth() != CV_32F) throw test_excep();
|
||||
if (Mat_<int>(1, 1).depth() != CV_32S) throw test_excep();
|
||||
if (Mat_<double>(1, 1).depth() != CV_64F) throw test_excep();
|
||||
if (Mat_<Point3d>(1, 1).depth() != CV_64F) throw test_excep();
|
||||
if (Mat_<signed char>(1, 1).depth() != CV_8S) throw test_excep();
|
||||
if (Mat_<unsigned short>(1, 1).depth() != CV_16U) throw test_excep();
|
||||
if (Mat_<unsigned short>(1, 1).channels() != 1) throw test_excep();
|
||||
if (Mat_<Point2f>(1, 1).channels() != 2) throw test_excep();
|
||||
if (Mat_<Point3f>(1, 1).channels() != 3) throw test_excep();
|
||||
if (Mat_<Point3d>(1, 1).channels() != 3) throw test_excep();
|
||||
|
||||
Mat_<uchar> eye = Mat_<uchar>::zeros(2, 2); CHECK_DIFF(Mat_<uchar>::zeros(Size(2, 2)), eye);
|
||||
eye.at<uchar>(Point(0,0)) = 1; eye.at<uchar>(1, 1) = 1;
|
||||
|
||||
CHECK_DIFF(Mat_<uchar>::eye(2, 2), eye);
|
||||
CHECK_DIFF(eye, Mat_<uchar>::eye(Size(2,2)));
|
||||
|
||||
Mat_<uchar> ones(2, 2, (uchar)1);
|
||||
CHECK_DIFF(ones, Mat_<uchar>::ones(Size(2,2)));
|
||||
CHECK_DIFF(Mat_<uchar>::ones(2, 2), ones);
|
||||
|
||||
Mat_<Point2f> pntMat(2, 2, Point2f(1, 0));
|
||||
if(pntMat.stepT() != 2) throw test_excep();
|
||||
|
||||
uchar uchar_data[] = {1, 0, 0, 1};
|
||||
|
||||
Mat_<uchar> matFromData(1, 4, uchar_data);
|
||||
const Mat_<uchar> mat2 = matFromData.clone();
|
||||
CHECK_DIFF(matFromData, eye.reshape(1));
|
||||
if (matFromData(Point(0,0)) != uchar_data[0])throw test_excep();
|
||||
if (mat2(Point(0,0)) != uchar_data[0]) throw test_excep();
|
||||
|
||||
if (matFromData(0,0) != uchar_data[0])throw test_excep();
|
||||
if (mat2(0,0) != uchar_data[0]) throw test_excep();
|
||||
|
||||
Mat_<uchar> rect(eye, Rect(0, 0, 1, 1));
|
||||
if (rect.cols != 1 || rect.rows != 1 || rect(0,0) != uchar_data[0]) throw test_excep();
|
||||
|
||||
//cv::Mat_<_Tp>::adjustROI(int,int,int,int)
|
||||
//cv::Mat_<_Tp>::cross(const Mat_&) const
|
||||
//cv::Mat_<_Tp>::Mat_(const vector<_Tp>&,bool)
|
||||
//cv::Mat_<_Tp>::Mat_(int,int,_Tp*,size_t)
|
||||
//cv::Mat_<_Tp>::Mat_(int,int,const _Tp&)
|
||||
//cv::Mat_<_Tp>::Mat_(Size,const _Tp&)
|
||||
//cv::Mat_<_Tp>::mul(const Mat_<_Tp>&,double) const
|
||||
//cv::Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat_<_Tp>,double,Mat_<_Tp>,MatOp_DivRS_<Mat> >,Mat_<_Tp> >&,double) const
|
||||
//cv::Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat_<_Tp>,double,Mat_<_Tp>,MatOp_Scale_<Mat> >,Mat_<_Tp> >&,double) const
|
||||
//cv::Mat_<_Tp>::operator Mat_<T2>() const
|
||||
//cv::Mat_<_Tp>::operator MatExpr_<Mat_<_Tp>,Mat_<_Tp> >() const
|
||||
//cv::Mat_<_Tp>::operator()(const Range&,const Range&) const
|
||||
//cv::Mat_<_Tp>::operator()(const Rect&) const
|
||||
|
||||
//cv::Mat_<_Tp>::operator=(const MatExpr_Base&)
|
||||
//cv::Mat_<_Tp>::operator[](int) const
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
float matrix_data[] = { 3, 1, -4, -5, 1, 0, 0, 1.1f, 1.5f};
|
||||
Mat_<float> mt(3, 3, matrix_data);
|
||||
Mat_<float> mi = mt.inv();
|
||||
Mat_<float> d1 = Mat_<float>::eye(3, 3);
|
||||
Mat_<float> d2 = d1 * 2;
|
||||
Mat_<float> mt_tr = mt.t();
|
||||
Mat_<float> mi_tr = mi.t();
|
||||
Mat_<float> mi2 = mi * 2;
|
||||
|
||||
CHECK_DIFF_FLT( mi2 * mt, d2 );
|
||||
CHECK_DIFF_FLT( mi * mt, d1 );
|
||||
CHECK_DIFF_FLT( mt_tr * mi_tr, d1 );
|
||||
|
||||
Mat_<float> mf;
|
||||
mf = mi.clone(); mf*=mt; CHECK_DIFF_FLT(mf, d1);
|
||||
|
||||
////// typedefs //////
|
||||
|
||||
if (Mat1b(1, 1).elemSize() != sizeof(uchar)) throw test_excep();
|
||||
if (Mat2b(1, 1).elemSize() != 2 * sizeof(uchar)) throw test_excep();
|
||||
if (Mat3b(1, 1).elemSize() != 3 * sizeof(uchar)) throw test_excep();
|
||||
if (Mat1f(1, 1).elemSize() != sizeof(float)) throw test_excep();
|
||||
if (Mat2f(1, 1).elemSize() != 2 * sizeof(float)) throw test_excep();
|
||||
if (Mat3f(1, 1).elemSize() != 3 * sizeof(float)) throw test_excep();
|
||||
if (Mat1f(1, 1).depth() != CV_32F) throw test_excep();
|
||||
if (Mat3f(1, 1).depth() != CV_32F) throw test_excep();
|
||||
if (Mat3f(1, 1).type() != CV_32FC3) throw test_excep();
|
||||
if (Mat1i(1, 1).depth() != CV_32S) throw test_excep();
|
||||
if (Mat1d(1, 1).depth() != CV_64F) throw test_excep();
|
||||
if (Mat1b(1, 1).depth() != CV_8U) throw test_excep();
|
||||
if (Mat3b(1, 1).type() != CV_8UC3) throw test_excep();
|
||||
if (Mat1w(1, 1).depth() != CV_16U) throw test_excep();
|
||||
if (Mat1s(1, 1).depth() != CV_16S) throw test_excep();
|
||||
if (Mat1f(1, 1).channels() != 1) throw test_excep();
|
||||
if (Mat1b(1, 1).channels() != 1) throw test_excep();
|
||||
if (Mat1i(1, 1).channels() != 1) throw test_excep();
|
||||
if (Mat1w(1, 1).channels() != 1) throw test_excep();
|
||||
if (Mat1s(1, 1).channels() != 1) throw test_excep();
|
||||
if (Mat2f(1, 1).channels() != 2) throw test_excep();
|
||||
if (Mat2b(1, 1).channels() != 2) throw test_excep();
|
||||
if (Mat2i(1, 1).channels() != 2) throw test_excep();
|
||||
if (Mat2w(1, 1).channels() != 2) throw test_excep();
|
||||
if (Mat2s(1, 1).channels() != 2) throw test_excep();
|
||||
if (Mat3f(1, 1).channels() != 3) throw test_excep();
|
||||
if (Mat3b(1, 1).channels() != 3) throw test_excep();
|
||||
if (Mat3i(1, 1).channels() != 3) throw test_excep();
|
||||
if (Mat3w(1, 1).channels() != 3) throw test_excep();
|
||||
if (Mat3s(1, 1).channels() != 3) throw test_excep();
|
||||
|
||||
}
|
||||
catch (const test_excep& e)
|
||||
{
|
||||
ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CV_OperationsTest::TestMatND()
|
||||
{
|
||||
int sizes[] = { 3, 3, 3};
|
||||
cv::MatND nd(3, sizes, CV_32F);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CV_OperationsTest::TestSparseMat()
|
||||
{
|
||||
try
|
||||
{
|
||||
int sizes[] = { 10, 10, 10};
|
||||
int dims = sizeof(sizes)/sizeof(sizes[0]);
|
||||
SparseMat mat(dims, sizes, CV_32FC2);
|
||||
|
||||
if (mat.dims() != dims) throw test_excep();
|
||||
if (mat.channels() != 2) throw test_excep();
|
||||
if (mat.depth() != CV_32F) throw test_excep();
|
||||
|
||||
SparseMat mat2 = mat.clone();
|
||||
}
|
||||
catch (const test_excep&)
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CV_OperationsTest::operations1()
|
||||
{
|
||||
try
|
||||
{
|
||||
Point3d p1(1, 1, 1), p2(2, 2, 2), p4(4, 4, 4);
|
||||
p1*=2;
|
||||
if (!(p1 == p2)) throw test_excep();
|
||||
if (!(p2 * 2 == p4)) throw test_excep();
|
||||
if (!(p2 * 2.f == p4)) throw test_excep();
|
||||
if (!(p2 * 2.f == p4)) throw test_excep();
|
||||
|
||||
Point2d pi1(1, 1), pi2(2, 2), pi4(4, 4);
|
||||
pi1*=2;
|
||||
if (!(pi1 == pi2)) throw test_excep();
|
||||
if (!(pi2 * 2 == pi4)) throw test_excep();
|
||||
if (!(pi2 * 2.f == pi4)) throw test_excep();
|
||||
if (!(pi2 * 2.f == pi4)) throw test_excep();
|
||||
|
||||
Vec2d v12(1, 1), v22(2, 2);
|
||||
v12*=2.0;
|
||||
if (!(v12 == v22)) throw test_excep();
|
||||
|
||||
Vec3d v13(1, 1, 1), v23(2, 2, 2);
|
||||
v13*=2.0;
|
||||
if (!(v13 == v23)) throw test_excep();
|
||||
|
||||
Vec4d v14(1, 1, 1, 1), v24(2, 2, 2, 2);
|
||||
v14*=2.0;
|
||||
if (!(v14 == v24)) throw test_excep();
|
||||
|
||||
Size sz(10, 20);
|
||||
if (sz.area() != 200) throw test_excep();
|
||||
if (sz.width != 10 || sz.height != 20) throw test_excep();
|
||||
if (((CvSize)sz).width != 10 || ((CvSize)sz).height != 20) throw test_excep();
|
||||
|
||||
Vec<double, 5> v5d(1, 1, 1, 1, 1);
|
||||
Vec<double, 6> v6d(1, 1, 1, 1, 1, 1);
|
||||
Vec<double, 7> v7d(1, 1, 1, 1, 1, 1, 1);
|
||||
Vec<double, 8> v8d(1, 1, 1, 1, 1, 1, 1, 1);
|
||||
Vec<double, 9> v9d(1, 1, 1, 1, 1, 1, 1, 1, 1);
|
||||
Vec<double,10> v10d(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
|
||||
|
||||
Vec<double,10> v10dzero;
|
||||
for (int ii = 0; ii < 10; ++ii) {
|
||||
if (!v10dzero[ii] == 0.0)
|
||||
throw test_excep();
|
||||
}
|
||||
}
|
||||
catch(const test_excep&)
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CV_OperationsTest::run( int /* start_from */)
|
||||
{
|
||||
if (!TestMat())
|
||||
return;
|
||||
|
||||
if (!SomeMatFunctions())
|
||||
return;
|
||||
|
||||
if (!TestTemplateMat())
|
||||
return;
|
||||
|
||||
/* if (!TestMatND())
|
||||
return;*/
|
||||
|
||||
if (!TestSparseMat())
|
||||
return;
|
||||
|
||||
if (!operations1())
|
||||
return;
|
||||
|
||||
ts->set_failed_test_info(cvtest::TS::OK);
|
||||
}
|
||||
|
||||
TEST(Core_Array, expressions) { CV_OperationsTest test; test.safe_run(); }
|
@@ -1,2 +1,8 @@
|
||||
#include "opencv2/gtest/gtestcv.hpp"
|
||||
#include "opencv2/core/core.hpp"
|
||||
#ifndef __OPENCV_TEST_PRECOMP_HPP__
|
||||
#define __OPENCV_TEST_PRECOMP_HPP__
|
||||
|
||||
#include "opencv2/ts/ts.hpp"
|
||||
#include "opencv2/core/core_c.h"
|
||||
#include <iostream>
|
||||
|
||||
#endif
|
||||
|
303
modules/core/test/test_rand.cpp
Normal file
303
modules/core/test/test_rand.cpp
Normal file
@@ -0,0 +1,303 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
class Core_RandTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_RandTest();
|
||||
protected:
|
||||
void run(int);
|
||||
bool check_pdf(const Mat& hist, double scale, int dist_type,
|
||||
double& refval, double& realval);
|
||||
};
|
||||
|
||||
|
||||
Core_RandTest::Core_RandTest()
|
||||
{
|
||||
}
|
||||
|
||||
static double chi2_p95(int n)
|
||||
{
|
||||
static float chi2_tab95[] = {
|
||||
3.841f, 5.991f, 7.815f, 9.488f, 11.07f, 12.59f, 14.07f, 15.51f,
|
||||
16.92f, 18.31f, 19.68f, 21.03f, 21.03f, 22.36f, 23.69f, 25.00f,
|
||||
26.30f, 27.59f, 28.87f, 30.14f, 31.41f, 32.67f, 33.92f, 35.17f,
|
||||
36.42f, 37.65f, 38.89f, 40.11f, 41.34f, 42.56f, 43.77f };
|
||||
static const double xp = 1.64;
|
||||
CV_Assert(n >= 1);
|
||||
|
||||
if( n <= 30 )
|
||||
return chi2_tab95[n-1];
|
||||
return n + sqrt((double)2*n)*xp + 0.6666666666666*(xp*xp - 1);
|
||||
}
|
||||
|
||||
bool Core_RandTest::check_pdf(const Mat& hist, double scale,
|
||||
int dist_type, double& refval, double& realval)
|
||||
{
|
||||
Mat hist0(hist.size(), CV_32F);
|
||||
const int* H = (const int*)hist.data;
|
||||
float* H0 = ((float*)hist0.data);
|
||||
int i, hsz = hist.cols;
|
||||
|
||||
double sum = 0;
|
||||
for( i = 0; i < hsz; i++ )
|
||||
sum += H[i];
|
||||
CV_Assert( fabs(1./sum - scale) < FLT_EPSILON );
|
||||
|
||||
if( dist_type == CV_RAND_UNI )
|
||||
{
|
||||
float scale0 = (float)(1./hsz);
|
||||
for( i = 0; i < hsz; i++ )
|
||||
H0[i] = scale0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double sum = 0, r = (hsz-1.)/2;
|
||||
double alpha = 2*sqrt(2.)/r, beta = -alpha*r;
|
||||
for( i = 0; i < hsz; i++ )
|
||||
{
|
||||
double x = i*alpha + beta;
|
||||
H0[i] = (float)exp(-x*x);
|
||||
sum += H0[i];
|
||||
}
|
||||
sum = 1./sum;
|
||||
for( i = 0; i < hsz; i++ )
|
||||
H0[i] = (float)(H0[i]*sum);
|
||||
}
|
||||
|
||||
double chi2 = 0;
|
||||
for( i = 0; i < hsz; i++ )
|
||||
{
|
||||
double a = H0[i];
|
||||
double b = H[i]*scale;
|
||||
if( a > DBL_EPSILON )
|
||||
chi2 += (a - b)*(a - b)/(a + b);
|
||||
}
|
||||
realval = chi2;
|
||||
|
||||
double chi2_pval = chi2_p95(hsz - 1 - (dist_type == CV_RAND_NORMAL ? 2 : 0));
|
||||
refval = chi2_pval*0.01;
|
||||
return realval <= refval;
|
||||
}
|
||||
|
||||
void Core_RandTest::run( int )
|
||||
{
|
||||
static int _ranges[][2] =
|
||||
{{ 0, 256 }, { -128, 128 }, { 0, 65536 }, { -32768, 32768 },
|
||||
{ -1000000, 1000000 }, { -1000, 1000 }, { -1000, 1000 }};
|
||||
|
||||
const int MAX_SDIM = 10;
|
||||
const int N = 2000000;
|
||||
const int maxSlice = 1000;
|
||||
const int MAX_HIST_SIZE = 1000;
|
||||
int progress = 0;
|
||||
|
||||
RNG& rng = ts->get_rng();
|
||||
RNG tested_rng = theRNG();
|
||||
test_case_count = 200;
|
||||
|
||||
for( int idx = 0; idx < test_case_count; idx++ )
|
||||
{
|
||||
progress = update_progress( progress, idx, test_case_count, 0 );
|
||||
ts->update_context( this, idx, false );
|
||||
|
||||
int depth = cvtest::randInt(rng) % (CV_64F+1);
|
||||
int c, cn = (cvtest::randInt(rng) % 4) + 1;
|
||||
int type = CV_MAKETYPE(depth, cn);
|
||||
int dist_type = cvtest::randInt(rng) % (CV_RAND_NORMAL+1);
|
||||
int i, k, SZ = N/cn;
|
||||
Scalar A, B;
|
||||
|
||||
bool do_sphere_test = dist_type == CV_RAND_UNI;
|
||||
Mat arr[2], hist[4];
|
||||
int W[] = {0,0,0,0};
|
||||
|
||||
arr[0].create(1, SZ, type);
|
||||
arr[1].create(1, SZ, type);
|
||||
bool fast_algo = dist_type == CV_RAND_UNI && depth < CV_32F;
|
||||
|
||||
for( c = 0; c < cn; c++ )
|
||||
{
|
||||
int a, b, hsz;
|
||||
if( dist_type == CV_RAND_UNI )
|
||||
{
|
||||
a = (int)(cvtest::randInt(rng) % (_ranges[depth][1] -
|
||||
_ranges[depth][0])) + _ranges[depth][0];
|
||||
do
|
||||
{
|
||||
b = (int)(cvtest::randInt(rng) % (_ranges[depth][1] -
|
||||
_ranges[depth][0])) + _ranges[depth][0];
|
||||
}
|
||||
while( abs(a-b) <= 1 );
|
||||
if( a > b )
|
||||
std::swap(a, b);
|
||||
|
||||
unsigned r = (unsigned)(b - a);
|
||||
fast_algo = fast_algo && r <= 256 && (r & (r-1)) == 0;
|
||||
hsz = min((unsigned)(b - a), (unsigned)MAX_HIST_SIZE);
|
||||
do_sphere_test = do_sphere_test && b - a >= 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
int vrange = _ranges[depth][1] - _ranges[depth][0];
|
||||
int meanrange = vrange/16;
|
||||
int mindiv = MAX(vrange/20, 5);
|
||||
int maxdiv = MIN(vrange/8, 10000);
|
||||
|
||||
a = cvtest::randInt(rng) % meanrange - meanrange/2 +
|
||||
(_ranges[depth][0] + _ranges[depth][1])/2;
|
||||
b = cvtest::randInt(rng) % (maxdiv - mindiv) + mindiv;
|
||||
hsz = min((unsigned)b*9, (unsigned)MAX_HIST_SIZE);
|
||||
}
|
||||
A[c] = a;
|
||||
B[c] = b;
|
||||
hist[c].create(1, hsz, CV_32S);
|
||||
}
|
||||
|
||||
cv::RNG saved_rng = tested_rng;
|
||||
int maxk = fast_algo ? 0 : 1;
|
||||
for( k = 0; k <= maxk; k++ )
|
||||
{
|
||||
tested_rng = saved_rng;
|
||||
int sz = 0, dsz = 0, slice;
|
||||
for( slice = 0; slice < maxSlice; slice++, sz += dsz )
|
||||
{
|
||||
dsz = slice+1 < maxSlice ? cvtest::randInt(rng) % (SZ - sz + 1) : SZ - sz;
|
||||
Mat aslice = arr[k].colRange(sz, sz + dsz);
|
||||
tested_rng.fill(aslice, dist_type, A, B);
|
||||
}
|
||||
}
|
||||
|
||||
if( maxk >= 1 && norm(arr[0], arr[1], NORM_INF) != 0 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "RNG output depends on the array lengths (some generated numbers get lost?)" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
for( c = 0; c < cn; c++ )
|
||||
{
|
||||
const uchar* data = arr[0].data;
|
||||
int* H = hist[c].ptr<int>();
|
||||
int HSZ = hist[c].cols;
|
||||
double minVal = dist_type == CV_RAND_UNI ? A[c] : A[c] - B[c]*4;
|
||||
double maxVal = dist_type == CV_RAND_UNI ? B[c] : A[c] + B[c]*4;
|
||||
double scale = HSZ/(maxVal - minVal);
|
||||
double delta = -minVal*scale;
|
||||
|
||||
hist[c] = Scalar::all(0);
|
||||
|
||||
for( i = c; i < SZ*cn; i += cn )
|
||||
{
|
||||
double val = depth == CV_8U ? ((const uchar*)data)[i] :
|
||||
depth == CV_8S ? ((const schar*)data)[i] :
|
||||
depth == CV_16U ? ((const ushort*)data)[i] :
|
||||
depth == CV_16S ? ((const short*)data)[i] :
|
||||
depth == CV_32S ? ((const int*)data)[i] :
|
||||
depth == CV_32F ? ((const float*)data)[i] :
|
||||
((const double*)data)[i];
|
||||
int ival = cvFloor(val*scale + delta);
|
||||
if( (unsigned)ival < (unsigned)HSZ )
|
||||
{
|
||||
H[ival]++;
|
||||
W[c]++;
|
||||
}
|
||||
else if( dist_type == CV_RAND_UNI )
|
||||
{
|
||||
if( (minVal <= val && val < maxVal) || (depth >= CV_32F && val == maxVal) )
|
||||
{
|
||||
H[ival < 0 ? 0 : HSZ-1]++;
|
||||
W[c]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar('^');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( dist_type == CV_RAND_UNI && W[c] != SZ )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Uniform RNG gave values out of the range [%g,%g) on channel %d/%d\n",
|
||||
A[c], B[c], c, cn);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
if( dist_type == CV_RAND_NORMAL && W[c] < SZ*.90)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Normal RNG gave too many values out of the range (%g+4*%g,%g+4*%g) on channel %d/%d\n",
|
||||
A[c], B[c], A[c], B[c], c, cn);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
double refval = 0, realval = 0;
|
||||
|
||||
if( !check_pdf(hist[c], 1./W[c], dist_type, refval, realval) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "RNG failed Chi-square test "
|
||||
"(got %g vs probable maximum %g) on channel %d/%d\n",
|
||||
realval, refval, c, cn);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Monte-Carlo test. Compute volume of SDIM-dimensional sphere
|
||||
// inscribed in [-1,1]^SDIM cube.
|
||||
if( do_sphere_test )
|
||||
{
|
||||
int SDIM = cvtest::randInt(rng) % (MAX_SDIM-1) + 2;
|
||||
int N0 = (SZ*cn/SDIM), N = 0;
|
||||
double r2 = 0;
|
||||
const uchar* data = arr[0].data;
|
||||
double scale[4], delta[4];
|
||||
for( c = 0; c < cn; c++ )
|
||||
{
|
||||
scale[c] = 2./(B[c] - A[c]);
|
||||
delta[c] = -A[c]*scale[c] - 1;
|
||||
}
|
||||
|
||||
for( i = k = c = 0; i <= SZ*cn - SDIM; i++, k++, c++ )
|
||||
{
|
||||
double val = depth == CV_8U ? ((const uchar*)data)[i] :
|
||||
depth == CV_8S ? ((const schar*)data)[i] :
|
||||
depth == CV_16U ? ((const ushort*)data)[i] :
|
||||
depth == CV_16S ? ((const short*)data)[i] :
|
||||
depth == CV_32S ? ((const int*)data)[i] :
|
||||
depth == CV_32F ? ((const float*)data)[i] : ((const double*)data)[i];
|
||||
c &= c < cn ? -1 : 0;
|
||||
val = val*scale[c] + delta[c];
|
||||
r2 += val*val;
|
||||
if( k == SDIM-1 )
|
||||
{
|
||||
N += r2 <= 1;
|
||||
r2 = 0;
|
||||
k = -1;
|
||||
}
|
||||
}
|
||||
|
||||
double V = ((double)N/N0)*(1 << SDIM);
|
||||
|
||||
// the theoretically computed volume
|
||||
int sdim = SDIM % 2;
|
||||
double V0 = sdim + 1;
|
||||
for( sdim += 2; sdim <= SDIM; sdim += 2 )
|
||||
V0 *= 2*CV_PI/sdim;
|
||||
|
||||
if( fabs(V - V0) > 0.3*fabs(V0) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "RNG failed %d-dim sphere volume test (got %g instead of %g)\n",
|
||||
SDIM, V, V0);
|
||||
ts->printf( cvtest::TS::LOG, "depth = %d, N0 = %d\n", depth, N0);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_Rand, quality) { Core_RandTest test; test.safe_run(); }
|
||||
|
||||
|
Reference in New Issue
Block a user