1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
45 /****************************************************************************************\
46 * Mean value over the region *
47 \****************************************************************************************/
49 #define ICV_MEAN_CASE_C1( len ) \
50 for( ; x <= (len) - 2; x += 2 ) \
53 s0 += src[x], pix++; \
55 s0 += src[x+1], pix++; \
58 for( ; x < (len); x++ ) \
63 #define ICV_MEAN_CASE_C2( len ) \
64 for( ; x < (len); x++ ) \
73 #define ICV_MEAN_CASE_C3( len ) \
74 for( ; x < (len); x++ ) \
84 #define ICV_MEAN_CASE_C4( len ) \
85 for( ; x < (len); x++ ) \
96 #define ICV_MEAN_COI_CASE( len, cn ) \
97 for( ; x <= (len) - 2; x += 2 ) \
100 s0 += src[x*(cn)], pix++; \
102 s0+=src[(x+1)*(cn)], pix++; \
105 for( ; x < (len); x++ ) \
107 s0 += src[x*(cn)], pix++;
110 ////////////////////////////////////// entry macros //////////////////////////////////////
112 #define ICV_MEAN_ENTRY_COMMON() \
114 step /= sizeof(src[0])
116 #define ICV_MEAN_ENTRY_C1( sumtype ) \
118 ICV_MEAN_ENTRY_COMMON()
120 #define ICV_MEAN_ENTRY_C2( sumtype ) \
121 sumtype s0 = 0, s1 = 0; \
122 ICV_MEAN_ENTRY_COMMON()
124 #define ICV_MEAN_ENTRY_C3( sumtype ) \
125 sumtype s0 = 0, s1 = 0, s2 = 0; \
126 ICV_MEAN_ENTRY_COMMON()
128 #define ICV_MEAN_ENTRY_C4( sumtype ) \
129 sumtype s0 = 0, s1 = 0, s2 = 0, s3 = 0; \
130 ICV_MEAN_ENTRY_COMMON()
133 #define ICV_MEAN_ENTRY_BLOCK_COMMON( block_size ) \
134 int remaining = block_size; \
135 ICV_MEAN_ENTRY_COMMON()
137 #define ICV_MEAN_ENTRY_BLOCK_C1( sumtype, worktype, block_size )\
140 ICV_MEAN_ENTRY_BLOCK_COMMON( block_size )
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 )
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 )
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 )
158 /////////////////////////////////////// exit macros //////////////////////////////////////
160 #define ICV_MEAN_EXIT_COMMON() \
161 double scale = pix ? 1./pix : 0
163 #define ICV_MEAN_EXIT_C1( tmp ) \
164 ICV_MEAN_EXIT_COMMON(); \
165 mean[0] = scale*(double)tmp##0
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; \
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; \
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; \
189 t0 = scale*(double)tmp##2; \
190 t1 = scale*(double)tmp##3; \
194 #define ICV_MEAN_EXIT_BLOCK_C1() \
196 ICV_MEAN_EXIT_C1( sum )
198 #define ICV_MEAN_EXIT_BLOCK_C2() \
199 sum0 += s0; sum1 += s1; \
200 ICV_MEAN_EXIT_C2( sum )
202 #define ICV_MEAN_EXIT_BLOCK_C3() \
203 sum0 += s0; sum1 += s1; \
205 ICV_MEAN_EXIT_C3( sum )
207 #define ICV_MEAN_EXIT_BLOCK_C4() \
208 sum0 += s0; sum1 += s1; \
209 sum2 += s2; sum3 += s3; \
210 ICV_MEAN_EXIT_C4( sum )
212 ////////////////////////////////////// update macros /////////////////////////////////////
214 #define ICV_MEAN_UPDATE_COMMON( block_size )\
215 remaining = block_size
217 #define ICV_MEAN_UPDATE_C1( block_size ) \
218 ICV_MEAN_UPDATE_COMMON( block_size ); \
222 #define ICV_MEAN_UPDATE_C2( block_size ) \
223 ICV_MEAN_UPDATE_COMMON( block_size ); \
224 sum0 += s0; sum1 += s1; \
227 #define ICV_MEAN_UPDATE_C3( block_size ) \
228 ICV_MEAN_UPDATE_COMMON( block_size ); \
229 sum0 += s0; sum1 += s1; sum2 += s2; \
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
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)) \
247 ICV_MEAN_ENTRY_BLOCK_C##cn( sumtype, worktype, block_size );\
249 for( ; size.height--; src += step, mask += maskstep ) \
252 while( x < size.width ) \
254 int limit = MIN( remaining, size.width - x ); \
255 remaining -= limit; \
257 ICV_MEAN_CASE_C##cn( limit ); \
258 if( remaining == 0 ) \
260 ICV_MEAN_UPDATE_C##cn( block_size ); \
265 { ICV_MEAN_EXIT_BLOCK_C##cn(); } \
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)) \
278 ICV_MEAN_ENTRY_C##cn( sumtype ); \
280 for( ; size.height--; src += step, mask += maskstep ) \
283 ICV_MEAN_CASE_C##cn( size.width ); \
286 { ICV_MEAN_EXIT_C##cn( s ); } \
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 ) \
299 ICV_MEAN_ENTRY_BLOCK_C1( sumtype, worktype, block_size ); \
302 for( ; size.height--; src += step, mask += maskstep ) \
305 while( x < size.width ) \
307 int limit = MIN( remaining, size.width - x ); \
308 remaining -= limit; \
310 ICV_MEAN_COI_CASE( limit, cn ); \
311 if( remaining == 0 ) \
313 ICV_MEAN_UPDATE_C1( block_size ); \
318 { ICV_MEAN_EXIT_BLOCK_C1(); } \
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 ) \
331 ICV_MEAN_ENTRY_C1( sumtype ); \
334 for( ; size.height--; src += step, mask += maskstep ) \
337 ICV_MEAN_COI_CASE( size.width, cn ); \
340 { ICV_MEAN_EXIT_C1( s ); } \
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 )
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 )
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 )
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
378 CV_DEF_INIT_BIG_FUNC_TAB_2D( Mean, MR )
379 CV_DEF_INIT_FUNC_TAB_2D( Mean, CnCMR )
382 cvAvg( const void* img, const void* maskarr )
384 CvScalar mean = {{0,0,0,0}};
386 static CvBigFuncTable mean_tab;
387 static CvFuncTable meancoi_tab;
388 static int inittab = 0;
390 CV_FUNCNAME("cvAvg");
399 CV_CALL( mean = cvSum(img));
400 size = cvGetSize( img );
401 size.width *= size.height;
402 scale = size.width ? 1./size.width : 0;
404 mean.val[0] *= scale;
405 mean.val[1] *= scale;
406 mean.val[2] *= scale;
407 mean.val[3] *= scale;
412 int mat_step, mask_step;
414 CvMat stub, maskstub, *mat = (CvMat*)img, *mask = (CvMat*)maskarr;
418 icvInitMeanMRTable( &mean_tab );
419 icvInitMeanCnCMRTable( &meancoi_tab );
423 if( !CV_IS_MAT(mat) )
424 CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
426 if( !CV_IS_MAT(mask) )
427 CV_CALL( mask = cvGetMat( mask, &maskstub ));
429 if( !CV_IS_MASK_ARR(mask) )
430 CV_ERROR( CV_StsBadMask, "" );
432 if( !CV_ARE_SIZES_EQ( mat, mask ) )
433 CV_ERROR( CV_StsUnmatchedSizes, "" );
435 type = CV_MAT_TYPE( mat->type );
436 size = cvGetMatSize( mat );
438 mat_step = mat->step;
439 mask_step = mask->step;
441 if( CV_IS_MAT_CONT( mat->type & mask->type ))
443 size.width *= size.height;
445 mat_step = mask_step = CV_STUB_STEP;
448 if( CV_MAT_CN(type) == 1 || coi == 0 )
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" );
455 func = (CvFunc2D_2A1P)(mean_tab.fn_2d[type]);
458 CV_ERROR( CV_StsBadArg, cvUnsupportedFormat );
460 IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr,
461 mask_step, size, mean.val ));
465 CvFunc2DnC_2A1P func = (CvFunc2DnC_2A1P)(
466 meancoi_tab.fn_2d[CV_MAT_DEPTH(type)]);
469 CV_ERROR( CV_StsBadArg, cvUnsupportedFormat );
471 IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr,
472 mask_step, size, CV_MAT_CN(type), coi, mean.val ));