Home | History | Annotate | Download | only in src
      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