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 44 /****************************************************************************************\ 45 * Mean and StdDev calculation * 46 \****************************************************************************************/ 47 48 #define ICV_MEAN_SDV_COI_CASE( worktype, sqsumtype, \ 49 sqr_macro, len, cn ) \ 50 for( ; x <= (len) - 4*(cn); x += 4*(cn))\ 51 { \ 52 worktype t0 = src[x]; \ 53 worktype t1 = src[x + (cn)]; \ 54 \ 55 s0 += t0 + t1; \ 56 sq0 += (sqsumtype)(sqr_macro(t0)) + \ 57 (sqsumtype)(sqr_macro(t1)); \ 58 \ 59 t0 = src[x + 2*(cn)]; \ 60 t1 = src[x + 3*(cn)]; \ 61 \ 62 s0 += t0 + t1; \ 63 sq0 += (sqsumtype)(sqr_macro(t0)) + \ 64 (sqsumtype)(sqr_macro(t1)); \ 65 } \ 66 \ 67 for( ; x < (len); x += (cn) ) \ 68 { \ 69 worktype t0 = src[x]; \ 70 \ 71 s0 += t0; \ 72 sq0 += (sqsumtype)(sqr_macro(t0)); \ 73 } 74 75 76 #define ICV_MEAN_SDV_CASE_C1( worktype, sqsumtype, sqr_macro, len ) \ 77 ICV_MEAN_SDV_COI_CASE( worktype, sqsumtype, sqr_macro, len, 1 ) 78 79 80 #define ICV_MEAN_SDV_CASE_C2( worktype, sqsumtype, \ 81 sqr_macro, len ) \ 82 for( ; x < (len); x += 2 ) \ 83 { \ 84 worktype t0 = (src)[x]; \ 85 worktype t1 = (src)[x + 1]; \ 86 \ 87 s0 += t0; \ 88 sq0 += (sqsumtype)(sqr_macro(t0)); \ 89 s1 += t1; \ 90 sq1 += (sqsumtype)(sqr_macro(t1)); \ 91 } 92 93 94 #define ICV_MEAN_SDV_CASE_C3( worktype, sqsumtype, \ 95 sqr_macro, len ) \ 96 for( ; x < (len); x += 3 ) \ 97 { \ 98 worktype t0 = (src)[x]; \ 99 worktype t1 = (src)[x + 1]; \ 100 worktype t2 = (src)[x + 2]; \ 101 \ 102 s0 += t0; \ 103 sq0 += (sqsumtype)(sqr_macro(t0)); \ 104 s1 += t1; \ 105 sq1 += (sqsumtype)(sqr_macro(t1)); \ 106 s2 += t2; \ 107 sq2 += (sqsumtype)(sqr_macro(t2)); \ 108 } 109 110 111 #define ICV_MEAN_SDV_CASE_C4( worktype, sqsumtype, \ 112 sqr_macro, len ) \ 113 for( ; x < (len); x += 4 ) \ 114 { \ 115 worktype t0 = (src)[x]; \ 116 worktype t1 = (src)[x + 1]; \ 117 \ 118 s0 += t0; \ 119 sq0 += (sqsumtype)(sqr_macro(t0)); \ 120 s1 += t1; \ 121 sq1 += (sqsumtype)(sqr_macro(t1)); \ 122 \ 123 t0 = (src)[x + 2]; \ 124 t1 = (src)[x + 3]; \ 125 \ 126 s2 += t0; \ 127 sq2 += (sqsumtype)(sqr_macro(t0)); \ 128 s3 += t1; \ 129 sq3 += (sqsumtype)(sqr_macro(t1)); \ 130 } 131 132 133 #define ICV_MEAN_SDV_MASK_COI_CASE( worktype, sqsumtype, \ 134 sqr_macro, len, cn ) \ 135 for( ; x <= (len) - 4; x += 4 ) \ 136 { \ 137 worktype t0; \ 138 if( mask[x] ) \ 139 { \ 140 t0 = src[x*(cn)]; pix++; \ 141 s0 += t0; \ 142 sq0 += sqsumtype(sqr_macro(t0)); \ 143 } \ 144 \ 145 if( mask[x+1] ) \ 146 { \ 147 t0 = src[(x+1)*(cn)]; pix++; \ 148 s0 += t0; \ 149 sq0 += sqsumtype(sqr_macro(t0)); \ 150 } \ 151 \ 152 if( mask[x+2] ) \ 153 { \ 154 t0 = src[(x+2)*(cn)]; pix++; \ 155 s0 += t0; \ 156 sq0 += sqsumtype(sqr_macro(t0)); \ 157 } \ 158 \ 159 if( mask[x+3] ) \ 160 { \ 161 t0 = src[(x+3)*(cn)]; pix++; \ 162 s0 += t0; \ 163 sq0 += sqsumtype(sqr_macro(t0)); \ 164 } \ 165 } \ 166 \ 167 for( ; x < (len); x++ ) \ 168 { \ 169 if( mask[x] ) \ 170 { \ 171 worktype t0 = src[x*(cn)]; pix++; \ 172 s0 += t0; \ 173 sq0 += sqsumtype(sqr_macro(t0)); \ 174 } \ 175 } 176 177 178 #define ICV_MEAN_SDV_MASK_CASE_C1( worktype, sqsumtype, sqr_macro, len ) \ 179 ICV_MEAN_SDV_MASK_COI_CASE( worktype, sqsumtype, sqr_macro, len, 1 ) 180 181 182 #define ICV_MEAN_SDV_MASK_CASE_C2( worktype, sqsumtype,\ 183 sqr_macro, len ) \ 184 for( ; x < (len); x++ ) \ 185 { \ 186 if( mask[x] ) \ 187 { \ 188 worktype t0 = src[x*2]; \ 189 worktype t1 = src[x*2+1]; \ 190 pix++; \ 191 s0 += t0; \ 192 sq0 += sqsumtype(sqr_macro(t0)); \ 193 s1 += t1; \ 194 sq1 += sqsumtype(sqr_macro(t1)); \ 195 } \ 196 } 197 198 199 #define ICV_MEAN_SDV_MASK_CASE_C3( worktype, sqsumtype,\ 200 sqr_macro, len ) \ 201 for( ; x < (len); x++ ) \ 202 { \ 203 if( mask[x] ) \ 204 { \ 205 worktype t0 = src[x*3]; \ 206 worktype t1 = src[x*3+1]; \ 207 worktype t2 = src[x*3+2]; \ 208 pix++; \ 209 s0 += t0; \ 210 sq0 += sqsumtype(sqr_macro(t0)); \ 211 s1 += t1; \ 212 sq1 += sqsumtype(sqr_macro(t1)); \ 213 s2 += t2; \ 214 sq2 += sqsumtype(sqr_macro(t2)); \ 215 } \ 216 } 217 218 219 #define ICV_MEAN_SDV_MASK_CASE_C4( worktype, sqsumtype,\ 220 sqr_macro, len ) \ 221 for( ; x < (len); x++ ) \ 222 { \ 223 if( mask[x] ) \ 224 { \ 225 worktype t0 = src[x*4]; \ 226 worktype t1 = src[x*4+1]; \ 227 pix++; \ 228 s0 += t0; \ 229 sq0 += sqsumtype(sqr_macro(t0)); \ 230 s1 += t1; \ 231 sq1 += sqsumtype(sqr_macro(t1)); \ 232 t0 = src[x*4+2]; \ 233 t1 = src[x*4+3]; \ 234 s2 += t0; \ 235 sq2 += sqsumtype(sqr_macro(t0)); \ 236 s3 += t1; \ 237 sq3 += sqsumtype(sqr_macro(t1)); \ 238 } \ 239 } 240 241 242 ////////////////////////////////////// entry macros ////////////////////////////////////// 243 244 #define ICV_MEAN_SDV_ENTRY_COMMON() \ 245 int pix; \ 246 double scale, tmp; \ 247 step /= sizeof(src[0]) 248 249 #define ICV_MEAN_SDV_ENTRY_C1( sumtype, sqsumtype ) \ 250 sumtype s0 = 0; \ 251 sqsumtype sq0 = 0; \ 252 ICV_MEAN_SDV_ENTRY_COMMON() 253 254 #define ICV_MEAN_SDV_ENTRY_C2( sumtype, sqsumtype ) \ 255 sumtype s0 = 0, s1 = 0; \ 256 sqsumtype sq0 = 0, sq1 = 0; \ 257 ICV_MEAN_SDV_ENTRY_COMMON() 258 259 #define ICV_MEAN_SDV_ENTRY_C3( sumtype, sqsumtype ) \ 260 sumtype s0 = 0, s1 = 0, s2 = 0; \ 261 sqsumtype sq0 = 0, sq1 = 0, sq2 = 0; \ 262 ICV_MEAN_SDV_ENTRY_COMMON() 263 264 #define ICV_MEAN_SDV_ENTRY_C4( sumtype, sqsumtype ) \ 265 sumtype s0 = 0, s1 = 0, s2 = 0, s3 = 0; \ 266 sqsumtype sq0 = 0, sq1 = 0, sq2 = 0, sq3 = 0; \ 267 ICV_MEAN_SDV_ENTRY_COMMON() 268 269 270 #define ICV_MEAN_SDV_ENTRY_BLOCK_COMMON( block_size ) \ 271 int remaining = block_size; \ 272 ICV_MEAN_SDV_ENTRY_COMMON() 273 274 #define ICV_MEAN_SDV_ENTRY_BLOCK_C1( sumtype, sqsumtype, \ 275 worktype, sqworktype, block_size ) \ 276 sumtype sum0 = 0; \ 277 sqsumtype sqsum0 = 0; \ 278 worktype s0 = 0; \ 279 sqworktype sq0 = 0; \ 280 ICV_MEAN_SDV_ENTRY_BLOCK_COMMON( block_size ) 281 282 #define ICV_MEAN_SDV_ENTRY_BLOCK_C2( sumtype, sqsumtype, \ 283 worktype, sqworktype, block_size ) \ 284 sumtype sum0 = 0, sum1 = 0; \ 285 sqsumtype sqsum0 = 0, sqsum1 = 0; \ 286 worktype s0 = 0, s1 = 0; \ 287 sqworktype sq0 = 0, sq1 = 0; \ 288 ICV_MEAN_SDV_ENTRY_BLOCK_COMMON( block_size ) 289 290 #define ICV_MEAN_SDV_ENTRY_BLOCK_C3( sumtype, sqsumtype, \ 291 worktype, sqworktype, block_size ) \ 292 sumtype sum0 = 0, sum1 = 0, sum2 = 0; \ 293 sqsumtype sqsum0 = 0, sqsum1 = 0, sqsum2 = 0; \ 294 worktype s0 = 0, s1 = 0, s2 = 0; \ 295 sqworktype sq0 = 0, sq1 = 0, sq2 = 0; \ 296 ICV_MEAN_SDV_ENTRY_BLOCK_COMMON( block_size ) 297 298 #define ICV_MEAN_SDV_ENTRY_BLOCK_C4( sumtype, sqsumtype, \ 299 worktype, sqworktype, block_size ) \ 300 sumtype sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0; \ 301 sqsumtype sqsum0 = 0, sqsum1 = 0, sqsum2 = 0, sqsum3 = 0; \ 302 worktype s0 = 0, s1 = 0, s2 = 0, s3 = 0; \ 303 sqworktype sq0 = 0, sq1 = 0, sq2 = 0, sq3 = 0; \ 304 ICV_MEAN_SDV_ENTRY_BLOCK_COMMON( block_size ) 305 306 307 /////////////////////////////////////// exit macros ////////////////////////////////////// 308 309 #define ICV_MEAN_SDV_EXIT_COMMON() \ 310 scale = pix ? 1./pix : 0 311 312 #define ICV_MEAN_SDV_EXIT_CN( total, sqtotal, idx ) \ 313 ICV_MEAN_SDV_EXIT_COMMON(); \ 314 mean[idx] = tmp = scale*(double)total##idx; \ 315 tmp = scale*(double)sqtotal##idx - tmp*tmp; \ 316 sdv[idx] = sqrt(MAX(tmp,0.)) 317 318 #define ICV_MEAN_SDV_EXIT_C1( total, sqtotal ) \ 319 ICV_MEAN_SDV_EXIT_COMMON(); \ 320 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 0 ) 321 322 #define ICV_MEAN_SDV_EXIT_C2( total, sqtotal ) \ 323 ICV_MEAN_SDV_EXIT_COMMON(); \ 324 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 0 ); \ 325 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 1 ) 326 327 #define ICV_MEAN_SDV_EXIT_C3( total, sqtotal ) \ 328 ICV_MEAN_SDV_EXIT_COMMON(); \ 329 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 0 ); \ 330 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 1 ); \ 331 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 2 ) 332 333 #define ICV_MEAN_SDV_EXIT_C4( total, sqtotal ) \ 334 ICV_MEAN_SDV_EXIT_COMMON(); \ 335 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 0 ); \ 336 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 1 ); \ 337 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 2 ); \ 338 ICV_MEAN_SDV_EXIT_CN( total, sqtotal, 3 ) 339 340 ////////////////////////////////////// update macros ///////////////////////////////////// 341 342 #define ICV_MEAN_SDV_UPDATE_COMMON( block_size )\ 343 remaining = block_size 344 345 #define ICV_MEAN_SDV_UPDATE_C1( block_size ) \ 346 ICV_MEAN_SDV_UPDATE_COMMON( block_size ); \ 347 sum0 += s0; sqsum0 += sq0; \ 348 s0 = 0; sq0 = 0 349 350 #define ICV_MEAN_SDV_UPDATE_C2( block_size ) \ 351 ICV_MEAN_SDV_UPDATE_COMMON( block_size ); \ 352 sum0 += s0; sqsum0 += sq0; \ 353 sum1 += s1; sqsum1 += sq1; \ 354 s0 = s1 = 0; sq0 = sq1 = 0 355 356 #define ICV_MEAN_SDV_UPDATE_C3( block_size ) \ 357 ICV_MEAN_SDV_UPDATE_COMMON( block_size ); \ 358 sum0 += s0; sqsum0 += sq0; \ 359 sum1 += s1; sqsum1 += sq1; \ 360 sum2 += s2; sqsum2 += sq2; \ 361 s0 = s1 = s2 = 0; sq0 = sq1 = sq2 = 0 362 363 #define ICV_MEAN_SDV_UPDATE_C4( block_size ) \ 364 ICV_MEAN_SDV_UPDATE_COMMON( block_size ); \ 365 sum0 += s0; sqsum0 += sq0; \ 366 sum1 += s1; sqsum1 += sq1; \ 367 sum2 += s2; sqsum2 += sq2; \ 368 sum3 += s3; sqsum3 += sq3; \ 369 s0 = s1 = s2 = s3 = 0; sq0 = sq1 = sq2 = sq3 = 0 370 371 372 373 #define ICV_DEF_MEAN_SDV_BLOCK_FUNC_2D( flavor, cn, arrtype, \ 374 sumtype, sqsumtype, worktype, \ 375 sqworktype, block_size, sqr_macro ) \ 376 IPCVAPI_IMPL( CvStatus, icvMean_StdDev_##flavor##_C##cn##R, \ 377 ( const arrtype* src, int step, \ 378 CvSize size, double* mean, double* sdv ), \ 379 (src, step, size, mean, sdv) ) \ 380 { \ 381 ICV_MEAN_SDV_ENTRY_BLOCK_C##cn( sumtype, sqsumtype, \ 382 worktype, sqworktype, (block_size)*(cn) ); \ 383 pix = size.width * size.height; \ 384 size.width *= (cn); \ 385 \ 386 for( ; size.height--; src += step ) \ 387 { \ 388 int x = 0; \ 389 while( x < size.width ) \ 390 { \ 391 int limit = MIN( remaining, size.width - x ); \ 392 remaining -= limit; \ 393 limit += x; \ 394 ICV_MEAN_SDV_CASE_C##cn( worktype, sqworktype, \ 395 sqr_macro, limit ); \ 396 if( remaining == 0 ) \ 397 { \ 398 ICV_MEAN_SDV_UPDATE_C##cn( (block_size)*(cn) ); \ 399 } \ 400 } \ 401 } \ 402 \ 403 ICV_MEAN_SDV_UPDATE_C##cn(0); \ 404 ICV_MEAN_SDV_EXIT_C##cn( sum, sqsum ); \ 405 return CV_OK; \ 406 } 407 408 409 #define ICV_DEF_MEAN_SDV_FUNC_2D( flavor, cn, arrtype, \ 410 sumtype, sqsumtype, worktype ) \ 411 IPCVAPI_IMPL( CvStatus, icvMean_StdDev_##flavor##_C##cn##R, \ 412 ( const arrtype* src, int step, \ 413 CvSize size, double* mean, double* sdv ), \ 414 (src, step, size, mean, sdv) ) \ 415 { \ 416 ICV_MEAN_SDV_ENTRY_C##cn( sumtype, sqsumtype ); \ 417 pix = size.width * size.height; \ 418 size.width *= (cn); \ 419 \ 420 for( ; size.height--; src += step ) \ 421 { \ 422 int x = 0; \ 423 ICV_MEAN_SDV_CASE_C##cn( worktype, sqsumtype, \ 424 CV_SQR, size.width ); \ 425 } \ 426 \ 427 ICV_MEAN_SDV_EXIT_C##cn( s, sq ); \ 428 return CV_OK; \ 429 } 430 431 432 #define ICV_DEF_MEAN_SDV_BLOCK_FUNC_2D_COI( flavor, arrtype, \ 433 sumtype, sqsumtype, worktype, \ 434 sqworktype, block_size, sqr_macro ) \ 435 static CvStatus CV_STDCALL icvMean_StdDev_##flavor##_CnCR \ 436 ( const arrtype* src, int step, \ 437 CvSize size, int cn, int coi, \ 438 double* mean, double* sdv ) \ 439 { \ 440 ICV_MEAN_SDV_ENTRY_BLOCK_C1( sumtype, sqsumtype, \ 441 worktype, sqworktype, (block_size)*(cn) ); \ 442 pix = size.width * size.height; \ 443 size.width *= (cn); \ 444 src += coi - 1; \ 445 \ 446 for( ; size.height--; src += step ) \ 447 { \ 448 int x = 0; \ 449 while( x < size.width ) \ 450 { \ 451 int limit = MIN( remaining, size.width - x ); \ 452 remaining -= limit; \ 453 limit += x; \ 454 ICV_MEAN_SDV_COI_CASE( worktype, sqworktype, \ 455 sqr_macro, limit, cn); \ 456 if( remaining == 0 ) \ 457 { \ 458 ICV_MEAN_SDV_UPDATE_C1( (block_size)*(cn) ); \ 459 } \ 460 } \ 461 } \ 462 \ 463 ICV_MEAN_SDV_UPDATE_C1(0); \ 464 ICV_MEAN_SDV_EXIT_C1( sum, sqsum ); \ 465 return CV_OK; \ 466 } 467 468 469 #define ICV_DEF_MEAN_SDV_FUNC_2D_COI( flavor, arrtype, \ 470 sumtype, sqsumtype, worktype )\ 471 static CvStatus CV_STDCALL icvMean_StdDev_##flavor##_CnCR \ 472 ( const arrtype* src, int step, CvSize size,\ 473 int cn, int coi, double* mean, double* sdv )\ 474 { \ 475 ICV_MEAN_SDV_ENTRY_C1( sumtype, sqsumtype ); \ 476 pix = size.width * size.height; \ 477 size.width *= (cn); \ 478 src += coi - 1; \ 479 \ 480 for( ; size.height--; src += step ) \ 481 { \ 482 int x = 0; \ 483 ICV_MEAN_SDV_COI_CASE( worktype, sqsumtype, \ 484 CV_SQR, size.width, cn ); \ 485 } \ 486 \ 487 ICV_MEAN_SDV_EXIT_C1( s, sq ); \ 488 return CV_OK; \ 489 } 490 491 492 #define ICV_DEF_MEAN_SDV_MASK_BLOCK_FUNC_2D( flavor, cn, \ 493 arrtype, sumtype, sqsumtype, worktype, \ 494 sqworktype, block_size, sqr_macro ) \ 495 IPCVAPI_IMPL( CvStatus, icvMean_StdDev_##flavor##_C##cn##MR, \ 496 ( const arrtype* src, int step, \ 497 const uchar* mask, int maskstep, \ 498 CvSize size, double* mean, double* sdv ), \ 499 (src, step, mask, maskstep, size, mean, sdv))\ 500 { \ 501 ICV_MEAN_SDV_ENTRY_BLOCK_C##cn( sumtype, sqsumtype, \ 502 worktype, sqworktype, block_size ); \ 503 pix = 0; \ 504 \ 505 for( ; size.height--; src += step, mask += maskstep ) \ 506 { \ 507 int x = 0; \ 508 while( x < size.width ) \ 509 { \ 510 int limit = MIN( remaining, size.width - x ); \ 511 remaining -= limit; \ 512 limit += x; \ 513 ICV_MEAN_SDV_MASK_CASE_C##cn( worktype, sqworktype, \ 514 sqr_macro, limit ); \ 515 if( remaining == 0 ) \ 516 { \ 517 ICV_MEAN_SDV_UPDATE_C##cn( block_size ); \ 518 } \ 519 } \ 520 } \ 521 \ 522 ICV_MEAN_SDV_UPDATE_C##cn(0); \ 523 ICV_MEAN_SDV_EXIT_C##cn( sum, sqsum ); \ 524 return CV_OK; \ 525 } 526 527 528 #define ICV_DEF_MEAN_SDV_MASK_FUNC_2D( flavor, cn, arrtype, \ 529 sumtype, sqsumtype, worktype)\ 530 IPCVAPI_IMPL( CvStatus, icvMean_StdDev_##flavor##_C##cn##MR, \ 531 ( const arrtype* src, int step, \ 532 const uchar* mask, int maskstep, \ 533 CvSize size, double* mean, double* sdv ), \ 534 (src, step, mask, maskstep, size, mean, sdv))\ 535 { \ 536 ICV_MEAN_SDV_ENTRY_C##cn( sumtype, sqsumtype ); \ 537 pix = 0; \ 538 \ 539 for( ; size.height--; src += step, mask += maskstep ) \ 540 { \ 541 int x = 0; \ 542 ICV_MEAN_SDV_MASK_CASE_C##cn( worktype, sqsumtype, \ 543 CV_SQR, size.width ); \ 544 } \ 545 \ 546 ICV_MEAN_SDV_EXIT_C##cn( s, sq ); \ 547 return CV_OK; \ 548 } 549 550 551 #define ICV_DEF_MEAN_SDV_MASK_BLOCK_FUNC_2D_COI( flavor, \ 552 arrtype, sumtype, sqsumtype, worktype, \ 553 sqworktype, block_size, sqr_macro ) \ 554 static CvStatus CV_STDCALL icvMean_StdDev_##flavor##_CnCMR \ 555 ( const arrtype* src, int step, \ 556 const uchar* mask, int maskstep, \ 557 CvSize size, int cn, int coi, \ 558 double* mean, double* sdv ) \ 559 { \ 560 ICV_MEAN_SDV_ENTRY_BLOCK_C1( sumtype, sqsumtype, \ 561 worktype, sqworktype, block_size ); \ 562 pix = 0; \ 563 src += coi - 1; \ 564 \ 565 for( ; size.height--; src += step, mask += maskstep ) \ 566 { \ 567 int x = 0; \ 568 while( x < size.width ) \ 569 { \ 570 int limit = MIN( remaining, size.width - x ); \ 571 remaining -= limit; \ 572 limit += x; \ 573 ICV_MEAN_SDV_MASK_COI_CASE( worktype, sqworktype, \ 574 sqr_macro, limit, cn ); \ 575 if( remaining == 0 ) \ 576 { \ 577 ICV_MEAN_SDV_UPDATE_C1( block_size ); \ 578 } \ 579 } \ 580 } \ 581 \ 582 ICV_MEAN_SDV_UPDATE_C1(0); \ 583 ICV_MEAN_SDV_EXIT_C1( sum, sqsum ); \ 584 return CV_OK; \ 585 } 586 587 588 #define ICV_DEF_MEAN_SDV_MASK_FUNC_2D_COI( flavor, arrtype, \ 589 sumtype, sqsumtype, worktype ) \ 590 static CvStatus CV_STDCALL icvMean_StdDev_##flavor##_CnCMR \ 591 ( const arrtype* src, int step, \ 592 const uchar* mask, int maskstep, \ 593 CvSize size, int cn, int coi, \ 594 double* mean, double* sdv ) \ 595 { \ 596 ICV_MEAN_SDV_ENTRY_C1( sumtype, sqsumtype ); \ 597 pix = 0; \ 598 src += coi - 1; \ 599 \ 600 for( ; size.height--; src += step, mask += maskstep ) \ 601 { \ 602 int x = 0; \ 603 ICV_MEAN_SDV_MASK_COI_CASE( worktype, sqsumtype, \ 604 CV_SQR, size.width, cn ); \ 605 } \ 606 \ 607 ICV_MEAN_SDV_EXIT_C1( s, sq ); \ 608 return CV_OK; \ 609 } 610 611 612 #define ICV_DEF_MEAN_SDV_BLOCK_ALL( flavor, arrtype, sumtype, sqsumtype,\ 613 worktype, sqworktype, block_size, sqr_macro)\ 614 ICV_DEF_MEAN_SDV_BLOCK_FUNC_2D( flavor, 1, arrtype, sumtype, sqsumtype, \ 615 worktype, sqworktype, block_size, sqr_macro)\ 616 ICV_DEF_MEAN_SDV_BLOCK_FUNC_2D( flavor, 2, arrtype, sumtype, sqsumtype, \ 617 worktype, sqworktype, block_size, sqr_macro)\ 618 ICV_DEF_MEAN_SDV_BLOCK_FUNC_2D( flavor, 3, arrtype, sumtype, sqsumtype, \ 619 worktype, sqworktype, block_size, sqr_macro)\ 620 ICV_DEF_MEAN_SDV_BLOCK_FUNC_2D( flavor, 4, arrtype, sumtype, sqsumtype, \ 621 worktype, sqworktype, block_size, sqr_macro)\ 622 ICV_DEF_MEAN_SDV_BLOCK_FUNC_2D_COI( flavor, arrtype, sumtype, sqsumtype,\ 623 worktype, sqworktype, block_size, sqr_macro)\ 624 \ 625 ICV_DEF_MEAN_SDV_MASK_BLOCK_FUNC_2D( flavor, 1, arrtype, sumtype, \ 626 sqsumtype, worktype, sqworktype, block_size, sqr_macro ) \ 627 ICV_DEF_MEAN_SDV_MASK_BLOCK_FUNC_2D( flavor, 2, arrtype, sumtype, \ 628 sqsumtype, worktype, sqworktype, block_size, sqr_macro ) \ 629 ICV_DEF_MEAN_SDV_MASK_BLOCK_FUNC_2D( flavor, 3, arrtype, sumtype, \ 630 sqsumtype, worktype, sqworktype, block_size, sqr_macro ) \ 631 ICV_DEF_MEAN_SDV_MASK_BLOCK_FUNC_2D( flavor, 4, arrtype, sumtype, \ 632 sqsumtype, worktype, sqworktype, block_size, sqr_macro ) \ 633 ICV_DEF_MEAN_SDV_MASK_BLOCK_FUNC_2D_COI( flavor, arrtype, sumtype, \ 634 sqsumtype, worktype, sqworktype, block_size, sqr_macro ) 635 636 #define ICV_DEF_MEAN_SDV_ALL( flavor, arrtype, sumtype, sqsumtype, worktype ) \ 637 ICV_DEF_MEAN_SDV_FUNC_2D( flavor, 1, arrtype, sumtype, sqsumtype, worktype ) \ 638 ICV_DEF_MEAN_SDV_FUNC_2D( flavor, 2, arrtype, sumtype, sqsumtype, worktype ) \ 639 ICV_DEF_MEAN_SDV_FUNC_2D( flavor, 3, arrtype, sumtype, sqsumtype, worktype ) \ 640 ICV_DEF_MEAN_SDV_FUNC_2D( flavor, 4, arrtype, sumtype, sqsumtype, worktype ) \ 641 ICV_DEF_MEAN_SDV_FUNC_2D_COI( flavor, arrtype, sumtype, sqsumtype, worktype ) \ 642 \ 643 ICV_DEF_MEAN_SDV_MASK_FUNC_2D(flavor, 1, arrtype, sumtype, sqsumtype, worktype) \ 644 ICV_DEF_MEAN_SDV_MASK_FUNC_2D(flavor, 2, arrtype, sumtype, sqsumtype, worktype) \ 645 ICV_DEF_MEAN_SDV_MASK_FUNC_2D(flavor, 3, arrtype, sumtype, sqsumtype, worktype) \ 646 ICV_DEF_MEAN_SDV_MASK_FUNC_2D(flavor, 4, arrtype, sumtype, sqsumtype, worktype) \ 647 ICV_DEF_MEAN_SDV_MASK_FUNC_2D_COI( flavor, arrtype, sumtype, sqsumtype, worktype ) 648 649 650 ICV_DEF_MEAN_SDV_BLOCK_ALL( 8u, uchar, int64, int64, unsigned, unsigned, 1 << 16, CV_SQR_8U ) 651 ICV_DEF_MEAN_SDV_BLOCK_ALL( 16u, ushort, int64, int64, unsigned, int64, 1 << 16, CV_SQR ) 652 ICV_DEF_MEAN_SDV_BLOCK_ALL( 16s, short, int64, int64, int, int64, 1 << 16, CV_SQR ) 653 654 ICV_DEF_MEAN_SDV_ALL( 32s, int, double, double, double ) 655 ICV_DEF_MEAN_SDV_ALL( 32f, float, double, double, double ) 656 ICV_DEF_MEAN_SDV_ALL( 64f, double, double, double, double ) 657 658 #define icvMean_StdDev_8s_C1R 0 659 #define icvMean_StdDev_8s_C2R 0 660 #define icvMean_StdDev_8s_C3R 0 661 #define icvMean_StdDev_8s_C4R 0 662 #define icvMean_StdDev_8s_CnCR 0 663 664 #define icvMean_StdDev_8s_C1MR 0 665 #define icvMean_StdDev_8s_C2MR 0 666 #define icvMean_StdDev_8s_C3MR 0 667 #define icvMean_StdDev_8s_C4MR 0 668 #define icvMean_StdDev_8s_CnCMR 0 669 670 CV_DEF_INIT_BIG_FUNC_TAB_2D( Mean_StdDev, R ) 671 CV_DEF_INIT_FUNC_TAB_2D( Mean_StdDev, CnCR ) 672 CV_DEF_INIT_BIG_FUNC_TAB_2D( Mean_StdDev, MR ) 673 CV_DEF_INIT_FUNC_TAB_2D( Mean_StdDev, CnCMR ) 674 675 CV_IMPL void 676 cvAvgSdv( const CvArr* img, CvScalar* _mean, CvScalar* _sdv, const void* mask ) 677 { 678 CvScalar mean = {{0,0,0,0}}; 679 CvScalar sdv = {{0,0,0,0}}; 680 681 static CvBigFuncTable meansdv_tab; 682 static CvFuncTable meansdvcoi_tab; 683 static CvBigFuncTable meansdvmask_tab; 684 static CvFuncTable meansdvmaskcoi_tab; 685 static int inittab = 0; 686 687 CV_FUNCNAME("cvMean_StdDev"); 688 689 __BEGIN__; 690 691 int type, coi = 0; 692 int mat_step, mask_step = 0; 693 CvSize size; 694 CvMat stub, maskstub, *mat = (CvMat*)img, *matmask = (CvMat*)mask; 695 696 if( !inittab ) 697 { 698 icvInitMean_StdDevRTable( &meansdv_tab ); 699 icvInitMean_StdDevCnCRTable( &meansdvcoi_tab ); 700 icvInitMean_StdDevMRTable( &meansdvmask_tab ); 701 icvInitMean_StdDevCnCMRTable( &meansdvmaskcoi_tab ); 702 inittab = 1; 703 } 704 705 if( !CV_IS_MAT(mat) ) 706 CV_CALL( mat = cvGetMat( mat, &stub, &coi )); 707 708 type = CV_MAT_TYPE( mat->type ); 709 710 if( CV_MAT_CN(type) > 4 && coi == 0 ) 711 CV_ERROR( CV_StsOutOfRange, "The input array must have at most 4 channels unless COI is set" ); 712 713 size = cvGetMatSize( mat ); 714 mat_step = mat->step; 715 716 if( !mask ) 717 { 718 if( CV_IS_MAT_CONT( mat->type )) 719 { 720 size.width *= size.height; 721 size.height = 1; 722 mat_step = CV_STUB_STEP; 723 } 724 725 if( CV_MAT_CN(type) == 1 || coi == 0 ) 726 { 727 CvFunc2D_1A2P func = (CvFunc2D_1A2P)(meansdv_tab.fn_2d[type]); 728 729 if( !func ) 730 CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); 731 732 IPPI_CALL( func( mat->data.ptr, mat_step, size, mean.val, sdv.val )); 733 } 734 else 735 { 736 CvFunc2DnC_1A2P func = (CvFunc2DnC_1A2P) 737 (meansdvcoi_tab.fn_2d[CV_MAT_DEPTH(type)]); 738 739 if( !func ) 740 CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); 741 742 IPPI_CALL( func( mat->data.ptr, mat_step, size, 743 CV_MAT_CN(type), coi, mean.val, sdv.val )); 744 } 745 } 746 else 747 { 748 CV_CALL( matmask = cvGetMat( matmask, &maskstub )); 749 750 mask_step = matmask->step; 751 752 if( !CV_IS_MASK_ARR( matmask )) 753 CV_ERROR( CV_StsBadMask, "" ); 754 755 if( !CV_ARE_SIZES_EQ( mat, matmask )) 756 CV_ERROR( CV_StsUnmatchedSizes, "" ); 757 758 if( CV_IS_MAT_CONT( mat->type & matmask->type )) 759 { 760 size.width *= size.height; 761 size.height = 1; 762 mat_step = mask_step = CV_STUB_STEP; 763 } 764 765 if( CV_MAT_CN(type) == 1 || coi == 0 ) 766 { 767 CvFunc2D_2A2P func = (CvFunc2D_2A2P)(meansdvmask_tab.fn_2d[type]); 768 769 if( !func ) 770 CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); 771 772 IPPI_CALL( func( mat->data.ptr, mat_step, matmask->data.ptr, 773 mask_step, size, mean.val, sdv.val )); 774 } 775 else 776 { 777 CvFunc2DnC_2A2P func = (CvFunc2DnC_2A2P) 778 (meansdvmaskcoi_tab.fn_2d[CV_MAT_DEPTH(type)]); 779 780 if( !func ) 781 CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); 782 783 IPPI_CALL( func( mat->data.ptr, mat_step, 784 matmask->data.ptr, mask_step, 785 size, CV_MAT_CN(type), coi, mean.val, sdv.val )); 786 } 787 } 788 789 __END__; 790 791 if( _mean ) 792 *_mean = mean; 793 794 if( _sdv ) 795 *_sdv = sdv; 796 } 797 798 799 /* End of file */ 800