Home | History | Annotate | Download | only in test
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                        Intel License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of Intel Corporation may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the Intel Corporation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 
     42 #include "test_precomp.hpp"
     43 
     44 using namespace cv;
     45 using namespace std;
     46 
     47 class CV_ImgWarpBaseTest : public cvtest::ArrayTest
     48 {
     49 public:
     50     CV_ImgWarpBaseTest( bool warp_matrix );
     51 
     52 protected:
     53     int read_params( CvFileStorage* fs );
     54     int prepare_test_case( int test_case_idx );
     55     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
     56     void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
     57     void fill_array( int test_case_idx, int i, int j, Mat& arr );
     58 
     59     int interpolation;
     60     int max_interpolation;
     61     double spatial_scale_zoom, spatial_scale_decimate;
     62 };
     63 
     64 
     65 CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix )
     66 {
     67     test_array[INPUT].push_back(NULL);
     68     if( warp_matrix )
     69         test_array[INPUT].push_back(NULL);
     70     test_array[INPUT_OUTPUT].push_back(NULL);
     71     test_array[REF_INPUT_OUTPUT].push_back(NULL);
     72     max_interpolation = 5;
     73     interpolation = 0;
     74     element_wise_relative_error = false;
     75     spatial_scale_zoom = 0.01;
     76     spatial_scale_decimate = 0.005;
     77 }
     78 
     79 
     80 int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs )
     81 {
     82     int code = cvtest::ArrayTest::read_params( fs );
     83     return code;
     84 }
     85 
     86 
     87 void CV_ImgWarpBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
     88 {
     89     cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );
     90     if( CV_MAT_DEPTH(type) == CV_32F )
     91     {
     92         low = Scalar::all(-10.);
     93         high = Scalar::all(10);
     94     }
     95 }
     96 
     97 
     98 void CV_ImgWarpBaseTest::get_test_array_types_and_sizes( int test_case_idx,
     99                                                 vector<vector<Size> >& sizes, vector<vector<int> >& types )
    100 {
    101     RNG& rng = ts->get_rng();
    102     int depth = cvtest::randInt(rng) % 3;
    103     int cn = cvtest::randInt(rng) % 3 + 1;
    104     cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    105     depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F;
    106     cn += cn == 2;
    107 
    108     types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn);
    109     if( test_array[INPUT].size() > 1 )
    110         types[INPUT][1] = cvtest::randInt(rng) & 1 ? CV_32FC1 : CV_64FC1;
    111 
    112     interpolation = cvtest::randInt(rng) % max_interpolation;
    113 }
    114 
    115 
    116 void CV_ImgWarpBaseTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
    117 {
    118     if( i != INPUT || j != 0 )
    119         cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
    120 }
    121 
    122 int CV_ImgWarpBaseTest::prepare_test_case( int test_case_idx )
    123 {
    124     int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
    125     Mat& img = test_mat[INPUT][0];
    126     int i, j, cols = img.cols;
    127     int type = img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
    128     double scale = depth == CV_16U ? 1000. : 255.*0.5;
    129     double space_scale = spatial_scale_decimate;
    130     vector<float> buffer(img.cols*cn);
    131 
    132     if( code <= 0 )
    133         return code;
    134 
    135     if( test_mat[INPUT_OUTPUT][0].cols >= img.cols &&
    136         test_mat[INPUT_OUTPUT][0].rows >= img.rows )
    137         space_scale = spatial_scale_zoom;
    138 
    139     for( i = 0; i < img.rows; i++ )
    140     {
    141         uchar* ptr = img.ptr(i);
    142         switch( cn )
    143         {
    144         case 1:
    145             for( j = 0; j < cols; j++ )
    146                 buffer[j] = (float)((sin((i+1)*space_scale)*sin((j+1)*space_scale)+1.)*scale);
    147             break;
    148         case 2:
    149             for( j = 0; j < cols; j++ )
    150             {
    151                 buffer[j*2] = (float)((sin((i+1)*space_scale)+1.)*scale);
    152                 buffer[j*2+1] = (float)((sin((i+j)*space_scale)+1.)*scale);
    153             }
    154             break;
    155         case 3:
    156             for( j = 0; j < cols; j++ )
    157             {
    158                 buffer[j*3] = (float)((sin((i+1)*space_scale)+1.)*scale);
    159                 buffer[j*3+1] = (float)((sin(j*space_scale)+1.)*scale);
    160                 buffer[j*3+2] = (float)((sin((i+j)*space_scale)+1.)*scale);
    161             }
    162             break;
    163         case 4:
    164             for( j = 0; j < cols; j++ )
    165             {
    166                 buffer[j*4] = (float)((sin((i+1)*space_scale)+1.)*scale);
    167                 buffer[j*4+1] = (float)((sin(j*space_scale)+1.)*scale);
    168                 buffer[j*4+2] = (float)((sin((i+j)*space_scale)+1.)*scale);
    169                 buffer[j*4+3] = (float)((sin((i-j)*space_scale)+1.)*scale);
    170             }
    171             break;
    172         default:
    173             assert(0);
    174         }
    175 
    176         /*switch( depth )
    177         {
    178         case CV_8U:
    179             for( j = 0; j < cols*cn; j++ )
    180                 ptr[j] = (uchar)cvRound(buffer[j]);
    181             break;
    182         case CV_16U:
    183             for( j = 0; j < cols*cn; j++ )
    184                 ((ushort*)ptr)[j] = (ushort)cvRound(buffer[j]);
    185             break;
    186         case CV_32F:
    187             for( j = 0; j < cols*cn; j++ )
    188                 ((float*)ptr)[j] = (float)buffer[j];
    189             break;
    190         default:
    191             assert(0);
    192         }*/
    193         cv::Mat src(1, cols*cn, CV_32F, &buffer[0]);
    194         cv::Mat dst(1, cols*cn, depth, ptr);
    195         src.convertTo(dst, dst.type());
    196     }
    197 
    198     return code;
    199 }
    200 
    201 
    202 /////////////////////////
    203 
    204 class CV_ResizeTest : public CV_ImgWarpBaseTest
    205 {
    206 public:
    207     CV_ResizeTest();
    208 
    209 protected:
    210     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    211     void run_func();
    212     void prepare_to_validation( int /*test_case_idx*/ );
    213     double get_success_error_level( int test_case_idx, int i, int j );
    214 };
    215 
    216 
    217 CV_ResizeTest::CV_ResizeTest() : CV_ImgWarpBaseTest( false )
    218 {
    219 }
    220 
    221 
    222 void CV_ResizeTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    223 {
    224     RNG& rng = ts->get_rng();
    225     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    226     CvSize sz;
    227 
    228     sz.width = (cvtest::randInt(rng) % sizes[INPUT][0].width) + 1;
    229     sz.height = (cvtest::randInt(rng) % sizes[INPUT][0].height) + 1;
    230 
    231     if( cvtest::randInt(rng) & 1 )
    232     {
    233         int xfactor = cvtest::randInt(rng) % 10 + 1;
    234         int yfactor = cvtest::randInt(rng) % 10 + 1;
    235 
    236         if( cvtest::randInt(rng) & 1 )
    237             yfactor = xfactor;
    238 
    239         sz.width = sizes[INPUT][0].width / xfactor;
    240         sz.width = MAX(sz.width,1);
    241         sz.height = sizes[INPUT][0].height / yfactor;
    242         sz.height = MAX(sz.height,1);
    243         sizes[INPUT][0].width = sz.width * xfactor;
    244         sizes[INPUT][0].height = sz.height * yfactor;
    245     }
    246 
    247     if( cvtest::randInt(rng) & 1 )
    248         sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = sz;
    249     else
    250     {
    251         sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = sizes[INPUT][0];
    252         sizes[INPUT][0] = sz;
    253     }
    254     if( interpolation == 4 &&
    255        (MIN(sizes[INPUT][0].width,sizes[INPUT_OUTPUT][0].width) < 4 ||
    256         MIN(sizes[INPUT][0].height,sizes[INPUT_OUTPUT][0].height) < 4))
    257         interpolation = 2;
    258 }
    259 
    260 
    261 void CV_ResizeTest::run_func()
    262 {
    263     cvResize( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], interpolation );
    264 }
    265 
    266 
    267 double CV_ResizeTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
    268 {
    269     int depth = test_mat[INPUT][0].depth();
    270     return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 1e-1;
    271 }
    272 
    273 
    274 void CV_ResizeTest::prepare_to_validation( int /*test_case_idx*/ )
    275 {
    276     CvMat _src = test_mat[INPUT][0], _dst = test_mat[REF_INPUT_OUTPUT][0];
    277     CvMat *src = &_src, *dst = &_dst;
    278     int i, j, k;
    279     CvMat* x_idx = cvCreateMat( 1, dst->cols, CV_32SC1 );
    280     CvMat* y_idx = cvCreateMat( 1, dst->rows, CV_32SC1 );
    281     int* x_tab = x_idx->data.i;
    282     int elem_size = CV_ELEM_SIZE(src->type);
    283     int drows = dst->rows, dcols = dst->cols;
    284 
    285     if( interpolation == CV_INTER_NN )
    286     {
    287         for( j = 0; j < dcols; j++ )
    288         {
    289             int t = (j*src->cols*2 + MIN(src->cols,dcols) - 1)/(dcols*2);
    290             t -= t >= src->cols;
    291             x_idx->data.i[j] = t*elem_size;
    292         }
    293 
    294         for( j = 0; j < drows; j++ )
    295         {
    296             int t = (j*src->rows*2 + MIN(src->rows,drows) - 1)/(drows*2);
    297             t -= t >= src->rows;
    298             y_idx->data.i[j] = t;
    299         }
    300     }
    301     else
    302     {
    303         double scale_x = (double)src->cols/dcols;
    304         double scale_y = (double)src->rows/drows;
    305 
    306         for( j = 0; j < dcols; j++ )
    307         {
    308             double f = ((j+0.5)*scale_x - 0.5);
    309             i = cvRound(f);
    310             x_idx->data.i[j] = (i < 0 ? 0 : i >= src->cols ? src->cols - 1 : i)*elem_size;
    311         }
    312 
    313         for( j = 0; j < drows; j++ )
    314         {
    315             double f = ((j+0.5)*scale_y - 0.5);
    316             i = cvRound(f);
    317             y_idx->data.i[j] = i < 0 ? 0 : i >= src->rows ? src->rows - 1 : i;
    318         }
    319     }
    320 
    321     for( i = 0; i < drows; i++ )
    322     {
    323         uchar* dptr = dst->data.ptr + dst->step*i;
    324         const uchar* sptr0 = src->data.ptr + src->step*y_idx->data.i[i];
    325 
    326         for( j = 0; j < dcols; j++, dptr += elem_size )
    327         {
    328             const uchar* sptr = sptr0 + x_tab[j];
    329             for( k = 0; k < elem_size; k++ )
    330                 dptr[k] = sptr[k];
    331         }
    332     }
    333 
    334     cvReleaseMat( &x_idx );
    335     cvReleaseMat( &y_idx );
    336 }
    337 
    338 
    339 /////////////////////////
    340 
    341 static void test_remap( const Mat& src, Mat& dst, const Mat& mapx, const Mat& mapy,
    342                         Mat* mask=0, int interpolation=CV_INTER_LINEAR )
    343 {
    344     int x, y, k;
    345     int drows = dst.rows, dcols = dst.cols;
    346     int srows = src.rows, scols = src.cols;
    347     const uchar* sptr0 = src.ptr();
    348     int depth = src.depth(), cn = src.channels();
    349     int elem_size = (int)src.elemSize();
    350     int step = (int)(src.step / CV_ELEM_SIZE(depth));
    351     int delta;
    352 
    353     if( interpolation != CV_INTER_CUBIC )
    354     {
    355         delta = 0;
    356         scols -= 1; srows -= 1;
    357     }
    358     else
    359     {
    360         delta = 1;
    361         scols = MAX(scols - 3, 0);
    362         srows = MAX(srows - 3, 0);
    363     }
    364 
    365     int scols1 = MAX(scols - 2, 0);
    366     int srows1 = MAX(srows - 2, 0);
    367 
    368     if( mask )
    369         *mask = Scalar::all(0);
    370 
    371     for( y = 0; y < drows; y++ )
    372     {
    373         uchar* dptr = dst.ptr(y);
    374         const float* mx = mapx.ptr<float>(y);
    375         const float* my = mapy.ptr<float>(y);
    376         uchar* m = mask ? mask->ptr(y) : 0;
    377 
    378         for( x = 0; x < dcols; x++, dptr += elem_size )
    379         {
    380             float xs = mx[x];
    381             float ys = my[x];
    382             int ixs = cvFloor(xs);
    383             int iys = cvFloor(ys);
    384 
    385             if( (unsigned)(ixs - delta - 1) >= (unsigned)scols1 ||
    386                 (unsigned)(iys - delta - 1) >= (unsigned)srows1 )
    387             {
    388                 if( m )
    389                     m[x] = 1;
    390                 if( (unsigned)(ixs - delta) >= (unsigned)scols ||
    391                     (unsigned)(iys - delta) >= (unsigned)srows )
    392                     continue;
    393             }
    394 
    395             xs -= ixs;
    396             ys -= iys;
    397 
    398             switch( depth )
    399             {
    400             case CV_8U:
    401                 {
    402                 const uchar* sptr = sptr0 + iys*step + ixs*cn;
    403                 for( k = 0; k < cn; k++ )
    404                 {
    405                     float v00 = sptr[k];
    406                     float v01 = sptr[cn + k];
    407                     float v10 = sptr[step + k];
    408                     float v11 = sptr[step + cn + k];
    409 
    410                     v00 = v00 + xs*(v01 - v00);
    411                     v10 = v10 + xs*(v11 - v10);
    412                     v00 = v00 + ys*(v10 - v00);
    413                     dptr[k] = (uchar)cvRound(v00);
    414                 }
    415                 }
    416                 break;
    417             case CV_16U:
    418                 {
    419                 const ushort* sptr = (const ushort*)sptr0 + iys*step + ixs*cn;
    420                 for( k = 0; k < cn; k++ )
    421                 {
    422                     float v00 = sptr[k];
    423                     float v01 = sptr[cn + k];
    424                     float v10 = sptr[step + k];
    425                     float v11 = sptr[step + cn + k];
    426 
    427                     v00 = v00 + xs*(v01 - v00);
    428                     v10 = v10 + xs*(v11 - v10);
    429                     v00 = v00 + ys*(v10 - v00);
    430                     ((ushort*)dptr)[k] = (ushort)cvRound(v00);
    431                 }
    432                 }
    433                 break;
    434             case CV_32F:
    435                 {
    436                 const float* sptr = (const float*)sptr0 + iys*step + ixs*cn;
    437                 for( k = 0; k < cn; k++ )
    438                 {
    439                     float v00 = sptr[k];
    440                     float v01 = sptr[cn + k];
    441                     float v10 = sptr[step + k];
    442                     float v11 = sptr[step + cn + k];
    443 
    444                     v00 = v00 + xs*(v01 - v00);
    445                     v10 = v10 + xs*(v11 - v10);
    446                     v00 = v00 + ys*(v10 - v00);
    447                     ((float*)dptr)[k] = (float)v00;
    448                 }
    449                 }
    450                 break;
    451             default:
    452                 assert(0);
    453             }
    454         }
    455     }
    456 }
    457 
    458 /////////////////////////
    459 
    460 class CV_WarpAffineTest : public CV_ImgWarpBaseTest
    461 {
    462 public:
    463     CV_WarpAffineTest();
    464 
    465 protected:
    466     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    467     void run_func();
    468     int prepare_test_case( int test_case_idx );
    469     void prepare_to_validation( int /*test_case_idx*/ );
    470     double get_success_error_level( int test_case_idx, int i, int j );
    471 };
    472 
    473 
    474 CV_WarpAffineTest::CV_WarpAffineTest() : CV_ImgWarpBaseTest( true )
    475 {
    476     //spatial_scale_zoom = spatial_scale_decimate;
    477     spatial_scale_decimate = spatial_scale_zoom;
    478 }
    479 
    480 
    481 void CV_WarpAffineTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    482 {
    483     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    484     CvSize sz = sizes[INPUT][0];
    485     // run for the second time to get output of a different size
    486     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    487     sizes[INPUT][0] = sz;
    488     sizes[INPUT][1] = cvSize( 3, 2 );
    489 }
    490 
    491 
    492 void CV_WarpAffineTest::run_func()
    493 {
    494     CvMat mtx = test_mat[INPUT][1];
    495     cvWarpAffine( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &mtx, interpolation );
    496 }
    497 
    498 
    499 double CV_WarpAffineTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
    500 {
    501     int depth = test_mat[INPUT][0].depth();
    502     return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;
    503 }
    504 
    505 
    506 int CV_WarpAffineTest::prepare_test_case( int test_case_idx )
    507 {
    508     RNG& rng = ts->get_rng();
    509     int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
    510     const Mat& src = test_mat[INPUT][0];
    511     const Mat& dst = test_mat[INPUT_OUTPUT][0];
    512     Mat& mat = test_mat[INPUT][1];
    513     CvPoint2D32f center;
    514     double scale, angle;
    515 
    516     if( code <= 0 )
    517         return code;
    518 
    519     double buffer[6];
    520     Mat tmp( 2, 3, mat.type(), buffer );
    521 
    522     center.x = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.cols);
    523     center.y = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.rows);
    524     angle = cvtest::randReal(rng)*360;
    525     scale = ((double)dst.rows/src.rows + (double)dst.cols/src.cols)*0.5;
    526     getRotationMatrix2D(center, angle, scale).convertTo(mat, mat.depth());
    527     rng.fill( tmp, CV_RAND_NORMAL, Scalar::all(1.), Scalar::all(0.01) );
    528     cv::max(tmp, 0.9, tmp);
    529     cv::min(tmp, 1.1, tmp);
    530     cv::multiply(tmp, mat, mat, 1.);
    531 
    532     return code;
    533 }
    534 
    535 
    536 void CV_WarpAffineTest::prepare_to_validation( int /*test_case_idx*/ )
    537 {
    538     const Mat& src = test_mat[INPUT][0];
    539     Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
    540     Mat& dst0 = test_mat[INPUT_OUTPUT][0];
    541     Mat mapx(dst.size(), CV_32F), mapy(dst.size(), CV_32F);
    542     double m[6];
    543     Mat srcAb, dstAb( 2, 3, CV_64FC1, m );
    544 
    545     //cvInvert( &tM, &M, CV_LU );
    546     // [R|t] -> [R^-1 | -(R^-1)*t]
    547     test_mat[INPUT][1].convertTo( srcAb, CV_64F );
    548     Mat A = srcAb.colRange(0, 2);
    549     Mat b = srcAb.col(2);
    550     Mat invA = dstAb.colRange(0, 2);
    551     Mat invAb = dstAb.col(2);
    552     cv::invert(A, invA, CV_SVD);
    553     cv::gemm(invA, b, -1, Mat(), 0, invAb);
    554 
    555     for( int y = 0; y < dst.rows; y++ )
    556         for( int x = 0; x < dst.cols; x++ )
    557         {
    558             mapx.at<float>(y, x) = (float)(x*m[0] + y*m[1] + m[2]);
    559             mapy.at<float>(y, x) = (float)(x*m[3] + y*m[4] + m[5]);
    560         }
    561 
    562     Mat mask( dst.size(), CV_8U );
    563     test_remap( src, dst, mapx, mapy, &mask );
    564     dst.setTo(Scalar::all(0), mask);
    565     dst0.setTo(Scalar::all(0), mask);
    566 }
    567 
    568 
    569 /////////////////////////
    570 
    571 class CV_WarpPerspectiveTest : public CV_ImgWarpBaseTest
    572 {
    573 public:
    574     CV_WarpPerspectiveTest();
    575 
    576 protected:
    577     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    578     void run_func();
    579     int prepare_test_case( int test_case_idx );
    580     void prepare_to_validation( int /*test_case_idx*/ );
    581     double get_success_error_level( int test_case_idx, int i, int j );
    582 };
    583 
    584 
    585 CV_WarpPerspectiveTest::CV_WarpPerspectiveTest() : CV_ImgWarpBaseTest( true )
    586 {
    587     //spatial_scale_zoom = spatial_scale_decimate;
    588     spatial_scale_decimate = spatial_scale_zoom;
    589 }
    590 
    591 
    592 void CV_WarpPerspectiveTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    593 {
    594     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    595     CvSize sz = sizes[INPUT][0];
    596     // run for the second time to get output of a different size
    597     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    598     sizes[INPUT][0] = sz;
    599     sizes[INPUT][1] = cvSize( 3, 3 );
    600 }
    601 
    602 
    603 void CV_WarpPerspectiveTest::run_func()
    604 {
    605     CvMat mtx = test_mat[INPUT][1];
    606     cvWarpPerspective( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &mtx, interpolation );
    607 }
    608 
    609 
    610 double CV_WarpPerspectiveTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
    611 {
    612     int depth = test_mat[INPUT][0].depth();
    613     return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;
    614 }
    615 
    616 
    617 int CV_WarpPerspectiveTest::prepare_test_case( int test_case_idx )
    618 {
    619     RNG& rng = ts->get_rng();
    620     int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
    621     const CvMat& src = test_mat[INPUT][0];
    622     const CvMat& dst = test_mat[INPUT_OUTPUT][0];
    623     Mat& mat = test_mat[INPUT][1];
    624     Point2f s[4], d[4];
    625     int i;
    626 
    627     if( code <= 0 )
    628         return code;
    629 
    630     s[0] = Point2f(0,0);
    631     d[0] = Point2f(0,0);
    632     s[1] = Point2f(src.cols-1.f,0);
    633     d[1] = Point2f(dst.cols-1.f,0);
    634     s[2] = Point2f(src.cols-1.f,src.rows-1.f);
    635     d[2] = Point2f(dst.cols-1.f,dst.rows-1.f);
    636     s[3] = Point2f(0,src.rows-1.f);
    637     d[3] = Point2f(0,dst.rows-1.f);
    638 
    639     float bufer[16];
    640     Mat tmp( 1, 16, CV_32FC1, bufer );
    641 
    642     rng.fill( tmp, CV_RAND_NORMAL, Scalar::all(0.), Scalar::all(0.1) );
    643 
    644     for( i = 0; i < 4; i++ )
    645     {
    646         s[i].x += bufer[i*4]*src.cols/2;
    647         s[i].y += bufer[i*4+1]*src.rows/2;
    648         d[i].x += bufer[i*4+2]*dst.cols/2;
    649         d[i].y += bufer[i*4+3]*dst.rows/2;
    650     }
    651 
    652     cv::getPerspectiveTransform( s, d ).convertTo( mat, mat.depth() );
    653     return code;
    654 }
    655 
    656 
    657 void CV_WarpPerspectiveTest::prepare_to_validation( int /*test_case_idx*/ )
    658 {
    659     Mat& src = test_mat[INPUT][0];
    660     Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
    661     Mat& dst0 = test_mat[INPUT_OUTPUT][0];
    662     Mat mapx(dst.size(), CV_32F), mapy(dst.size(), CV_32F);
    663     double m[9];
    664     Mat srcM, dstM(3, 3, CV_64F, m);
    665 
    666     //cvInvert( &tM, &M, CV_LU );
    667     // [R|t] -> [R^-1 | -(R^-1)*t]
    668     test_mat[INPUT][1].convertTo( srcM, CV_64F );
    669     cv::invert(srcM, dstM, CV_SVD);
    670 
    671     for( int y = 0; y < dst.rows; y++ )
    672     {
    673         for( int x = 0; x < dst.cols; x++ )
    674         {
    675             double xs = x*m[0] + y*m[1] + m[2];
    676             double ys = x*m[3] + y*m[4] + m[5];
    677             double ds = x*m[6] + y*m[7] + m[8];
    678 
    679             ds = ds ? 1./ds : 0;
    680             xs *= ds;
    681             ys *= ds;
    682 
    683             mapx.at<float>(y, x) = (float)xs;
    684             mapy.at<float>(y, x) = (float)ys;
    685         }
    686     }
    687 
    688     Mat mask( dst.size(), CV_8U );
    689     test_remap( src, dst, mapx, mapy, &mask );
    690     dst.setTo(Scalar::all(0), mask);
    691     dst0.setTo(Scalar::all(0), mask);
    692 }
    693 
    694 
    695 /////////////////////////
    696 
    697 class CV_RemapTest : public CV_ImgWarpBaseTest
    698 {
    699 public:
    700     CV_RemapTest();
    701 
    702 protected:
    703     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    704     void run_func();
    705     int prepare_test_case( int test_case_idx );
    706     void prepare_to_validation( int /*test_case_idx*/ );
    707     double get_success_error_level( int test_case_idx, int i, int j );
    708     void fill_array( int test_case_idx, int i, int j, Mat& arr );
    709 };
    710 
    711 
    712 CV_RemapTest::CV_RemapTest() : CV_ImgWarpBaseTest( false )
    713 {
    714     //spatial_scale_zoom = spatial_scale_decimate;
    715     test_array[INPUT].push_back(NULL);
    716     test_array[INPUT].push_back(NULL);
    717 
    718     spatial_scale_decimate = spatial_scale_zoom;
    719 }
    720 
    721 
    722 void CV_RemapTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    723 {
    724     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    725     types[INPUT][1] = types[INPUT][2] = CV_32FC1;
    726     interpolation = CV_INTER_LINEAR;
    727 }
    728 
    729 
    730 void CV_RemapTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
    731 {
    732     if( i != INPUT )
    733         CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr );
    734 }
    735 
    736 
    737 void CV_RemapTest::run_func()
    738 {
    739     cvRemap( test_array[INPUT][0], test_array[INPUT_OUTPUT][0],
    740              test_array[INPUT][1], test_array[INPUT][2], interpolation );
    741 }
    742 
    743 
    744 double CV_RemapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
    745 {
    746     int depth = test_mat[INPUT][0].depth();
    747     return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;
    748 }
    749 
    750 
    751 int CV_RemapTest::prepare_test_case( int test_case_idx )
    752 {
    753     RNG& rng = ts->get_rng();
    754     int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
    755     const Mat& src = test_mat[INPUT][0];
    756     double a[9] = {0,0,0,0,0,0,0,0,1}, k[4];
    757     Mat _a( 3, 3, CV_64F, a );
    758     Mat _k( 4, 1, CV_64F, k );
    759     double sz = MAX(src.rows, src.cols);
    760 
    761     if( code <= 0 )
    762         return code;
    763 
    764     double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;
    765     a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
    766     a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
    767     a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);
    768     a[4] = aspect_ratio*a[0];
    769     k[0] = cvtest::randReal(rng)*0.06 - 0.03;
    770     k[1] = cvtest::randReal(rng)*0.06 - 0.03;
    771     if( k[0]*k[1] > 0 )
    772         k[1] = -k[1];
    773     k[2] = cvtest::randReal(rng)*0.004 - 0.002;
    774     k[3] = cvtest::randReal(rng)*0.004 - 0.002;
    775 
    776     cvtest::initUndistortMap( _a, _k, test_mat[INPUT][1].size(), test_mat[INPUT][1], test_mat[INPUT][2] );
    777     return code;
    778 }
    779 
    780 
    781 void CV_RemapTest::prepare_to_validation( int /*test_case_idx*/ )
    782 {
    783     Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
    784     Mat& dst0 = test_mat[INPUT_OUTPUT][0];
    785     Mat mask( dst.size(), CV_8U );
    786     test_remap(test_mat[INPUT][0], dst, test_mat[INPUT][1],
    787                test_mat[INPUT][2], &mask, interpolation );
    788     dst.setTo(Scalar::all(0), mask);
    789     dst0.setTo(Scalar::all(0), mask);
    790 }
    791 
    792 
    793 ////////////////////////////// undistort /////////////////////////////////
    794 
    795 class CV_UndistortTest : public CV_ImgWarpBaseTest
    796 {
    797 public:
    798     CV_UndistortTest();
    799 
    800 protected:
    801     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    802     void run_func();
    803     int prepare_test_case( int test_case_idx );
    804     void prepare_to_validation( int /*test_case_idx*/ );
    805     double get_success_error_level( int test_case_idx, int i, int j );
    806     void fill_array( int test_case_idx, int i, int j, Mat& arr );
    807 
    808 private:
    809     bool useCPlus;
    810     cv::Mat input0;
    811     cv::Mat input1;
    812     cv::Mat input2;
    813     cv::Mat input_new_cam;
    814     cv::Mat input_output;
    815 
    816     bool zero_new_cam;
    817     bool zero_distortion;
    818 };
    819 
    820 
    821 CV_UndistortTest::CV_UndistortTest() : CV_ImgWarpBaseTest( false )
    822 {
    823     //spatial_scale_zoom = spatial_scale_decimate;
    824     test_array[INPUT].push_back(NULL);
    825     test_array[INPUT].push_back(NULL);
    826     test_array[INPUT].push_back(NULL);
    827 
    828     spatial_scale_decimate = spatial_scale_zoom;
    829 }
    830 
    831 
    832 void CV_UndistortTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    833 {
    834     RNG& rng = ts->get_rng();
    835     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    836     int type = types[INPUT][0];
    837     type = CV_MAKETYPE( CV_8U, CV_MAT_CN(type) );
    838     types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = type;
    839     types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
    840     types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
    841     sizes[INPUT][1] = cvSize(3,3);
    842     sizes[INPUT][2] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);
    843     types[INPUT][3] =  types[INPUT][1];
    844     sizes[INPUT][3] = sizes[INPUT][1];
    845     interpolation = CV_INTER_LINEAR;
    846 }
    847 
    848 
    849 void CV_UndistortTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
    850 {
    851     if( i != INPUT )
    852         CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr );
    853 }
    854 
    855 
    856 void CV_UndistortTest::run_func()
    857 {
    858     if (!useCPlus)
    859     {
    860         CvMat a = test_mat[INPUT][1], k = test_mat[INPUT][2];
    861         cvUndistort2( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &a, &k);
    862     }
    863     else
    864     {
    865         if (zero_distortion)
    866         {
    867             cv::undistort(input0,input_output,input1,cv::Mat());
    868         }
    869         else
    870         {
    871             cv::undistort(input0,input_output,input1,input2);
    872         }
    873     }
    874 }
    875 
    876 
    877 double CV_UndistortTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
    878 {
    879     int depth = test_mat[INPUT][0].depth();
    880     return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;
    881 }
    882 
    883 
    884 int CV_UndistortTest::prepare_test_case( int test_case_idx )
    885 {
    886     RNG& rng = ts->get_rng();
    887     int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
    888 
    889     const Mat& src = test_mat[INPUT][0];
    890     double k[4], a[9] = {0,0,0,0,0,0,0,0,1};
    891     double new_cam[9] = {0,0,0,0,0,0,0,0,1};
    892     double sz = MAX(src.rows, src.cols);
    893 
    894     Mat& _new_cam0 = test_mat[INPUT][3];
    895     Mat _new_cam(test_mat[INPUT][3].rows,test_mat[INPUT][3].cols,CV_64F,new_cam);
    896     Mat& _a0 = test_mat[INPUT][1];
    897     Mat _a(3,3,CV_64F,a);
    898     Mat& _k0 = test_mat[INPUT][2];
    899     Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k);
    900 
    901     if( code <= 0 )
    902         return code;
    903 
    904     double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;
    905     a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
    906     a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
    907     a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);
    908     a[4] = aspect_ratio*a[0];
    909     k[0] = cvtest::randReal(rng)*0.06 - 0.03;
    910     k[1] = cvtest::randReal(rng)*0.06 - 0.03;
    911     if( k[0]*k[1] > 0 )
    912         k[1] = -k[1];
    913     if( cvtest::randInt(rng)%4 != 0 )
    914     {
    915         k[2] = cvtest::randReal(rng)*0.004 - 0.002;
    916         k[3] = cvtest::randReal(rng)*0.004 - 0.002;
    917     }
    918     else
    919         k[2] = k[3] = 0;
    920 
    921     new_cam[0] = a[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[0]; //10%
    922     new_cam[4] = a[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[4]; //10%
    923     new_cam[2] = a[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].rows; //15%
    924     new_cam[5] = a[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].cols; //15%
    925 
    926     _a.convertTo(_a0, _a0.depth());
    927 
    928     zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true;
    929     _k.convertTo(_k0, _k0.depth());
    930 
    931     zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true;
    932     _new_cam.convertTo(_new_cam0, _new_cam0.depth());
    933 
    934     //Testing C++ code
    935     useCPlus = ((cvtest::randInt(rng) % 2)!=0);
    936     if (useCPlus)
    937     {
    938         input0 = test_mat[INPUT][0];
    939         input1 = test_mat[INPUT][1];
    940         input2 = test_mat[INPUT][2];
    941         input_new_cam = test_mat[INPUT][3];
    942     }
    943 
    944     return code;
    945 }
    946 
    947 
    948 void CV_UndistortTest::prepare_to_validation( int /*test_case_idx*/ )
    949 {
    950     if (useCPlus)
    951     {
    952         Mat& output = test_mat[INPUT_OUTPUT][0];
    953         input_output.convertTo(output, output.type());
    954     }
    955     Mat& src = test_mat[INPUT][0];
    956     Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
    957     Mat& dst0 = test_mat[INPUT_OUTPUT][0];
    958     Mat mapx, mapy;
    959     cvtest::initUndistortMap( test_mat[INPUT][1], test_mat[INPUT][2], dst.size(), mapx, mapy );
    960     Mat mask( dst.size(), CV_8U );
    961     test_remap( src, dst, mapx, mapy, &mask, interpolation );
    962     dst.setTo(Scalar::all(0), mask);
    963     dst0.setTo(Scalar::all(0), mask);
    964 }
    965 
    966 
    967 class CV_UndistortMapTest : public cvtest::ArrayTest
    968 {
    969 public:
    970     CV_UndistortMapTest();
    971 
    972 protected:
    973     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    974     void run_func();
    975     int prepare_test_case( int test_case_idx );
    976     void prepare_to_validation( int /*test_case_idx*/ );
    977     double get_success_error_level( int test_case_idx, int i, int j );
    978     void fill_array( int test_case_idx, int i, int j, Mat& arr );
    979 
    980 private:
    981     bool dualChannel;
    982 };
    983 
    984 
    985 CV_UndistortMapTest::CV_UndistortMapTest()
    986 {
    987     test_array[INPUT].push_back(NULL);
    988     test_array[INPUT].push_back(NULL);
    989     test_array[OUTPUT].push_back(NULL);
    990     test_array[OUTPUT].push_back(NULL);
    991     test_array[REF_OUTPUT].push_back(NULL);
    992     test_array[REF_OUTPUT].push_back(NULL);
    993 
    994     element_wise_relative_error = false;
    995 }
    996 
    997 
    998 void CV_UndistortMapTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    999 {
   1000     RNG& rng = ts->get_rng();
   1001     cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1002     int depth = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
   1003 
   1004     CvSize sz = sizes[OUTPUT][0];
   1005     types[INPUT][0] = types[INPUT][1] = depth;
   1006     dualChannel = cvtest::randInt(rng)%2 == 0;
   1007     types[OUTPUT][0] = types[OUTPUT][1] =
   1008         types[REF_OUTPUT][0] = types[REF_OUTPUT][1] = dualChannel ? CV_32FC2 : CV_32F;
   1009     sizes[INPUT][0] = cvSize(3,3);
   1010     sizes[INPUT][1] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);
   1011 
   1012     sz.width = MAX(sz.width,16);
   1013     sz.height = MAX(sz.height,16);
   1014     sizes[OUTPUT][0] = sizes[OUTPUT][1] =
   1015         sizes[REF_OUTPUT][0] = sizes[REF_OUTPUT][1] = sz;
   1016 }
   1017 
   1018 
   1019 void CV_UndistortMapTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
   1020 {
   1021     if( i != INPUT )
   1022         cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
   1023 }
   1024 
   1025 
   1026 void CV_UndistortMapTest::run_func()
   1027 {
   1028     CvMat a = test_mat[INPUT][0], k = test_mat[INPUT][1];
   1029 
   1030     if (!dualChannel )
   1031         cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], test_array[OUTPUT][1] );
   1032     else
   1033         cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], 0 );
   1034 }
   1035 
   1036 
   1037 double CV_UndistortMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
   1038 {
   1039     return 1e-3;
   1040 }
   1041 
   1042 
   1043 int CV_UndistortMapTest::prepare_test_case( int test_case_idx )
   1044 {
   1045     RNG& rng = ts->get_rng();
   1046     int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
   1047     const Mat& mapx = test_mat[OUTPUT][0];
   1048     double k[4], a[9] = {0,0,0,0,0,0,0,0,1};
   1049     double sz = MAX(mapx.rows, mapx.cols);
   1050     Mat& _a0 = test_mat[INPUT][0], &_k0 = test_mat[INPUT][1];
   1051     Mat _a(3,3,CV_64F,a);
   1052     Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k);
   1053 
   1054     if( code <= 0 )
   1055         return code;
   1056 
   1057     double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;
   1058     a[2] = (mapx.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
   1059     a[5] = (mapx.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
   1060     a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);
   1061     a[4] = aspect_ratio*a[0];
   1062     k[0] = cvtest::randReal(rng)*0.06 - 0.03;
   1063     k[1] = cvtest::randReal(rng)*0.06 - 0.03;
   1064     if( k[0]*k[1] > 0 )
   1065         k[1] = -k[1];
   1066     k[2] = cvtest::randReal(rng)*0.004 - 0.002;
   1067     k[3] = cvtest::randReal(rng)*0.004 - 0.002;
   1068 
   1069     _a.convertTo(_a0, _a0.depth());
   1070     _k.convertTo(_k0, _k0.depth());
   1071 
   1072     if (dualChannel)
   1073     {
   1074         test_mat[REF_OUTPUT][1] = Scalar::all(0);
   1075         test_mat[OUTPUT][1] = Scalar::all(0);
   1076     }
   1077 
   1078     return code;
   1079 }
   1080 
   1081 
   1082 void CV_UndistortMapTest::prepare_to_validation( int )
   1083 {
   1084     Mat mapx, mapy;
   1085     cvtest::initUndistortMap( test_mat[INPUT][0], test_mat[INPUT][1], test_mat[REF_OUTPUT][0].size(), mapx, mapy );
   1086     if( !dualChannel )
   1087     {
   1088         mapx.copyTo(test_mat[REF_OUTPUT][0]);
   1089         mapy.copyTo(test_mat[REF_OUTPUT][1]);
   1090     }
   1091     else
   1092     {
   1093         Mat p[2] = {mapx, mapy};
   1094         cv::merge(p, 2, test_mat[REF_OUTPUT][0]);
   1095     }
   1096 }
   1097 
   1098 ////////////////////////////// GetRectSubPix /////////////////////////////////
   1099 
   1100 static void
   1101 test_getQuadrangeSubPix( const Mat& src, Mat& dst, double* a )
   1102 {
   1103     int sstep = (int)(src.step / sizeof(float));
   1104     int scols = src.cols, srows = src.rows;
   1105 
   1106     CV_Assert( src.depth() == CV_32F && src.type() == dst.type() );
   1107 
   1108     int cn = dst.channels();
   1109 
   1110     for( int y = 0; y < dst.rows; y++ )
   1111         for( int x = 0; x < dst.cols; x++ )
   1112         {
   1113             float* d = dst.ptr<float>(y) + x*cn;
   1114             float sx = (float)(a[0]*x + a[1]*y + a[2]);
   1115             float sy = (float)(a[3]*x + a[4]*y + a[5]);
   1116             int ix = cvFloor(sx), iy = cvFloor(sy);
   1117             int dx = cn, dy = sstep;
   1118             const float* s;
   1119             sx -= ix; sy -= iy;
   1120 
   1121             if( (unsigned)ix >= (unsigned)(scols-1) )
   1122                 ix = ix < 0 ? 0 : scols - 1, sx = 0, dx = 0;
   1123             if( (unsigned)iy >= (unsigned)(srows-1) )
   1124                 iy = iy < 0 ? 0 : srows - 1, sy = 0, dy = 0;
   1125 
   1126             s = src.ptr<float>(iy) + ix*cn;
   1127             for( int k = 0; k < cn; k++, s++ )
   1128             {
   1129                 float t0 = s[0] + sx*(s[dx] - s[0]);
   1130                 float t1 = s[dy] + sx*(s[dy + dx] - s[dy]);
   1131                 d[k] = t0 + sy*(t1 - t0);
   1132             }
   1133         }
   1134 }
   1135 
   1136 
   1137 class CV_GetRectSubPixTest : public CV_ImgWarpBaseTest
   1138 {
   1139 public:
   1140     CV_GetRectSubPixTest();
   1141 
   1142 protected:
   1143     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   1144     void run_func();
   1145     int prepare_test_case( int test_case_idx );
   1146     void prepare_to_validation( int /*test_case_idx*/ );
   1147     double get_success_error_level( int test_case_idx, int i, int j );
   1148     void fill_array( int test_case_idx, int i, int j, Mat& arr );
   1149 
   1150     CvPoint2D32f center;
   1151     bool test_cpp;
   1152 };
   1153 
   1154 
   1155 CV_GetRectSubPixTest::CV_GetRectSubPixTest() : CV_ImgWarpBaseTest( false )
   1156 {
   1157     //spatial_scale_zoom = spatial_scale_decimate;
   1158     spatial_scale_decimate = spatial_scale_zoom;
   1159     test_cpp = false;
   1160 }
   1161 
   1162 
   1163 void CV_GetRectSubPixTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
   1164 {
   1165     RNG& rng = ts->get_rng();
   1166     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1167     int src_depth = cvtest::randInt(rng) % 2, dst_depth;
   1168     int cn = cvtest::randInt(rng) % 2 ? 3 : 1;
   1169     CvSize src_size, dst_size;
   1170 
   1171     dst_depth = src_depth = src_depth == 0 ? CV_8U : CV_32F;
   1172     if( src_depth < CV_32F && cvtest::randInt(rng) % 2 )
   1173         dst_depth = CV_32F;
   1174 
   1175     types[INPUT][0] = CV_MAKETYPE(src_depth,cn);
   1176     types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(dst_depth,cn);
   1177 
   1178     src_size = sizes[INPUT][0];
   1179     dst_size.width = cvRound(sqrt(cvtest::randReal(rng)*src_size.width) + 1);
   1180     dst_size.height = cvRound(sqrt(cvtest::randReal(rng)*src_size.height) + 1);
   1181     dst_size.width = MIN(dst_size.width,src_size.width);
   1182     dst_size.height = MIN(dst_size.width,src_size.height);
   1183     sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = dst_size;
   1184 
   1185     center.x = (float)(cvtest::randReal(rng)*src_size.width);
   1186     center.y = (float)(cvtest::randReal(rng)*src_size.height);
   1187     interpolation = CV_INTER_LINEAR;
   1188 
   1189     test_cpp = (cvtest::randInt(rng) & 256) == 0;
   1190 }
   1191 
   1192 
   1193 void CV_GetRectSubPixTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
   1194 {
   1195     if( i != INPUT )
   1196         CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr );
   1197 }
   1198 
   1199 
   1200 void CV_GetRectSubPixTest::run_func()
   1201 {
   1202     if(!test_cpp)
   1203         cvGetRectSubPix( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], center );
   1204     else
   1205     {
   1206         cv::Mat _out = cv::cvarrToMat(test_array[INPUT_OUTPUT][0]);
   1207         cv::getRectSubPix( cv::cvarrToMat(test_array[INPUT][0]), _out.size(), center, _out, _out.type());
   1208     }
   1209 }
   1210 
   1211 
   1212 double CV_GetRectSubPixTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
   1213 {
   1214     int in_depth = test_mat[INPUT][0].depth();
   1215     int out_depth = test_mat[INPUT_OUTPUT][0].depth();
   1216 
   1217     return in_depth >= CV_32F ? 1e-3 : out_depth >= CV_32F ? 1e-2 : 1;
   1218 }
   1219 
   1220 
   1221 int CV_GetRectSubPixTest::prepare_test_case( int test_case_idx )
   1222 {
   1223     return CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
   1224 }
   1225 
   1226 
   1227 void CV_GetRectSubPixTest::prepare_to_validation( int /*test_case_idx*/ )
   1228 {
   1229     Mat& src0 = test_mat[INPUT][0];
   1230     Mat& dst0 = test_mat[REF_INPUT_OUTPUT][0];
   1231     Mat src = src0, dst = dst0;
   1232     int ftype = CV_MAKETYPE(CV_32F,src0.channels());
   1233     double a[] = { 1, 0, center.x - dst.cols*0.5 + 0.5,
   1234                    0, 1, center.y - dst.rows*0.5 + 0.5 };
   1235     if( src.depth() != CV_32F )
   1236         src0.convertTo(src, CV_32F);
   1237 
   1238     if( dst.depth() != CV_32F )
   1239         dst.create(dst0.size(), ftype);
   1240 
   1241     test_getQuadrangeSubPix( src, dst, a );
   1242 
   1243     if( dst.data != dst0.data )
   1244         dst.convertTo(dst0, dst0.depth());
   1245 }
   1246 
   1247 
   1248 class CV_GetQuadSubPixTest : public CV_ImgWarpBaseTest
   1249 {
   1250 public:
   1251     CV_GetQuadSubPixTest();
   1252 
   1253 protected:
   1254     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   1255     void run_func();
   1256     int prepare_test_case( int test_case_idx );
   1257     void prepare_to_validation( int /*test_case_idx*/ );
   1258     double get_success_error_level( int test_case_idx, int i, int j );
   1259 };
   1260 
   1261 
   1262 CV_GetQuadSubPixTest::CV_GetQuadSubPixTest() : CV_ImgWarpBaseTest( true )
   1263 {
   1264     //spatial_scale_zoom = spatial_scale_decimate;
   1265     spatial_scale_decimate = spatial_scale_zoom;
   1266 }
   1267 
   1268 
   1269 void CV_GetQuadSubPixTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
   1270 {
   1271     int min_size = 4;
   1272     CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1273     CvSize sz = sizes[INPUT][0], dsz;
   1274     RNG& rng = ts->get_rng();
   1275     int msz, src_depth = cvtest::randInt(rng) % 2, dst_depth;
   1276     int cn = cvtest::randInt(rng) % 2 ? 3 : 1;
   1277 
   1278     dst_depth = src_depth = src_depth == 0 ? CV_8U : CV_32F;
   1279     if( src_depth < CV_32F && cvtest::randInt(rng) % 2 )
   1280         dst_depth = CV_32F;
   1281 
   1282     types[INPUT][0] = CV_MAKETYPE(src_depth,cn);
   1283     types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(dst_depth,cn);
   1284 
   1285     sz.width = MAX(sz.width,min_size);
   1286     sz.height = MAX(sz.height,min_size);
   1287     sizes[INPUT][0] = sz;
   1288     msz = MIN( sz.width, sz.height );
   1289 
   1290     dsz.width = cvRound(sqrt(cvtest::randReal(rng)*msz) + 1);
   1291     dsz.height = cvRound(sqrt(cvtest::randReal(rng)*msz) + 1);
   1292     dsz.width = MIN(dsz.width,msz);
   1293     dsz.height = MIN(dsz.width,msz);
   1294     dsz.width = MAX(dsz.width,min_size);
   1295     dsz.height = MAX(dsz.height,min_size);
   1296     sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = dsz;
   1297     sizes[INPUT][1] = cvSize( 3, 2 );
   1298 }
   1299 
   1300 
   1301 void CV_GetQuadSubPixTest::run_func()
   1302 {
   1303     CvMat mtx = test_mat[INPUT][1];
   1304     cvGetQuadrangleSubPix( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &mtx );
   1305 }
   1306 
   1307 
   1308 double CV_GetQuadSubPixTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
   1309 {
   1310     int in_depth = test_mat[INPUT][0].depth();
   1311     //int out_depth = test_mat[INPUT_OUTPUT][0].depth();
   1312 
   1313     return in_depth >= CV_32F ? 1e-2 : 4;
   1314 }
   1315 
   1316 
   1317 int CV_GetQuadSubPixTest::prepare_test_case( int test_case_idx )
   1318 {
   1319     RNG& rng = ts->get_rng();
   1320     int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
   1321     const Mat& src = test_mat[INPUT][0];
   1322     Mat& mat = test_mat[INPUT][1];
   1323     CvPoint2D32f center;
   1324     double scale, angle;
   1325 
   1326     if( code <= 0 )
   1327         return code;
   1328 
   1329     double a[6];
   1330     Mat A( 2, 3, CV_64FC1, a );
   1331 
   1332     center.x = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.cols);
   1333     center.y = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.rows);
   1334     angle = cvtest::randReal(rng)*360;
   1335     scale = cvtest::randReal(rng)*0.2 + 0.9;
   1336 
   1337     // y = Ax + b -> x = A^-1(y - b) = A^-1*y - A^-1*b
   1338     scale = 1./scale;
   1339     angle = angle*(CV_PI/180.);
   1340     a[0] = a[4] = cos(angle)*scale;
   1341     a[1] = sin(angle)*scale;
   1342     a[3] = -a[1];
   1343     a[2] = center.x - a[0]*center.x - a[1]*center.y;
   1344     a[5] = center.y - a[3]*center.x - a[4]*center.y;
   1345     A.convertTo( mat, mat.depth() );
   1346 
   1347     return code;
   1348 }
   1349 
   1350 
   1351 void CV_GetQuadSubPixTest::prepare_to_validation( int /*test_case_idx*/ )
   1352 {
   1353     Mat& src0 = test_mat[INPUT][0];
   1354     Mat& dst0 = test_mat[REF_INPUT_OUTPUT][0];
   1355     Mat src = src0, dst = dst0;
   1356     int ftype = CV_MAKETYPE(CV_32F,src0.channels());
   1357     double a[6], dx = (dst0.cols - 1)*0.5, dy = (dst0.rows - 1)*0.5;
   1358     Mat A( 2, 3, CV_64F, a );
   1359 
   1360     if( src.depth() != CV_32F )
   1361         src0.convertTo(src, CV_32F);
   1362 
   1363     if( dst.depth() != CV_32F )
   1364         dst.create(dst0.size(), ftype);
   1365 
   1366     test_mat[INPUT][1].convertTo( A, CV_64F );
   1367     a[2] -= a[0]*dx + a[1]*dy;
   1368     a[5] -= a[3]*dx + a[4]*dy;
   1369     test_getQuadrangeSubPix( src, dst, a );
   1370 
   1371     if( dst.data != dst0.data )
   1372         dst.convertTo(dst0, dst0.depth());
   1373 }
   1374 
   1375 TEST(Imgproc_cvWarpAffine, regression)
   1376 {
   1377     IplImage* src = cvCreateImage(cvSize(100, 100), IPL_DEPTH_8U, 1);
   1378     IplImage* dst = cvCreateImage(cvSize(100, 100), IPL_DEPTH_8U, 1);
   1379 
   1380     float m[6];
   1381     CvMat M = cvMat( 2, 3, CV_32F, m );
   1382     int w = src->width;
   1383     int h = src->height;
   1384     cv2DRotationMatrix(cvPoint2D32f(w*0.5f, h*0.5f), 45.0, 1.0, &M);
   1385     cvWarpAffine(src, dst, &M);
   1386 }
   1387 
   1388 TEST(Imgproc_fitLine_vector_3d, regression)
   1389 {
   1390     std::vector<Point3f> points_vector;
   1391 
   1392     Point3f p21(4,4,4);
   1393     Point3f p22(8,8,8);
   1394 
   1395     points_vector.push_back(p21);
   1396     points_vector.push_back(p22);
   1397 
   1398     std::vector<float> line;
   1399 
   1400     cv::fitLine(points_vector, line, CV_DIST_L2, 0 ,0 ,0);
   1401 
   1402     ASSERT_EQ(line.size(), (size_t)6);
   1403 
   1404 }
   1405 
   1406 TEST(Imgproc_fitLine_vector_2d, regression)
   1407 {
   1408     std::vector<Point2f> points_vector;
   1409 
   1410     Point2f p21(4,4);
   1411     Point2f p22(8,8);
   1412     Point2f p23(16,16);
   1413 
   1414     points_vector.push_back(p21);
   1415     points_vector.push_back(p22);
   1416     points_vector.push_back(p23);
   1417 
   1418     std::vector<float> line;
   1419 
   1420     cv::fitLine(points_vector, line, CV_DIST_L2, 0 ,0 ,0);
   1421 
   1422     ASSERT_EQ(line.size(), (size_t)4);
   1423 }
   1424 
   1425 TEST(Imgproc_fitLine_Mat_2dC2, regression)
   1426 {
   1427     cv::Mat mat1 = Mat::zeros(3, 1, CV_32SC2);
   1428     std::vector<float> line1;
   1429 
   1430     cv::fitLine(mat1, line1, CV_DIST_L2, 0 ,0 ,0);
   1431 
   1432     ASSERT_EQ(line1.size(), (size_t)4);
   1433 }
   1434 
   1435 TEST(Imgproc_fitLine_Mat_2dC1, regression)
   1436 {
   1437     cv::Matx<int, 3, 2> mat2;
   1438     std::vector<float> line2;
   1439 
   1440     cv::fitLine(mat2, line2, CV_DIST_L2, 0 ,0 ,0);
   1441 
   1442     ASSERT_EQ(line2.size(), (size_t)4);
   1443 }
   1444 
   1445 TEST(Imgproc_fitLine_Mat_3dC3, regression)
   1446 {
   1447     cv::Mat mat1 = Mat::zeros(2, 1, CV_32SC3);
   1448     std::vector<float> line1;
   1449 
   1450     cv::fitLine(mat1, line1, CV_DIST_L2, 0 ,0 ,0);
   1451 
   1452     ASSERT_EQ(line1.size(), (size_t)6);
   1453 }
   1454 
   1455 TEST(Imgproc_fitLine_Mat_3dC1, regression)
   1456 {
   1457     cv::Mat mat2 = Mat::zeros(2, 3, CV_32SC1);
   1458     std::vector<float> line2;
   1459 
   1460     cv::fitLine(mat2, line2, CV_DIST_L2, 0 ,0 ,0);
   1461 
   1462     ASSERT_EQ(line2.size(), (size_t)6);
   1463 }
   1464 
   1465 TEST(Imgproc_resize_area, regression)
   1466 {
   1467     static ushort input_data[16 * 16] = {
   1468          90,  94,  80,   3, 231,   2, 186, 245, 188, 165,  10,  19, 201, 169,   8, 228,
   1469          86,   5, 203, 120, 136, 185,  24,  94,  81, 150, 163, 137,  88, 105, 132, 132,
   1470         236,  48, 250, 218,  19,  52,  54, 221, 159, 112,  45,  11, 152, 153, 112, 134,
   1471          78, 133, 136,  83,  65,  76,  82, 250,   9, 235, 148,  26, 236, 179, 200,  50,
   1472          99,  51, 103, 142, 201,  65, 176,  33,  49, 226, 177, 109,  46,  21,  67, 130,
   1473          54, 125, 107, 154, 145,  51, 199, 189, 161, 142, 231, 240, 139, 162, 240,  22,
   1474         231,  86,  79, 106,  92,  47, 146, 156,  36, 207,  71,  33,   2, 244, 221,  71,
   1475          44, 127,  71, 177,  75, 126,  68, 119, 200, 129, 191, 251,   6, 236, 247,  6,
   1476         133, 175,  56, 239, 147, 221, 243, 154, 242,  82, 106,  99,  77, 158,  60, 229,
   1477           2,  42,  24, 174,  27, 198,  14, 204, 246, 251, 141,  31, 114, 163,  29, 147,
   1478         121,  53,  74,  31, 147, 189,  42,  98, 202,  17, 228, 123, 209,  40,  77,  49,
   1479         112, 203,  30,  12, 205,  25,  19, 106, 145, 185, 163, 201, 237, 223, 247,  38,
   1480          33, 105, 243, 117,  92, 179, 204, 248, 160,  90,  73, 126,   2,  41, 213, 204,
   1481           6, 124, 195, 201, 230, 187, 210, 167,  48,  79, 123, 159, 145, 218, 105, 209,
   1482         240, 152, 136, 235, 235, 164, 157,  9,  152,  38,  27, 209, 120,  77, 238, 196,
   1483         240, 233,  10, 241,  90,  67,  12, 79,    0,  43,  58,  27,  83, 199, 190, 182};
   1484 
   1485     static ushort expected_data[5 * 5] = {
   1486         120, 100, 151, 101, 130,
   1487         106, 115, 141, 130, 127,
   1488          91, 136, 170, 114, 140,
   1489         104, 122, 131, 147, 133,
   1490         161, 163,  70, 107, 182
   1491     };
   1492 
   1493     cv::Mat src(16, 16, CV_16UC1, input_data);
   1494     cv::Mat expected(5, 5, CV_16UC1, expected_data);
   1495     cv::Mat actual(expected.size(), expected.type());
   1496 
   1497     cv::resize(src, actual, cv::Size(), 0.3, 0.3, INTER_AREA);
   1498 
   1499     ASSERT_EQ(actual.type(), expected.type());
   1500     ASSERT_EQ(actual.size(), expected.size());
   1501 
   1502     Mat diff;
   1503     absdiff(actual, expected, diff);
   1504 
   1505     Mat one_channel_diff = diff; //.reshape(1);
   1506 
   1507     float elem_diff = 1.0f;
   1508     Size dsize = actual.size();
   1509     bool next = true;
   1510     for (int dy = 0; dy < dsize.height && next; ++dy)
   1511     {
   1512         ushort* eD = expected.ptr<ushort>(dy);
   1513         ushort* aD = actual.ptr<ushort>(dy);
   1514 
   1515         for (int dx = 0; dx < dsize.width && next; ++dx)
   1516             if (fabs(static_cast<float>(aD[dx] - eD[dx])) > elem_diff)
   1517             {
   1518                 cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Inf norm: %f\n", static_cast<float>(norm(actual, expected, NORM_INF)));
   1519                 cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Error in : (%d, %d)\n", dx, dy);
   1520 
   1521                 const int radius = 3;
   1522                 int rmin = MAX(dy - radius, 0), rmax = MIN(dy + radius, dsize.height);
   1523                 int cmin = MAX(dx - radius, 0), cmax = MIN(dx + radius, dsize.width);
   1524 
   1525                 std::cout << "Abs diff:" << std::endl << diff << std::endl;
   1526                 std::cout << "actual result:\n" << actual(Range(rmin, rmax), Range(cmin, cmax)) << std::endl;
   1527                 std::cout << "expected result:\n" << expected(Range(rmin, rmax), Range(cmin, cmax)) << std::endl;
   1528 
   1529                 next = false;
   1530             }
   1531     }
   1532 
   1533     ASSERT_EQ(cvtest::norm(one_channel_diff, cv::NORM_INF), 0);
   1534 }
   1535 
   1536 
   1537 //////////////////////////////////////////////////////////////////////////
   1538 
   1539 TEST(Imgproc_Resize, accuracy) { CV_ResizeTest test; test.safe_run(); }
   1540 TEST(Imgproc_WarpAffine, accuracy) { CV_WarpAffineTest test; test.safe_run(); }
   1541 TEST(Imgproc_WarpPerspective, accuracy) { CV_WarpPerspectiveTest test; test.safe_run(); }
   1542 TEST(Imgproc_Remap, accuracy) { CV_RemapTest test; test.safe_run(); }
   1543 TEST(Imgproc_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); }
   1544 TEST(Imgproc_InitUndistortMap, accuracy) { CV_UndistortMapTest test; test.safe_run(); }
   1545 TEST(Imgproc_GetRectSubPix, accuracy) { CV_GetRectSubPixTest test; test.safe_run(); }
   1546 TEST(Imgproc_GetQuadSubPix, accuracy) { CV_GetQuadSubPixTest test; test.safe_run(); }
   1547 
   1548 //////////////////////////////////////////////////////////////////////////
   1549 
   1550 template <typename T, typename WT>
   1551 struct IntCast
   1552 {
   1553     T operator() (WT val) const
   1554     {
   1555         return cv::saturate_cast<T>(val >> 2);
   1556     }
   1557 };
   1558 
   1559 template <typename T, typename WT>
   1560 struct FltCast
   1561 {
   1562     T operator() (WT val) const
   1563     {
   1564         return cv::saturate_cast<T>(val * 0.25);
   1565     }
   1566 };
   1567 
   1568 template <typename T, typename WT, int one, typename CastOp>
   1569 void resizeArea(const cv::Mat & src, cv::Mat & dst)
   1570 {
   1571     int cn = src.channels();
   1572     CastOp castOp;
   1573 
   1574     for (int y = 0; y < dst.rows; ++y)
   1575     {
   1576         const T * sptr0 = src.ptr<T>(y << 1);
   1577         const T * sptr1 = src.ptr<T>((y << 1) + 1);
   1578         T * dptr = dst.ptr<T>(y);
   1579 
   1580         for (int x = 0; x < dst.cols * cn; x += cn)
   1581         {
   1582             int x1 = x << 1;
   1583 
   1584             for (int c = 0; c < cn; ++c)
   1585             {
   1586                 WT sum = WT(sptr0[x1 + c]) + WT(sptr0[x1 + c + cn]);
   1587                 sum += WT(sptr1[x1 + c]) + WT(sptr1[x1 + c + cn]) + (WT)(one);
   1588 
   1589                 dptr[x + c] = castOp(sum);
   1590             }
   1591         }
   1592     }
   1593 }
   1594 
   1595 TEST(Resize, Area_half)
   1596 {
   1597     const int size = 1000;
   1598     int types[] = { CV_8UC1, CV_8UC4,
   1599                     CV_16UC1, CV_16UC4,
   1600                     CV_16SC1, CV_16SC3, CV_16SC4,
   1601                     CV_32FC1, CV_32FC4 };
   1602 
   1603     cv::RNG rng(17);
   1604 
   1605     for (int i = 0, _size = sizeof(types) / sizeof(types[0]); i < _size; ++i)
   1606     {
   1607         int type = types[i], depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
   1608         const float eps = depth <= CV_32S ? 0 : 7e-5f;
   1609 
   1610         SCOPED_TRACE(depth);
   1611         SCOPED_TRACE(cn);
   1612 
   1613         cv::Mat src(size, size, type), dst_actual(size >> 1, size >> 1, type),
   1614             dst_reference(size >> 1, size >> 1, type);
   1615 
   1616         rng.fill(src, cv::RNG::UNIFORM, -1000, 1000, true);
   1617 
   1618         if (depth == CV_8U)
   1619             resizeArea<uchar, ushort, 2, IntCast<uchar, ushort> >(src, dst_reference);
   1620         else if (depth == CV_16U)
   1621             resizeArea<ushort, uint, 2, IntCast<ushort, uint> >(src, dst_reference);
   1622         else if (depth == CV_16S)
   1623             resizeArea<short, int, 2, IntCast<short, int> >(src, dst_reference);
   1624         else if (depth == CV_32F)
   1625             resizeArea<float, float, 0, FltCast<float, float> >(src, dst_reference);
   1626         else
   1627             CV_Assert(0);
   1628 
   1629         cv::resize(src, dst_actual, dst_actual.size(), 0, 0, cv::INTER_AREA);
   1630 
   1631         ASSERT_GE(eps, cvtest::norm(dst_reference, dst_actual, cv::NORM_INF));
   1632     }
   1633 }
   1634 
   1635 TEST(Imgproc_Warp, multichannel)
   1636 {
   1637     RNG& rng = theRNG();
   1638     for( int iter = 0; iter < 30; iter++ )
   1639     {
   1640         int width = rng.uniform(3, 333);
   1641         int height = rng.uniform(3, 333);
   1642         int cn = rng.uniform(1, 10);
   1643         Mat src(height, width, CV_8UC(cn)), dst;
   1644         //randu(src, 0, 256);
   1645         src.setTo(0.);
   1646 
   1647         Mat rot = getRotationMatrix2D(Point2f(0.f, 0.f), 1, 1);
   1648         warpAffine(src, dst, rot, src.size());
   1649         ASSERT_EQ(0.0, norm(dst, NORM_INF));
   1650         Mat rot2 = Mat::eye(3, 3, rot.type());
   1651         rot.copyTo(rot2.rowRange(0, 2));
   1652         warpPerspective(src, dst, rot2, src.size());
   1653         ASSERT_EQ(0.0, norm(dst, NORM_INF));
   1654     }
   1655 }
   1656 
   1657 TEST(Imgproc_GetAffineTransform, singularity)
   1658 {
   1659     Point2f A_sample[3];
   1660     A_sample[0] = Point2f(8.f, 9.f);
   1661     A_sample[1] = Point2f(40.f, 41.f);
   1662     A_sample[2] = Point2f(47.f, 48.f);
   1663     Point2f B_sample[3];
   1664     B_sample[0] = Point2f(7.37465f, 11.8295f);
   1665     B_sample[1] = Point2f(15.0113f, 12.8994f);
   1666     B_sample[2] = Point2f(38.9943f, 9.56297f);
   1667     Mat trans = getAffineTransform(A_sample, B_sample);
   1668     ASSERT_EQ(0.0, norm(trans, NORM_INF));
   1669 }
   1670 
   1671 TEST(Imgproc_Remap, DISABLED_memleak)
   1672 {
   1673     Mat src;
   1674     const int N = 400;
   1675     src.create(N, N, CV_8U);
   1676     randu(src, 0, 256);
   1677     Mat map_x, map_y, dst;
   1678     dst.create( src.size(), src.type() );
   1679     map_x.create( src.size(), CV_32FC1 );
   1680     map_y.create( src.size(), CV_32FC1 );
   1681     randu(map_x, 0., N+0.);
   1682     randu(map_y, 0., N+0.);
   1683 
   1684     for( int iter = 0; iter < 10000; iter++ )
   1685     {
   1686         if(iter % 100 == 0)
   1687         {
   1688             putchar('.');
   1689             fflush(stdout);
   1690         }
   1691         remap(src, dst, map_x, map_y, CV_INTER_LINEAR);
   1692     }
   1693 }
   1694 
   1695 /* End of file. */
   1696