• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CV_ImgWarpBaseTest(bool warp_matrix)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 
read_params(CvFileStorage * fs)80 int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs )
81 {
82     int code = cvtest::ArrayTest::read_params( fs );
83     return code;
84 }
85 
86 
get_minmax_bounds(int i,int j,int type,Scalar & low,Scalar & high)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 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
fill_array(int test_case_idx,int i,int j,Mat & arr)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 
prepare_test_case(int test_case_idx)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 
CV_ResizeTest()217 CV_ResizeTest::CV_ResizeTest() : CV_ImgWarpBaseTest( false )
218 {
219 }
220 
221 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
run_func()261 void CV_ResizeTest::run_func()
262 {
263     cvResize( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], interpolation );
264 }
265 
266 
get_success_error_level(int,int,int)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 
prepare_to_validation(int)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 
test_remap(const Mat & src,Mat & dst,const Mat & mapx,const Mat & mapy,Mat * mask=0,int interpolation=CV_INTER_LINEAR)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 
CV_WarpAffineTest()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 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
run_func()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 
get_success_error_level(int,int,int)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 
prepare_test_case(int test_case_idx)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 
prepare_to_validation(int)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 
CV_WarpPerspectiveTest()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 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
run_func()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 
get_success_error_level(int,int,int)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 
prepare_test_case(int test_case_idx)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 
prepare_to_validation(int)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 
CV_RemapTest()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 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
fill_array(int test_case_idx,int i,int j,Mat & arr)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 
run_func()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 
get_success_error_level(int,int,int)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 
prepare_test_case(int test_case_idx)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 
prepare_to_validation(int)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 
CV_UndistortTest()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 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
fill_array(int test_case_idx,int i,int j,Mat & arr)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 
run_func()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 
get_success_error_level(int,int,int)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 
prepare_test_case(int test_case_idx)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 
prepare_to_validation(int)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 
CV_UndistortMapTest()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 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
fill_array(int test_case_idx,int i,int j,Mat & arr)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 
run_func()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 
get_success_error_level(int,int,int)1037 double CV_UndistortMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
1038 {
1039     return 1e-3;
1040 }
1041 
1042 
prepare_test_case(int test_case_idx)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 
prepare_to_validation(int)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
test_getQuadrangeSubPix(const Mat & src,Mat & dst,double * a)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 
CV_GetRectSubPixTest()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 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
fill_array(int test_case_idx,int i,int j,Mat & arr)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 
run_func()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 
get_success_error_level(int,int,int)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 
prepare_test_case(int test_case_idx)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 
prepare_to_validation(int)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 
CV_GetQuadSubPixTest()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 
get_test_array_types_and_sizes(int test_case_idx,vector<vector<Size>> & sizes,vector<vector<int>> & types)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 
run_func()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 
get_success_error_level(int,int,int)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 
prepare_test_case(int test_case_idx)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 
prepare_to_validation(int)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 
TEST(Imgproc_cvWarpAffine,regression)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 
TEST(Imgproc_fitLine_vector_3d,regression)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 
TEST(Imgproc_fitLine_vector_2d,regression)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 
TEST(Imgproc_fitLine_Mat_2dC2,regression)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 
TEST(Imgproc_fitLine_Mat_2dC1,regression)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 
TEST(Imgproc_fitLine_Mat_3dC3,regression)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 
TEST(Imgproc_fitLine_Mat_3dC1,regression)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 
TEST(Imgproc_resize_area,regression)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 
TEST(Imgproc_Resize,accuracy)1539 TEST(Imgproc_Resize, accuracy) { CV_ResizeTest test; test.safe_run(); }
TEST(Imgproc_WarpAffine,accuracy)1540 TEST(Imgproc_WarpAffine, accuracy) { CV_WarpAffineTest test; test.safe_run(); }
TEST(Imgproc_WarpPerspective,accuracy)1541 TEST(Imgproc_WarpPerspective, accuracy) { CV_WarpPerspectiveTest test; test.safe_run(); }
TEST(Imgproc_Remap,accuracy)1542 TEST(Imgproc_Remap, accuracy) { CV_RemapTest test; test.safe_run(); }
TEST(Imgproc_Undistort,accuracy)1543 TEST(Imgproc_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); }
TEST(Imgproc_InitUndistortMap,accuracy)1544 TEST(Imgproc_InitUndistortMap, accuracy) { CV_UndistortMapTest test; test.safe_run(); }
TEST(Imgproc_GetRectSubPix,accuracy)1545 TEST(Imgproc_GetRectSubPix, accuracy) { CV_GetRectSubPixTest test; test.safe_run(); }
TEST(Imgproc_GetQuadSubPix,accuracy)1546 TEST(Imgproc_GetQuadSubPix, accuracy) { CV_GetQuadSubPixTest test; test.safe_run(); }
1547 
1548 //////////////////////////////////////////////////////////////////////////
1549 
1550 template <typename T, typename WT>
1551 struct IntCast
1552 {
operator ()IntCast1553     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 {
operator ()FltCast1562     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>
resizeArea(const cv::Mat & src,cv::Mat & dst)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 
TEST(Resize,Area_half)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 
TEST(Imgproc_Warp,multichannel)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 
TEST(Imgproc_GetAffineTransform,singularity)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 
TEST(Imgproc_Remap,DISABLED_memleak)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