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 "precomp.hpp" 43#include "opencv2/core/core_c.h" 44 45namespace cvtest 46{ 47 48static const int default_test_case_count = 500; 49static const int default_max_log_array_size = 9; 50 51ArrayTest::ArrayTest() 52{ 53 test_case_count = default_test_case_count; 54 55 iplimage_allowed = true; 56 cvmat_allowed = true; 57 optional_mask = false; 58 min_log_array_size = 0; 59 max_log_array_size = default_max_log_array_size; 60 element_wise_relative_error = true; 61 62 test_array.resize(MAX_ARR); 63} 64 65 66ArrayTest::~ArrayTest() 67{ 68 clear(); 69} 70 71 72void ArrayTest::clear() 73{ 74 for( size_t i = 0; i < test_array.size(); i++ ) 75 { 76 for( size_t j = 0; j < test_array[i].size(); j++ ) 77 cvRelease( &test_array[i][j] ); 78 } 79 BaseTest::clear(); 80} 81 82 83int ArrayTest::read_params( CvFileStorage* fs ) 84{ 85 int code = BaseTest::read_params( fs ); 86 if( code < 0 ) 87 return code; 88 89 min_log_array_size = cvReadInt( find_param( fs, "min_log_array_size" ), min_log_array_size ); 90 max_log_array_size = cvReadInt( find_param( fs, "max_log_array_size" ), max_log_array_size ); 91 test_case_count = cvReadInt( find_param( fs, "test_case_count" ), test_case_count ); 92 test_case_count = cvRound( test_case_count*ts->get_test_case_count_scale() ); 93 94 min_log_array_size = clipInt( min_log_array_size, 0, 20 ); 95 max_log_array_size = clipInt( max_log_array_size, min_log_array_size, 20 ); 96 test_case_count = clipInt( test_case_count, 0, 100000 ); 97 98 return code; 99} 100 101 102void ArrayTest::get_test_array_types_and_sizes( int /*test_case_idx*/, vector<vector<Size> >& sizes, vector<vector<int> >& types ) 103{ 104 RNG& rng = ts->get_rng(); 105 Size size; 106 double val; 107 size_t i, j; 108 109 val = randReal(rng) * (max_log_array_size - min_log_array_size) + min_log_array_size; 110 size.width = cvRound( exp(val*CV_LOG2) ); 111 val = randReal(rng) * (max_log_array_size - min_log_array_size) + min_log_array_size; 112 size.height = cvRound( exp(val*CV_LOG2) ); 113 114 for( i = 0; i < test_array.size(); i++ ) 115 { 116 size_t sizei = test_array[i].size(); 117 for( j = 0; j < sizei; j++ ) 118 { 119 sizes[i][j] = size; 120 types[i][j] = CV_8UC1; 121 } 122 } 123} 124 125 126static const unsigned int icvTsTypeToDepth[] = 127{ 128 IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, 129 IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F 130}; 131 132 133int ArrayTest::prepare_test_case( int test_case_idx ) 134{ 135 int code = 1; 136 size_t max_arr = test_array.size(); 137 vector<vector<Size> > sizes(max_arr); 138 vector<vector<Size> > whole_sizes(max_arr); 139 vector<vector<int> > types(max_arr); 140 size_t i, j; 141 RNG& rng = ts->get_rng(); 142 bool is_image = false; 143 144 for( i = 0; i < max_arr; i++ ) 145 { 146 size_t sizei = std::max(test_array[i].size(), (size_t)1); 147 sizes[i].resize(sizei); 148 types[i].resize(sizei); 149 whole_sizes[i].resize(sizei); 150 } 151 152 get_test_array_types_and_sizes( test_case_idx, sizes, types ); 153 154 for( i = 0; i < max_arr; i++ ) 155 { 156 size_t sizei = test_array[i].size(); 157 for( j = 0; j < sizei; j++ ) 158 { 159 unsigned t = randInt(rng); 160 bool create_mask = true, use_roi = false; 161 CvSize size = sizes[i][j], whole_size = size; 162 CvRect roi; 163 164 is_image = !cvmat_allowed ? true : iplimage_allowed ? (t & 1) != 0 : false; 165 create_mask = (t & 6) == 0; // ~ each of 3 tests will use mask 166 use_roi = (t & 8) != 0; 167 if( use_roi ) 168 { 169 whole_size.width += randInt(rng) % 10; 170 whole_size.height += randInt(rng) % 10; 171 } 172 173 cvRelease( &test_array[i][j] ); 174 if( size.width > 0 && size.height > 0 && 175 types[i][j] >= 0 && (i != MASK || create_mask) ) 176 { 177 if( use_roi ) 178 { 179 roi.width = size.width; 180 roi.height = size.height; 181 if( whole_size.width > size.width ) 182 roi.x = randInt(rng) % (whole_size.width - size.width); 183 184 if( whole_size.height > size.height ) 185 roi.y = randInt(rng) % (whole_size.height - size.height); 186 } 187 188 if( is_image ) 189 { 190 test_array[i][j] = cvCreateImage( whole_size, 191 icvTsTypeToDepth[CV_MAT_DEPTH(types[i][j])], CV_MAT_CN(types[i][j]) ); 192 if( use_roi ) 193 cvSetImageROI( (IplImage*)test_array[i][j], roi ); 194 } 195 else 196 { 197 test_array[i][j] = cvCreateMat( whole_size.height, whole_size.width, types[i][j] ); 198 if( use_roi ) 199 { 200 CvMat submat, *mat = (CvMat*)test_array[i][j]; 201 cvGetSubRect( test_array[i][j], &submat, roi ); 202 submat.refcount = mat->refcount; 203 *mat = submat; 204 } 205 } 206 } 207 } 208 } 209 210 test_mat.resize(test_array.size()); 211 for( i = 0; i < max_arr; i++ ) 212 { 213 size_t sizei = test_array[i].size(); 214 test_mat[i].resize(sizei); 215 for( j = 0; j < sizei; j++ ) 216 { 217 CvArr* arr = test_array[i][j]; 218 test_mat[i][j] = cv::cvarrToMat(arr); 219 if( !test_mat[i][j].empty() ) 220 fill_array( test_case_idx, (int)i, (int)j, test_mat[i][j] ); 221 } 222 } 223 224 return code; 225} 226 227 228void ArrayTest::get_minmax_bounds( int i, int /*j*/, int type, Scalar& low, Scalar& high ) 229{ 230 double l, u; 231 int depth = CV_MAT_DEPTH(type); 232 233 if( i == MASK ) 234 { 235 l = -2; 236 u = 2; 237 } 238 else if( depth < CV_32S ) 239 { 240 l = getMinVal(type); 241 u = getMaxVal(type); 242 } 243 else 244 { 245 u = depth == CV_32S ? 1000000 : 1000.; 246 l = -u; 247 } 248 249 low = Scalar::all(l); 250 high = Scalar::all(u); 251} 252 253 254void ArrayTest::fill_array( int /*test_case_idx*/, int i, int j, Mat& arr ) 255{ 256 if( i == REF_INPUT_OUTPUT ) 257 cvtest::copy( test_mat[INPUT_OUTPUT][j], arr, Mat() ); 258 else if( i == INPUT || i == INPUT_OUTPUT || i == MASK ) 259 { 260 Scalar low, high; 261 262 get_minmax_bounds( i, j, arr.type(), low, high ); 263 randUni( ts->get_rng(), arr, low, high ); 264 } 265} 266 267 268double ArrayTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) 269{ 270 int elem_depth = CV_MAT_DEPTH(cvGetElemType(test_array[i][j])); 271 assert( i == OUTPUT || i == INPUT_OUTPUT ); 272 return elem_depth < CV_32F ? 0 : elem_depth == CV_32F ? FLT_EPSILON*100: DBL_EPSILON*5000; 273} 274 275 276void ArrayTest::prepare_to_validation( int /*test_case_idx*/ ) 277{ 278 assert(0); 279} 280 281 282int ArrayTest::validate_test_results( int test_case_idx ) 283{ 284 static const char* arr_names[] = { "input", "input/output", "output", 285 "ref input/output", "ref output", 286 "temporary", "mask" }; 287 size_t i, j; 288 prepare_to_validation( test_case_idx ); 289 290 for( i = 0; i < 2; i++ ) 291 { 292 int i0 = i == 0 ? OUTPUT : INPUT_OUTPUT; 293 int i1 = i == 0 ? REF_OUTPUT : REF_INPUT_OUTPUT; 294 size_t sizei = test_array[i0].size(); 295 296 assert( sizei == test_array[i1].size() ); 297 for( j = 0; j < sizei; j++ ) 298 { 299 double err_level; 300 int code; 301 302 if( !test_array[i1][j] ) 303 continue; 304 305 err_level = get_success_error_level( test_case_idx, i0, (int)j ); 306 code = cmpEps2(ts, test_mat[i0][j], test_mat[i1][j], err_level, element_wise_relative_error, arr_names[i0]); 307 308 if (code == 0) continue; 309 310 for( i0 = 0; i0 < (int)test_array.size(); i0++ ) 311 { 312 size_t sizei0 = test_array[i0].size(); 313 if( i0 == REF_INPUT_OUTPUT || i0 == OUTPUT || i0 == TEMP ) 314 continue; 315 for( i1 = 0; i1 < (int)sizei0; i1++ ) 316 { 317 const Mat& arr = test_mat[i0][i1]; 318 if( !arr.empty() ) 319 { 320 string sizestr = vec2str(", ", &arr.size[0], arr.dims); 321 ts->printf( TS::LOG, "%s array %d type=%sC%d, size=(%s)\n", 322 arr_names[i0], i1, getTypeName(arr.depth()), 323 arr.channels(), sizestr.c_str() ); 324 } 325 } 326 } 327 ts->set_failed_test_info( code ); 328 return code; 329 } 330 } 331 332 return 0; 333} 334 335} 336 337/* End of file. */ 338