|
|
|
@ -42,6 +42,7 @@ |
|
|
|
|
|
|
|
|
|
#include "test_precomp.hpp" |
|
|
|
|
#include "opencv2/imgproc/imgproc_c.h" |
|
|
|
|
#include "opencv2/calib3d/calib3d_c.h" |
|
|
|
|
|
|
|
|
|
namespace opencv_test { namespace { |
|
|
|
|
|
|
|
|
@ -938,4 +939,584 @@ TEST(Calib3d_DefaultNewCameraMatrix, accuracy) { CV_DefaultNewCameraMatrixTest t |
|
|
|
|
TEST(Calib3d_UndistortPoints, accuracy) { CV_UndistortPointsTest test; test.safe_run(); } |
|
|
|
|
TEST(Calib3d_InitUndistortRectifyMap, accuracy) { CV_InitUndistortRectifyMapTest test; test.safe_run(); } |
|
|
|
|
|
|
|
|
|
////////////////////////////// undistort /////////////////////////////////
|
|
|
|
|
|
|
|
|
|
static void test_remap( const Mat& src, Mat& dst, const Mat& mapx, const Mat& mapy, |
|
|
|
|
Mat* mask=0, int interpolation=CV_INTER_LINEAR ) |
|
|
|
|
{ |
|
|
|
|
int x, y, k; |
|
|
|
|
int drows = dst.rows, dcols = dst.cols; |
|
|
|
|
int srows = src.rows, scols = src.cols; |
|
|
|
|
const uchar* sptr0 = src.ptr(); |
|
|
|
|
int depth = src.depth(), cn = src.channels(); |
|
|
|
|
int elem_size = (int)src.elemSize(); |
|
|
|
|
int step = (int)(src.step / CV_ELEM_SIZE(depth)); |
|
|
|
|
int delta; |
|
|
|
|
|
|
|
|
|
if( interpolation != CV_INTER_CUBIC ) |
|
|
|
|
{ |
|
|
|
|
delta = 0; |
|
|
|
|
scols -= 1; srows -= 1; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
delta = 1; |
|
|
|
|
scols = MAX(scols - 3, 0); |
|
|
|
|
srows = MAX(srows - 3, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int scols1 = MAX(scols - 2, 0); |
|
|
|
|
int srows1 = MAX(srows - 2, 0); |
|
|
|
|
|
|
|
|
|
if( mask ) |
|
|
|
|
*mask = Scalar::all(0); |
|
|
|
|
|
|
|
|
|
for( y = 0; y < drows; y++ ) |
|
|
|
|
{ |
|
|
|
|
uchar* dptr = dst.ptr(y); |
|
|
|
|
const float* mx = mapx.ptr<float>(y); |
|
|
|
|
const float* my = mapy.ptr<float>(y); |
|
|
|
|
uchar* m = mask ? mask->ptr(y) : 0; |
|
|
|
|
|
|
|
|
|
for( x = 0; x < dcols; x++, dptr += elem_size ) |
|
|
|
|
{ |
|
|
|
|
float xs = mx[x]; |
|
|
|
|
float ys = my[x]; |
|
|
|
|
int ixs = cvFloor(xs); |
|
|
|
|
int iys = cvFloor(ys); |
|
|
|
|
|
|
|
|
|
if( (unsigned)(ixs - delta - 1) >= (unsigned)scols1 || |
|
|
|
|
(unsigned)(iys - delta - 1) >= (unsigned)srows1 ) |
|
|
|
|
{ |
|
|
|
|
if( m ) |
|
|
|
|
m[x] = 1; |
|
|
|
|
if( (unsigned)(ixs - delta) >= (unsigned)scols || |
|
|
|
|
(unsigned)(iys - delta) >= (unsigned)srows ) |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xs -= ixs; |
|
|
|
|
ys -= iys; |
|
|
|
|
|
|
|
|
|
switch( depth ) |
|
|
|
|
{ |
|
|
|
|
case CV_8U: |
|
|
|
|
{ |
|
|
|
|
const uchar* sptr = sptr0 + iys*step + ixs*cn; |
|
|
|
|
for( k = 0; k < cn; k++ ) |
|
|
|
|
{ |
|
|
|
|
float v00 = sptr[k]; |
|
|
|
|
float v01 = sptr[cn + k]; |
|
|
|
|
float v10 = sptr[step + k]; |
|
|
|
|
float v11 = sptr[step + cn + k]; |
|
|
|
|
|
|
|
|
|
v00 = v00 + xs*(v01 - v00); |
|
|
|
|
v10 = v10 + xs*(v11 - v10); |
|
|
|
|
v00 = v00 + ys*(v10 - v00); |
|
|
|
|
dptr[k] = (uchar)cvRound(v00); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case CV_16U: |
|
|
|
|
{ |
|
|
|
|
const ushort* sptr = (const ushort*)sptr0 + iys*step + ixs*cn; |
|
|
|
|
for( k = 0; k < cn; k++ ) |
|
|
|
|
{ |
|
|
|
|
float v00 = sptr[k]; |
|
|
|
|
float v01 = sptr[cn + k]; |
|
|
|
|
float v10 = sptr[step + k]; |
|
|
|
|
float v11 = sptr[step + cn + k]; |
|
|
|
|
|
|
|
|
|
v00 = v00 + xs*(v01 - v00); |
|
|
|
|
v10 = v10 + xs*(v11 - v10); |
|
|
|
|
v00 = v00 + ys*(v10 - v00); |
|
|
|
|
((ushort*)dptr)[k] = (ushort)cvRound(v00); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case CV_32F: |
|
|
|
|
{ |
|
|
|
|
const float* sptr = (const float*)sptr0 + iys*step + ixs*cn; |
|
|
|
|
for( k = 0; k < cn; k++ ) |
|
|
|
|
{ |
|
|
|
|
float v00 = sptr[k]; |
|
|
|
|
float v01 = sptr[cn + k]; |
|
|
|
|
float v10 = sptr[step + k]; |
|
|
|
|
float v11 = sptr[step + cn + k]; |
|
|
|
|
|
|
|
|
|
v00 = v00 + xs*(v01 - v00); |
|
|
|
|
v10 = v10 + xs*(v11 - v10); |
|
|
|
|
v00 = v00 + ys*(v10 - v00); |
|
|
|
|
((float*)dptr)[k] = (float)v00; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
assert(0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class CV_ImgWarpBaseTest : public cvtest::ArrayTest |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
CV_ImgWarpBaseTest( bool warp_matrix ); |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
int read_params( CvFileStorage* fs ); |
|
|
|
|
int prepare_test_case( int test_case_idx ); |
|
|
|
|
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types ); |
|
|
|
|
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); |
|
|
|
|
void fill_array( int test_case_idx, int i, int j, Mat& arr ); |
|
|
|
|
|
|
|
|
|
int interpolation; |
|
|
|
|
int max_interpolation; |
|
|
|
|
double spatial_scale_zoom, spatial_scale_decimate; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix ) |
|
|
|
|
{ |
|
|
|
|
test_array[INPUT].push_back(NULL); |
|
|
|
|
if( warp_matrix ) |
|
|
|
|
test_array[INPUT].push_back(NULL); |
|
|
|
|
test_array[INPUT_OUTPUT].push_back(NULL); |
|
|
|
|
test_array[REF_INPUT_OUTPUT].push_back(NULL); |
|
|
|
|
max_interpolation = 5; |
|
|
|
|
interpolation = 0; |
|
|
|
|
element_wise_relative_error = false; |
|
|
|
|
spatial_scale_zoom = 0.01; |
|
|
|
|
spatial_scale_decimate = 0.005; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs ) |
|
|
|
|
{ |
|
|
|
|
int code = cvtest::ArrayTest::read_params( fs ); |
|
|
|
|
return code; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_ImgWarpBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) |
|
|
|
|
{ |
|
|
|
|
cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); |
|
|
|
|
if( CV_MAT_DEPTH(type) == CV_32F ) |
|
|
|
|
{ |
|
|
|
|
low = Scalar::all(-10.); |
|
|
|
|
high = Scalar::all(10); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_ImgWarpBaseTest::get_test_array_types_and_sizes( int test_case_idx, |
|
|
|
|
vector<vector<Size> >& sizes, vector<vector<int> >& types ) |
|
|
|
|
{ |
|
|
|
|
RNG& rng = ts->get_rng(); |
|
|
|
|
int depth = cvtest::randInt(rng) % 3; |
|
|
|
|
int cn = cvtest::randInt(rng) % 3 + 1; |
|
|
|
|
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); |
|
|
|
|
depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F; |
|
|
|
|
cn += cn == 2; |
|
|
|
|
|
|
|
|
|
types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn); |
|
|
|
|
if( test_array[INPUT].size() > 1 ) |
|
|
|
|
types[INPUT][1] = cvtest::randInt(rng) & 1 ? CV_32FC1 : CV_64FC1; |
|
|
|
|
|
|
|
|
|
interpolation = cvtest::randInt(rng) % max_interpolation; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_ImgWarpBaseTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) |
|
|
|
|
{ |
|
|
|
|
if( i != INPUT || j != 0 ) |
|
|
|
|
cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int CV_ImgWarpBaseTest::prepare_test_case( int test_case_idx ) |
|
|
|
|
{ |
|
|
|
|
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); |
|
|
|
|
Mat& img = test_mat[INPUT][0]; |
|
|
|
|
int i, j, cols = img.cols; |
|
|
|
|
int type = img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); |
|
|
|
|
double scale = depth == CV_16U ? 1000. : 255.*0.5; |
|
|
|
|
double space_scale = spatial_scale_decimate; |
|
|
|
|
vector<float> buffer(img.cols*cn); |
|
|
|
|
|
|
|
|
|
if( code <= 0 ) |
|
|
|
|
return code; |
|
|
|
|
|
|
|
|
|
if( test_mat[INPUT_OUTPUT][0].cols >= img.cols && |
|
|
|
|
test_mat[INPUT_OUTPUT][0].rows >= img.rows ) |
|
|
|
|
space_scale = spatial_scale_zoom; |
|
|
|
|
|
|
|
|
|
for( i = 0; i < img.rows; i++ ) |
|
|
|
|
{ |
|
|
|
|
uchar* ptr = img.ptr(i); |
|
|
|
|
switch( cn ) |
|
|
|
|
{ |
|
|
|
|
case 1: |
|
|
|
|
for( j = 0; j < cols; j++ ) |
|
|
|
|
buffer[j] = (float)((sin((i+1)*space_scale)*sin((j+1)*space_scale)+1.)*scale); |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
for( j = 0; j < cols; j++ ) |
|
|
|
|
{ |
|
|
|
|
buffer[j*2] = (float)((sin((i+1)*space_scale)+1.)*scale); |
|
|
|
|
buffer[j*2+1] = (float)((sin((i+j)*space_scale)+1.)*scale); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 3: |
|
|
|
|
for( j = 0; j < cols; j++ ) |
|
|
|
|
{ |
|
|
|
|
buffer[j*3] = (float)((sin((i+1)*space_scale)+1.)*scale); |
|
|
|
|
buffer[j*3+1] = (float)((sin(j*space_scale)+1.)*scale); |
|
|
|
|
buffer[j*3+2] = (float)((sin((i+j)*space_scale)+1.)*scale); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 4: |
|
|
|
|
for( j = 0; j < cols; j++ ) |
|
|
|
|
{ |
|
|
|
|
buffer[j*4] = (float)((sin((i+1)*space_scale)+1.)*scale); |
|
|
|
|
buffer[j*4+1] = (float)((sin(j*space_scale)+1.)*scale); |
|
|
|
|
buffer[j*4+2] = (float)((sin((i+j)*space_scale)+1.)*scale); |
|
|
|
|
buffer[j*4+3] = (float)((sin((i-j)*space_scale)+1.)*scale); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
assert(0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*switch( depth )
|
|
|
|
|
{ |
|
|
|
|
case CV_8U: |
|
|
|
|
for( j = 0; j < cols*cn; j++ ) |
|
|
|
|
ptr[j] = (uchar)cvRound(buffer[j]); |
|
|
|
|
break; |
|
|
|
|
case CV_16U: |
|
|
|
|
for( j = 0; j < cols*cn; j++ ) |
|
|
|
|
((ushort*)ptr)[j] = (ushort)cvRound(buffer[j]); |
|
|
|
|
break; |
|
|
|
|
case CV_32F: |
|
|
|
|
for( j = 0; j < cols*cn; j++ ) |
|
|
|
|
((float*)ptr)[j] = (float)buffer[j]; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
assert(0); |
|
|
|
|
}*/ |
|
|
|
|
cv::Mat src(1, cols*cn, CV_32F, &buffer[0]); |
|
|
|
|
cv::Mat dst(1, cols*cn, depth, ptr); |
|
|
|
|
src.convertTo(dst, dst.type()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return code; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CV_UndistortTest : public CV_ImgWarpBaseTest |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
CV_UndistortTest(); |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types ); |
|
|
|
|
void run_func(); |
|
|
|
|
int prepare_test_case( int test_case_idx ); |
|
|
|
|
void prepare_to_validation( int /*test_case_idx*/ ); |
|
|
|
|
double get_success_error_level( int test_case_idx, int i, int j ); |
|
|
|
|
void fill_array( int test_case_idx, int i, int j, Mat& arr ); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
bool useCPlus; |
|
|
|
|
cv::Mat input0; |
|
|
|
|
cv::Mat input1; |
|
|
|
|
cv::Mat input2; |
|
|
|
|
cv::Mat input_new_cam; |
|
|
|
|
cv::Mat input_output; |
|
|
|
|
|
|
|
|
|
bool zero_new_cam; |
|
|
|
|
bool zero_distortion; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CV_UndistortTest::CV_UndistortTest() : CV_ImgWarpBaseTest( false ) |
|
|
|
|
{ |
|
|
|
|
//spatial_scale_zoom = spatial_scale_decimate;
|
|
|
|
|
test_array[INPUT].push_back(NULL); |
|
|
|
|
test_array[INPUT].push_back(NULL); |
|
|
|
|
test_array[INPUT].push_back(NULL); |
|
|
|
|
|
|
|
|
|
spatial_scale_decimate = spatial_scale_zoom; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_UndistortTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types ) |
|
|
|
|
{ |
|
|
|
|
RNG& rng = ts->get_rng(); |
|
|
|
|
CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); |
|
|
|
|
int type = types[INPUT][0]; |
|
|
|
|
type = CV_MAKETYPE( CV_8U, CV_MAT_CN(type) ); |
|
|
|
|
types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = type; |
|
|
|
|
types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; |
|
|
|
|
types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; |
|
|
|
|
sizes[INPUT][1] = cvSize(3,3); |
|
|
|
|
sizes[INPUT][2] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4); |
|
|
|
|
types[INPUT][3] = types[INPUT][1]; |
|
|
|
|
sizes[INPUT][3] = sizes[INPUT][1]; |
|
|
|
|
interpolation = CV_INTER_LINEAR; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_UndistortTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) |
|
|
|
|
{ |
|
|
|
|
if( i != INPUT ) |
|
|
|
|
CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_UndistortTest::run_func() |
|
|
|
|
{ |
|
|
|
|
if (!useCPlus) |
|
|
|
|
{ |
|
|
|
|
CvMat a = cvMat(test_mat[INPUT][1]), k = cvMat(test_mat[INPUT][2]); |
|
|
|
|
cvUndistort2( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &a, &k); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if (zero_distortion) |
|
|
|
|
{ |
|
|
|
|
cv::undistort(input0,input_output,input1,cv::Mat()); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
cv::undistort(input0,input_output,input1,input2); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double CV_UndistortTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) |
|
|
|
|
{ |
|
|
|
|
int depth = test_mat[INPUT][0].depth(); |
|
|
|
|
return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int CV_UndistortTest::prepare_test_case( int test_case_idx ) |
|
|
|
|
{ |
|
|
|
|
RNG& rng = ts->get_rng(); |
|
|
|
|
int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx ); |
|
|
|
|
|
|
|
|
|
const Mat& src = test_mat[INPUT][0]; |
|
|
|
|
double k[4], a[9] = {0,0,0,0,0,0,0,0,1}; |
|
|
|
|
double new_cam[9] = {0,0,0,0,0,0,0,0,1}; |
|
|
|
|
double sz = MAX(src.rows, src.cols); |
|
|
|
|
|
|
|
|
|
Mat& _new_cam0 = test_mat[INPUT][3]; |
|
|
|
|
Mat _new_cam(test_mat[INPUT][3].rows,test_mat[INPUT][3].cols,CV_64F,new_cam); |
|
|
|
|
Mat& _a0 = test_mat[INPUT][1]; |
|
|
|
|
Mat _a(3,3,CV_64F,a); |
|
|
|
|
Mat& _k0 = test_mat[INPUT][2]; |
|
|
|
|
Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k); |
|
|
|
|
|
|
|
|
|
if( code <= 0 ) |
|
|
|
|
return code; |
|
|
|
|
|
|
|
|
|
double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7; |
|
|
|
|
a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5; |
|
|
|
|
a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5; |
|
|
|
|
a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6); |
|
|
|
|
a[4] = aspect_ratio*a[0]; |
|
|
|
|
k[0] = cvtest::randReal(rng)*0.06 - 0.03; |
|
|
|
|
k[1] = cvtest::randReal(rng)*0.06 - 0.03; |
|
|
|
|
if( k[0]*k[1] > 0 ) |
|
|
|
|
k[1] = -k[1]; |
|
|
|
|
if( cvtest::randInt(rng)%4 != 0 ) |
|
|
|
|
{ |
|
|
|
|
k[2] = cvtest::randReal(rng)*0.004 - 0.002; |
|
|
|
|
k[3] = cvtest::randReal(rng)*0.004 - 0.002; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
k[2] = k[3] = 0; |
|
|
|
|
|
|
|
|
|
new_cam[0] = a[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[0]; //10%
|
|
|
|
|
new_cam[4] = a[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[4]; //10%
|
|
|
|
|
new_cam[2] = a[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].rows; //15%
|
|
|
|
|
new_cam[5] = a[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].cols; //15%
|
|
|
|
|
|
|
|
|
|
_a.convertTo(_a0, _a0.depth()); |
|
|
|
|
|
|
|
|
|
zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true; |
|
|
|
|
_k.convertTo(_k0, _k0.depth()); |
|
|
|
|
|
|
|
|
|
zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true; |
|
|
|
|
_new_cam.convertTo(_new_cam0, _new_cam0.depth()); |
|
|
|
|
|
|
|
|
|
//Testing C++ code
|
|
|
|
|
useCPlus = ((cvtest::randInt(rng) % 2)!=0); |
|
|
|
|
if (useCPlus) |
|
|
|
|
{ |
|
|
|
|
input0 = test_mat[INPUT][0]; |
|
|
|
|
input1 = test_mat[INPUT][1]; |
|
|
|
|
input2 = test_mat[INPUT][2]; |
|
|
|
|
input_new_cam = test_mat[INPUT][3]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return code; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_UndistortTest::prepare_to_validation( int /*test_case_idx*/ ) |
|
|
|
|
{ |
|
|
|
|
if (useCPlus) |
|
|
|
|
{ |
|
|
|
|
Mat& output = test_mat[INPUT_OUTPUT][0]; |
|
|
|
|
input_output.convertTo(output, output.type()); |
|
|
|
|
} |
|
|
|
|
Mat& src = test_mat[INPUT][0]; |
|
|
|
|
Mat& dst = test_mat[REF_INPUT_OUTPUT][0]; |
|
|
|
|
Mat& dst0 = test_mat[INPUT_OUTPUT][0]; |
|
|
|
|
Mat mapx, mapy; |
|
|
|
|
cvtest::initUndistortMap( test_mat[INPUT][1], test_mat[INPUT][2], dst.size(), mapx, mapy ); |
|
|
|
|
Mat mask( dst.size(), CV_8U ); |
|
|
|
|
test_remap( src, dst, mapx, mapy, &mask, interpolation ); |
|
|
|
|
dst.setTo(Scalar::all(0), mask); |
|
|
|
|
dst0.setTo(Scalar::all(0), mask); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CV_UndistortMapTest : public cvtest::ArrayTest |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
CV_UndistortMapTest(); |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types ); |
|
|
|
|
void run_func(); |
|
|
|
|
int prepare_test_case( int test_case_idx ); |
|
|
|
|
void prepare_to_validation( int /*test_case_idx*/ ); |
|
|
|
|
double get_success_error_level( int test_case_idx, int i, int j ); |
|
|
|
|
void fill_array( int test_case_idx, int i, int j, Mat& arr ); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
bool dualChannel; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CV_UndistortMapTest::CV_UndistortMapTest() |
|
|
|
|
{ |
|
|
|
|
test_array[INPUT].push_back(NULL); |
|
|
|
|
test_array[INPUT].push_back(NULL); |
|
|
|
|
test_array[OUTPUT].push_back(NULL); |
|
|
|
|
test_array[OUTPUT].push_back(NULL); |
|
|
|
|
test_array[REF_OUTPUT].push_back(NULL); |
|
|
|
|
test_array[REF_OUTPUT].push_back(NULL); |
|
|
|
|
|
|
|
|
|
element_wise_relative_error = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_UndistortMapTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types ) |
|
|
|
|
{ |
|
|
|
|
RNG& rng = ts->get_rng(); |
|
|
|
|
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); |
|
|
|
|
int depth = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; |
|
|
|
|
|
|
|
|
|
Size sz = sizes[OUTPUT][0]; |
|
|
|
|
types[INPUT][0] = types[INPUT][1] = depth; |
|
|
|
|
dualChannel = cvtest::randInt(rng)%2 == 0; |
|
|
|
|
types[OUTPUT][0] = types[OUTPUT][1] = |
|
|
|
|
types[REF_OUTPUT][0] = types[REF_OUTPUT][1] = dualChannel ? CV_32FC2 : CV_32F; |
|
|
|
|
sizes[INPUT][0] = cvSize(3,3); |
|
|
|
|
sizes[INPUT][1] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4); |
|
|
|
|
|
|
|
|
|
sz.width = MAX(sz.width,16); |
|
|
|
|
sz.height = MAX(sz.height,16); |
|
|
|
|
sizes[OUTPUT][0] = sizes[OUTPUT][1] = |
|
|
|
|
sizes[REF_OUTPUT][0] = sizes[REF_OUTPUT][1] = sz; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_UndistortMapTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) |
|
|
|
|
{ |
|
|
|
|
if( i != INPUT ) |
|
|
|
|
cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_UndistortMapTest::run_func() |
|
|
|
|
{ |
|
|
|
|
CvMat a = cvMat(test_mat[INPUT][0]), k = cvMat(test_mat[INPUT][1]); |
|
|
|
|
|
|
|
|
|
if (!dualChannel ) |
|
|
|
|
cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], test_array[OUTPUT][1] ); |
|
|
|
|
else |
|
|
|
|
cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], 0 ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double CV_UndistortMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) |
|
|
|
|
{ |
|
|
|
|
return 1e-3; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int CV_UndistortMapTest::prepare_test_case( int test_case_idx ) |
|
|
|
|
{ |
|
|
|
|
RNG& rng = ts->get_rng(); |
|
|
|
|
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); |
|
|
|
|
const Mat& mapx = test_mat[OUTPUT][0]; |
|
|
|
|
double k[4], a[9] = {0,0,0,0,0,0,0,0,1}; |
|
|
|
|
double sz = MAX(mapx.rows, mapx.cols); |
|
|
|
|
Mat& _a0 = test_mat[INPUT][0], &_k0 = test_mat[INPUT][1]; |
|
|
|
|
Mat _a(3,3,CV_64F,a); |
|
|
|
|
Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k); |
|
|
|
|
|
|
|
|
|
if( code <= 0 ) |
|
|
|
|
return code; |
|
|
|
|
|
|
|
|
|
double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7; |
|
|
|
|
a[2] = (mapx.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5; |
|
|
|
|
a[5] = (mapx.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5; |
|
|
|
|
a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6); |
|
|
|
|
a[4] = aspect_ratio*a[0]; |
|
|
|
|
k[0] = cvtest::randReal(rng)*0.06 - 0.03; |
|
|
|
|
k[1] = cvtest::randReal(rng)*0.06 - 0.03; |
|
|
|
|
if( k[0]*k[1] > 0 ) |
|
|
|
|
k[1] = -k[1]; |
|
|
|
|
k[2] = cvtest::randReal(rng)*0.004 - 0.002; |
|
|
|
|
k[3] = cvtest::randReal(rng)*0.004 - 0.002; |
|
|
|
|
|
|
|
|
|
_a.convertTo(_a0, _a0.depth()); |
|
|
|
|
_k.convertTo(_k0, _k0.depth()); |
|
|
|
|
|
|
|
|
|
if (dualChannel) |
|
|
|
|
{ |
|
|
|
|
test_mat[REF_OUTPUT][1] = Scalar::all(0); |
|
|
|
|
test_mat[OUTPUT][1] = Scalar::all(0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return code; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CV_UndistortMapTest::prepare_to_validation( int ) |
|
|
|
|
{ |
|
|
|
|
Mat mapx, mapy; |
|
|
|
|
cvtest::initUndistortMap( test_mat[INPUT][0], test_mat[INPUT][1], test_mat[REF_OUTPUT][0].size(), mapx, mapy ); |
|
|
|
|
if( !dualChannel ) |
|
|
|
|
{ |
|
|
|
|
mapx.copyTo(test_mat[REF_OUTPUT][0]); |
|
|
|
|
mapy.copyTo(test_mat[REF_OUTPUT][1]); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Mat p[2] = {mapx, mapy}; |
|
|
|
|
cv::merge(p, 2, test_mat[REF_OUTPUT][0]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST(Calib3d_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); } |
|
|
|
|
TEST(Calib3d_InitUndistortMap, accuracy) { CV_UndistortMapTest test; test.safe_run(); } |
|
|
|
|
|
|
|
|
|
}} // namespace
|
|
|
|
|