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
CV_DEF_INIT_BIG_FUNC_TAB_2D(Mean,MR)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