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 "_cxcore.h" 43 #include <float.h> 44 45 /****************************************************************************************\ 46 * Mean value over the region * 47 \****************************************************************************************/ 48 49 #define ICV_MEAN_CASE_C1( len ) \ 50 for( ; x <= (len) - 2; x += 2 ) \ 51 { \ 52 if( mask[x] ) \ 53 s0 += src[x], pix++; \ 54 if( mask[x+1] ) \ 55 s0 += src[x+1], pix++; \ 56 } \ 57 \ 58 for( ; x < (len); x++ ) \ 59 if( mask[x] ) \ 60 s0 += src[x], pix++ 61 62 63 #define ICV_MEAN_CASE_C2( len ) \ 64 for( ; x < (len); x++ ) \ 65 if( mask[x] ) \ 66 { \ 67 s0 += src[x*2]; \ 68 s1 += src[x*2+1]; \ 69 pix++; \ 70 } 71 72 73 #define ICV_MEAN_CASE_C3( len ) \ 74 for( ; x < (len); x++ ) \ 75 if( mask[x] ) \ 76 { \ 77 s0 += src[x*3]; \ 78 s1 += src[x*3+1]; \ 79 s2 += src[x*3+2]; \ 80 pix++; \ 81 } 82 83 84 #define ICV_MEAN_CASE_C4( len ) \ 85 for( ; x < (len); x++ ) \ 86 if( mask[x] ) \ 87 { \ 88 s0 += src[x*4]; \ 89 s1 += src[x*4+1]; \ 90 s2 += src[x*4+2]; \ 91 s3 += src[x*4+3]; \ 92 pix++; \ 93 } 94 95 96 #define ICV_MEAN_COI_CASE( len, cn ) \ 97 for( ; x <= (len) - 2; x += 2 ) \ 98 { \ 99 if( mask[x] ) \ 100 s0 += src[x*(cn)], pix++; \ 101 if( mask[x+1] ) \ 102 s0+=src[(x+1)*(cn)], pix++; \ 103 } \ 104 \ 105 for( ; x < (len); x++ ) \ 106 if( mask[x] ) \ 107 s0 += src[x*(cn)], pix++; 108 109 110 ////////////////////////////////////// entry macros ////////////////////////////////////// 111 112 #define ICV_MEAN_ENTRY_COMMON() \ 113 int pix = 0; \ 114 step /= sizeof(src[0]) 115 116 #define ICV_MEAN_ENTRY_C1( sumtype ) \ 117 sumtype s0 = 0; \ 118 ICV_MEAN_ENTRY_COMMON() 119 120 #define ICV_MEAN_ENTRY_C2( sumtype ) \ 121 sumtype s0 = 0, s1 = 0; \ 122 ICV_MEAN_ENTRY_COMMON() 123 124 #define ICV_MEAN_ENTRY_C3( sumtype ) \ 125 sumtype s0 = 0, s1 = 0, s2 = 0; \ 126 ICV_MEAN_ENTRY_COMMON() 127 128 #define ICV_MEAN_ENTRY_C4( sumtype ) \ 129 sumtype s0 = 0, s1 = 0, s2 = 0, s3 = 0; \ 130 ICV_MEAN_ENTRY_COMMON() 131 132 133 #define ICV_MEAN_ENTRY_BLOCK_COMMON( block_size ) \ 134 int remaining = block_size; \ 135 ICV_MEAN_ENTRY_COMMON() 136 137 #define ICV_MEAN_ENTRY_BLOCK_C1( sumtype, worktype, block_size )\ 138 sumtype sum0 = 0; \ 139 worktype s0 = 0; \ 140 ICV_MEAN_ENTRY_BLOCK_COMMON( block_size ) 141 142 #define ICV_MEAN_ENTRY_BLOCK_C2( sumtype, worktype, block_size )\ 143 sumtype sum0 = 0, sum1 = 0; \ 144 worktype s0 = 0, s1 = 0; \ 145 ICV_MEAN_ENTRY_BLOCK_COMMON( block_size ) 146 147 #define ICV_MEAN_ENTRY_BLOCK_C3( sumtype, worktype, block_size )\ 148 sumtype sum0 = 0, sum1 = 0, sum2 = 0; \ 149 worktype s0 = 0, s1 = 0, s2 = 0; \ 150 ICV_MEAN_ENTRY_BLOCK_COMMON( block_size ) 151 152 #define ICV_MEAN_ENTRY_BLOCK_C4( sumtype, worktype, block_size )\ 153 sumtype sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0; \ 154 worktype s0 = 0, s1 = 0, s2 = 0, s3 = 0; \ 155 ICV_MEAN_ENTRY_BLOCK_COMMON( block_size ) 156 157 158 /////////////////////////////////////// exit macros ////////////////////////////////////// 159 160 #define ICV_MEAN_EXIT_COMMON() \ 161 double scale = pix ? 1./pix : 0 162 163 #define ICV_MEAN_EXIT_C1( tmp ) \ 164 ICV_MEAN_EXIT_COMMON(); \ 165 mean[0] = scale*(double)tmp##0 166 167 #define ICV_MEAN_EXIT_C2( tmp ) \ 168 ICV_MEAN_EXIT_COMMON(); \ 169 double t0 = scale*(double)tmp##0; \ 170 double t1 = scale*(double)tmp##1; \ 171 mean[0] = t0; \ 172 mean[1] = t1 173 174 #define ICV_MEAN_EXIT_C3( tmp ) \ 175 ICV_MEAN_EXIT_COMMON(); \ 176 double t0 = scale*(double)tmp##0; \ 177 double t1 = scale*(double)tmp##1; \ 178 double t2 = scale*(double)tmp##2; \ 179 mean[0] = t0; \ 180 mean[1] = t1; \ 181 mean[2] = t2 182 183 #define ICV_MEAN_EXIT_C4( tmp ) \ 184 ICV_MEAN_EXIT_COMMON(); \ 185 double t0 = scale*(double)tmp##0; \ 186 double t1 = scale*(double)tmp##1; \ 187 mean[0] = t0; \ 188 mean[1] = t1; \ 189 t0 = scale*(double)tmp##2; \ 190 t1 = scale*(double)tmp##3; \ 191 mean[2] = t0; \ 192 mean[3] = t1 193 194 #define ICV_MEAN_EXIT_BLOCK_C1() \ 195 sum0 += s0; \ 196 ICV_MEAN_EXIT_C1( sum ) 197 198 #define ICV_MEAN_EXIT_BLOCK_C2() \ 199 sum0 += s0; sum1 += s1; \ 200 ICV_MEAN_EXIT_C2( sum ) 201 202 #define ICV_MEAN_EXIT_BLOCK_C3() \ 203 sum0 += s0; sum1 += s1; \ 204 sum2 += s2; \ 205 ICV_MEAN_EXIT_C3( sum ) 206 207 #define ICV_MEAN_EXIT_BLOCK_C4() \ 208 sum0 += s0; sum1 += s1; \ 209 sum2 += s2; sum3 += s3; \ 210 ICV_MEAN_EXIT_C4( sum ) 211 212 ////////////////////////////////////// update macros ///////////////////////////////////// 213 214 #define ICV_MEAN_UPDATE_COMMON( block_size )\ 215 remaining = block_size 216 217 #define ICV_MEAN_UPDATE_C1( block_size ) \ 218 ICV_MEAN_UPDATE_COMMON( block_size ); \ 219 sum0 += s0; \ 220 s0 = 0 221 222 #define ICV_MEAN_UPDATE_C2( block_size ) \ 223 ICV_MEAN_UPDATE_COMMON( block_size ); \ 224 sum0 += s0; sum1 += s1; \ 225 s0 = s1 = 0 226 227 #define ICV_MEAN_UPDATE_C3( block_size ) \ 228 ICV_MEAN_UPDATE_COMMON( block_size ); \ 229 sum0 += s0; sum1 += s1; sum2 += s2; \ 230 s0 = s1 = s2 = 0 231 232 #define ICV_MEAN_UPDATE_C4( block_size ) \ 233 ICV_MEAN_UPDATE_COMMON( block_size ); \ 234 sum0 += s0; sum1 += s1; \ 235 sum2 += s2; sum3 += s3; \ 236 s0 = s1 = s2 = s3 = 0 237 238 239 #define ICV_IMPL_MEAN_BLOCK_FUNC_2D( flavor, cn, \ 240 arrtype, sumtype, worktype, block_size ) \ 241 IPCVAPI_IMPL( CvStatus, icvMean_##flavor##_C##cn##MR, \ 242 ( const arrtype* src, int step, \ 243 const uchar* mask, int maskstep, \ 244 CvSize size, double* mean ), \ 245 (src, step, mask, maskstep, size, mean)) \ 246 { \ 247 ICV_MEAN_ENTRY_BLOCK_C##cn( sumtype, worktype, block_size );\ 248 \ 249 for( ; size.height--; src += step, mask += maskstep ) \ 250 { \ 251 int x = 0; \ 252 while( x < size.width ) \ 253 { \ 254 int limit = MIN( remaining, size.width - x ); \ 255 remaining -= limit; \ 256 limit += x; \ 257 ICV_MEAN_CASE_C##cn( limit ); \ 258 if( remaining == 0 ) \ 259 { \ 260 ICV_MEAN_UPDATE_C##cn( block_size ); \ 261 } \ 262 } \ 263 } \ 264 \ 265 { ICV_MEAN_EXIT_BLOCK_C##cn(); } \ 266 return CV_OK; \ 267 } 268 269 270 #define ICV_IMPL_MEAN_FUNC_2D( flavor, cn, \ 271 arrtype, sumtype, worktype ) \ 272 IPCVAPI_IMPL( CvStatus, icvMean_##flavor##_C##cn##MR, \ 273 ( const arrtype* src, int step, \ 274 const uchar* mask, int maskstep, \ 275 CvSize size, double* mean), \ 276 (src, step, mask, maskstep, size, mean)) \ 277 { \ 278 ICV_MEAN_ENTRY_C##cn( sumtype ); \ 279 \ 280 for( ; size.height--; src += step, mask += maskstep ) \ 281 { \ 282 int x = 0; \ 283 ICV_MEAN_CASE_C##cn( size.width ); \ 284 } \ 285 \ 286 { ICV_MEAN_EXIT_C##cn( s ); } \ 287 return CV_OK; \ 288 } 289 290 291 #define ICV_IMPL_MEAN_BLOCK_FUNC_2D_COI( flavor, \ 292 arrtype, sumtype, worktype, block_size ) \ 293 static CvStatus CV_STDCALL \ 294 icvMean_##flavor##_CnCMR( const arrtype* src, int step, \ 295 const uchar* mask, int maskstep, \ 296 CvSize size, int cn, \ 297 int coi, double* mean ) \ 298 { \ 299 ICV_MEAN_ENTRY_BLOCK_C1( sumtype, worktype, block_size ); \ 300 src += coi - 1; \ 301 \ 302 for( ; size.height--; src += step, mask += maskstep ) \ 303 { \ 304 int x = 0; \ 305 while( x < size.width ) \ 306 { \ 307 int limit = MIN( remaining, size.width - x ); \ 308 remaining -= limit; \ 309 limit += x; \ 310 ICV_MEAN_COI_CASE( limit, cn ); \ 311 if( remaining == 0 ) \ 312 { \ 313 ICV_MEAN_UPDATE_C1( block_size ); \ 314 } \ 315 } \ 316 } \ 317 \ 318 { ICV_MEAN_EXIT_BLOCK_C1(); } \ 319 return CV_OK; \ 320 } 321 322 323 #define ICV_IMPL_MEAN_FUNC_2D_COI( flavor, \ 324 arrtype, sumtype, worktype ) \ 325 static CvStatus CV_STDCALL \ 326 icvMean_##flavor##_CnCMR( const arrtype* src, int step, \ 327 const uchar* mask, int maskstep, \ 328 CvSize size, int cn, \ 329 int coi, double* mean ) \ 330 { \ 331 ICV_MEAN_ENTRY_C1( sumtype ); \ 332 src += coi - 1; \ 333 \ 334 for( ; size.height--; src += step, mask += maskstep ) \ 335 { \ 336 int x = 0; \ 337 ICV_MEAN_COI_CASE( size.width, cn ); \ 338 } \ 339 \ 340 { ICV_MEAN_EXIT_C1( s ); } \ 341 return CV_OK; \ 342 } 343 344 345 #define ICV_IMPL_MEAN_BLOCK_ALL( flavor, arrtype, sumtype, \ 346 worktype, block_size ) \ 347 ICV_IMPL_MEAN_BLOCK_FUNC_2D( flavor, 1, arrtype, sumtype, \ 348 worktype, block_size ) \ 349 ICV_IMPL_MEAN_BLOCK_FUNC_2D( flavor, 2, arrtype, sumtype, \ 350 worktype, block_size ) \ 351 ICV_IMPL_MEAN_BLOCK_FUNC_2D( flavor, 3, arrtype, sumtype, \ 352 worktype, block_size ) \ 353 ICV_IMPL_MEAN_BLOCK_FUNC_2D( flavor, 4, arrtype, sumtype, \ 354 worktype, block_size ) \ 355 ICV_IMPL_MEAN_BLOCK_FUNC_2D_COI( flavor, arrtype, sumtype, \ 356 worktype, block_size ) 357 358 #define ICV_IMPL_MEAN_ALL( flavor, arrtype, sumtype, worktype ) \ 359 ICV_IMPL_MEAN_FUNC_2D( flavor, 1, arrtype, sumtype, worktype ) \ 360 ICV_IMPL_MEAN_FUNC_2D( flavor, 2, arrtype, sumtype, worktype ) \ 361 ICV_IMPL_MEAN_FUNC_2D( flavor, 3, arrtype, sumtype, worktype ) \ 362 ICV_IMPL_MEAN_FUNC_2D( flavor, 4, arrtype, sumtype, worktype ) \ 363 ICV_IMPL_MEAN_FUNC_2D_COI( flavor, arrtype, sumtype, worktype ) 364 365 ICV_IMPL_MEAN_BLOCK_ALL( 8u, uchar, int64, unsigned, 1 << 24 ) 366 ICV_IMPL_MEAN_BLOCK_ALL( 16u, ushort, int64, unsigned, 1 << 16 ) 367 ICV_IMPL_MEAN_BLOCK_ALL( 16s, short, int64, int, 1 << 16 ) 368 ICV_IMPL_MEAN_ALL( 32s, int, double, double ) 369 ICV_IMPL_MEAN_ALL( 32f, float, double, double ) 370 ICV_IMPL_MEAN_ALL( 64f, double, double, double ) 371 372 #define icvMean_8s_C1MR 0 373 #define icvMean_8s_C2MR 0 374 #define icvMean_8s_C3MR 0 375 #define icvMean_8s_C4MR 0 376 #define icvMean_8s_CnCMR 0 377 378 CV_DEF_INIT_BIG_FUNC_TAB_2D( Mean, MR ) 379 CV_DEF_INIT_FUNC_TAB_2D( Mean, CnCMR ) 380 381 CV_IMPL CvScalar 382 cvAvg( const void* img, const void* maskarr ) 383 { 384 CvScalar mean = {{0,0,0,0}}; 385 386 static CvBigFuncTable mean_tab; 387 static CvFuncTable meancoi_tab; 388 static int inittab = 0; 389 390 CV_FUNCNAME("cvAvg"); 391 392 __BEGIN__; 393 394 CvSize size; 395 double scale; 396 397 if( !maskarr ) 398 { 399 CV_CALL( mean = cvSum(img)); 400 size = cvGetSize( img ); 401 size.width *= size.height; 402 scale = size.width ? 1./size.width : 0; 403 404 mean.val[0] *= scale; 405 mean.val[1] *= scale; 406 mean.val[2] *= scale; 407 mean.val[3] *= scale; 408 } 409 else 410 { 411 int type, coi = 0; 412 int mat_step, mask_step; 413 414 CvMat stub, maskstub, *mat = (CvMat*)img, *mask = (CvMat*)maskarr; 415 416 if( !inittab ) 417 { 418 icvInitMeanMRTable( &mean_tab ); 419 icvInitMeanCnCMRTable( &meancoi_tab ); 420 inittab = 1; 421 } 422 423 if( !CV_IS_MAT(mat) ) 424 CV_CALL( mat = cvGetMat( mat, &stub, &coi )); 425 426 if( !CV_IS_MAT(mask) ) 427 CV_CALL( mask = cvGetMat( mask, &maskstub )); 428 429 if( !CV_IS_MASK_ARR(mask) ) 430 CV_ERROR( CV_StsBadMask, "" ); 431 432 if( !CV_ARE_SIZES_EQ( mat, mask ) ) 433 CV_ERROR( CV_StsUnmatchedSizes, "" ); 434 435 type = CV_MAT_TYPE( mat->type ); 436 size = cvGetMatSize( mat ); 437 438 mat_step = mat->step; 439 mask_step = mask->step; 440 441 if( CV_IS_MAT_CONT( mat->type & mask->type )) 442 { 443 size.width *= size.height; 444 size.height = 1; 445 mat_step = mask_step = CV_STUB_STEP; 446 } 447 448 if( CV_MAT_CN(type) == 1 || coi == 0 ) 449 { 450 CvFunc2D_2A1P func; 451 452 if( CV_MAT_CN(type) > 4 ) 453 CV_ERROR( CV_StsOutOfRange, "The input array must have at most 4 channels unless COI is set" ); 454 455 func = (CvFunc2D_2A1P)(mean_tab.fn_2d[type]); 456 457 if( !func ) 458 CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); 459 460 IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, 461 mask_step, size, mean.val )); 462 } 463 else 464 { 465 CvFunc2DnC_2A1P func = (CvFunc2DnC_2A1P)( 466 meancoi_tab.fn_2d[CV_MAT_DEPTH(type)]); 467 468 if( !func ) 469 CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); 470 471 IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, 472 mask_step, size, CV_MAT_CN(type), coi, mean.val )); 473 } 474 } 475 476 __END__; 477 478 return mean; 479 } 480 481 /* End of file */ 482