Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/imgproc/src/accum.cpp
16354 views
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
// License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15
// Copyright (C) 2014, Itseez Inc., all rights reserved.
16
// Third party copyrights are property of their respective owners.
17
/
18
// Redistribution and use in source and binary forms, with or without modification,
19
// are permitted provided that the following conditions are met:
20
//
21
// * Redistribution's of source code must retain the above copyright notice,
22
// this list of conditions and the following disclaimer.
23
//
24
// * Redistribution's in binary form must reproduce the above copyright notice,
25
// this list of conditions and the following disclaimer in the documentation
26
// and/or other materials provided with the distribution.
27
//
28
// * The name of the copyright holders may not be used to endorse or promote products
29
// derived from this software without specific prior written permission.
30
//
31
// This software is provided by the copyright holders and contributors "as is" and
32
// any express or implied warranties, including, but not limited to, the implied
33
// warranties of merchantability and fitness for a particular purpose are disclaimed.
34
// In no event shall the Intel Corporation or contributors be liable for any direct,
35
// indirect, incidental, special, exemplary, or consequential damages
36
// (including, but not limited to, procurement of substitute goods or services;
37
// loss of use, data, or profits; or business interruption) however caused
38
// and on any theory of liability, whether in contract, strict liability,
39
// or tort (including negligence or otherwise) arising in any way out of
40
// the use of this software, even if advised of the possibility of such damage.
41
//
42
//M*/
43
44
#include "precomp.hpp"
45
#include "opencl_kernels_imgproc.hpp"
46
#include "opencv2/core/hal/intrin.hpp"
47
#define CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
48
#include "accum.simd.hpp"
49
#include "accum.simd_declarations.hpp"
50
#include "opencv2/core/openvx/ovx_defs.hpp"
51
52
namespace cv
53
{
54
55
typedef void(*AccFunc)(const uchar*, uchar*, const uchar*, int, int);
56
typedef void(*AccProdFunc)(const uchar*, const uchar*, uchar*, const uchar*, int, int);
57
typedef void(*AccWFunc)(const uchar*, uchar*, const uchar*, int, int, double);
58
59
static AccFunc accTab[] =
60
{
61
(AccFunc)acc_8u32f, (AccFunc)acc_8u64f,
62
(AccFunc)acc_16u32f, (AccFunc)acc_16u64f,
63
(AccFunc)acc_32f, (AccFunc)acc_32f64f,
64
(AccFunc)acc_64f
65
};
66
67
static AccFunc accSqrTab[] =
68
{
69
(AccFunc)accSqr_8u32f, (AccFunc)accSqr_8u64f,
70
(AccFunc)accSqr_16u32f, (AccFunc)accSqr_16u64f,
71
(AccFunc)accSqr_32f, (AccFunc)accSqr_32f64f,
72
(AccFunc)accSqr_64f
73
};
74
75
static AccProdFunc accProdTab[] =
76
{
77
(AccProdFunc)accProd_8u32f, (AccProdFunc)accProd_8u64f,
78
(AccProdFunc)accProd_16u32f, (AccProdFunc)accProd_16u64f,
79
(AccProdFunc)accProd_32f, (AccProdFunc)accProd_32f64f,
80
(AccProdFunc)accProd_64f
81
};
82
83
static AccWFunc accWTab[] =
84
{
85
(AccWFunc)accW_8u32f, (AccWFunc)accW_8u64f,
86
(AccWFunc)accW_16u32f, (AccWFunc)accW_16u64f,
87
(AccWFunc)accW_32f, (AccWFunc)accW_32f64f,
88
(AccWFunc)accW_64f
89
};
90
91
inline int getAccTabIdx(int sdepth, int ddepth)
92
{
93
return sdepth == CV_8U && ddepth == CV_32F ? 0 :
94
sdepth == CV_8U && ddepth == CV_64F ? 1 :
95
sdepth == CV_16U && ddepth == CV_32F ? 2 :
96
sdepth == CV_16U && ddepth == CV_64F ? 3 :
97
sdepth == CV_32F && ddepth == CV_32F ? 4 :
98
sdepth == CV_32F && ddepth == CV_64F ? 5 :
99
sdepth == CV_64F && ddepth == CV_64F ? 6 : -1;
100
}
101
102
#ifdef HAVE_OPENCL
103
104
enum
105
{
106
ACCUMULATE = 0,
107
ACCUMULATE_SQUARE = 1,
108
ACCUMULATE_PRODUCT = 2,
109
ACCUMULATE_WEIGHTED = 3
110
};
111
112
static bool ocl_accumulate( InputArray _src, InputArray _src2, InputOutputArray _dst, double alpha,
113
InputArray _mask, int op_type )
114
{
115
CV_Assert(op_type == ACCUMULATE || op_type == ACCUMULATE_SQUARE ||
116
op_type == ACCUMULATE_PRODUCT || op_type == ACCUMULATE_WEIGHTED);
117
118
const ocl::Device & dev = ocl::Device::getDefault();
119
bool haveMask = !_mask.empty(), doubleSupport = dev.doubleFPConfig() > 0;
120
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype), ddepth = _dst.depth();
121
int kercn = haveMask ? cn : ocl::predictOptimalVectorWidthMax(_src, _src2, _dst), rowsPerWI = dev.isIntel() ? 4 : 1;
122
123
if (!doubleSupport && (sdepth == CV_64F || ddepth == CV_64F))
124
return false;
125
126
const char * const opMap[4] = { "ACCUMULATE", "ACCUMULATE_SQUARE", "ACCUMULATE_PRODUCT",
127
"ACCUMULATE_WEIGHTED" };
128
129
char cvt[40];
130
ocl::Kernel k("accumulate", ocl::imgproc::accumulate_oclsrc,
131
format("-D %s%s -D srcT1=%s -D cn=%d -D dstT1=%s%s -D rowsPerWI=%d -D convertToDT=%s",
132
opMap[op_type], haveMask ? " -D HAVE_MASK" : "",
133
ocl::typeToStr(sdepth), kercn, ocl::typeToStr(ddepth),
134
doubleSupport ? " -D DOUBLE_SUPPORT" : "", rowsPerWI,
135
ocl::convertTypeStr(sdepth, ddepth, 1, cvt)));
136
if (k.empty())
137
return false;
138
139
UMat src = _src.getUMat(), src2 = _src2.getUMat(), dst = _dst.getUMat(), mask = _mask.getUMat();
140
141
ocl::KernelArg srcarg = ocl::KernelArg::ReadOnlyNoSize(src),
142
src2arg = ocl::KernelArg::ReadOnlyNoSize(src2),
143
dstarg = ocl::KernelArg::ReadWrite(dst, cn, kercn),
144
maskarg = ocl::KernelArg::ReadOnlyNoSize(mask);
145
146
int argidx = k.set(0, srcarg);
147
if (op_type == ACCUMULATE_PRODUCT)
148
argidx = k.set(argidx, src2arg);
149
argidx = k.set(argidx, dstarg);
150
if (op_type == ACCUMULATE_WEIGHTED)
151
{
152
if (ddepth == CV_32F)
153
argidx = k.set(argidx, (float)alpha);
154
else
155
argidx = k.set(argidx, alpha);
156
}
157
if (haveMask)
158
k.set(argidx, maskarg);
159
160
size_t globalsize[2] = { (size_t)src.cols * cn / kercn, ((size_t)src.rows + rowsPerWI - 1) / rowsPerWI };
161
return k.run(2, globalsize, NULL, false);
162
}
163
164
#endif
165
166
}
167
168
#if defined(HAVE_IPP)
169
namespace cv
170
{
171
static bool ipp_accumulate(InputArray _src, InputOutputArray _dst, InputArray _mask)
172
{
173
CV_INSTRUMENT_REGION_IPP();
174
175
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
176
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype);
177
178
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
179
180
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && (mask.empty() || mask.isContinuous())))
181
{
182
typedef IppStatus (CV_STDCALL * IppiAdd)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep, IppiSize roiSize);
183
typedef IppStatus (CV_STDCALL * IppiAddMask)(const void * pSrc, int srcStep, const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst,
184
int srcDstStep, IppiSize roiSize);
185
IppiAdd ippiAdd_I = 0;
186
IppiAddMask ippiAdd_IM = 0;
187
188
if (mask.empty())
189
{
190
CV_SUPPRESS_DEPRECATED_START
191
ippiAdd_I = sdepth == CV_8U && ddepth == CV_32F ? (IppiAdd)ippiAdd_8u32f_C1IR :
192
sdepth == CV_16U && ddepth == CV_32F ? (IppiAdd)ippiAdd_16u32f_C1IR :
193
sdepth == CV_32F && ddepth == CV_32F ? (IppiAdd)ippiAdd_32f_C1IR : 0;
194
CV_SUPPRESS_DEPRECATED_END
195
}
196
else if (scn == 1)
197
{
198
ippiAdd_IM = sdepth == CV_8U && ddepth == CV_32F ? (IppiAddMask)ippiAdd_8u32f_C1IMR :
199
sdepth == CV_16U && ddepth == CV_32F ? (IppiAddMask)ippiAdd_16u32f_C1IMR :
200
sdepth == CV_32F && ddepth == CV_32F ? (IppiAddMask)ippiAdd_32f_C1IMR : 0;
201
}
202
203
if (ippiAdd_I || ippiAdd_IM)
204
{
205
IppStatus status = ippStsErr;
206
207
Size size = src.size();
208
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
209
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
210
{
211
srcstep = static_cast<int>(src.total() * src.elemSize());
212
dststep = static_cast<int>(dst.total() * dst.elemSize());
213
maskstep = static_cast<int>(mask.total() * mask.elemSize());
214
size.width = static_cast<int>(src.total());
215
size.height = 1;
216
}
217
size.width *= scn;
218
219
if (ippiAdd_I)
220
status = CV_INSTRUMENT_FUN_IPP(ippiAdd_I, src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
221
else if (ippiAdd_IM)
222
status = CV_INSTRUMENT_FUN_IPP(ippiAdd_IM, src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
223
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
224
225
if (status >= 0)
226
return true;
227
}
228
}
229
return false;
230
}
231
}
232
#endif
233
234
#ifdef HAVE_OPENVX
235
namespace cv
236
{
237
enum
238
{
239
VX_ACCUMULATE_OP = 0,
240
VX_ACCUMULATE_SQUARE_OP = 1,
241
VX_ACCUMULATE_WEIGHTED_OP = 2
242
};
243
244
namespace ovx {
245
template <> inline bool skipSmallImages<VX_KERNEL_ACCUMULATE>(int w, int h) { return w*h < 120 * 60; }
246
}
247
static bool openvx_accumulate(InputArray _src, InputOutputArray _dst, InputArray _mask, double _weight, int opType)
248
{
249
Mat srcMat = _src.getMat(), dstMat = _dst.getMat();
250
if (ovx::skipSmallImages<VX_KERNEL_ACCUMULATE>(srcMat.cols, srcMat.rows))
251
return false;
252
if(!_mask.empty() ||
253
(opType == VX_ACCUMULATE_WEIGHTED_OP && dstMat.type() != CV_8UC1 ) ||
254
(opType != VX_ACCUMULATE_WEIGHTED_OP && dstMat.type() != CV_16SC1 ) ||
255
srcMat.type() != CV_8UC1)
256
{
257
return false;
258
}
259
//TODO: handle different number of channels (channel extract && channel combine)
260
//TODO: handle mask (threshold mask to 0xff && bitwise AND with src)
261
//(both things can be done by creating a graph)
262
263
try
264
{
265
ivx::Context context = ovx::getOpenVXContext();
266
ivx::Image srcImage = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(srcMat.type()),
267
ivx::Image::createAddressing(srcMat), srcMat.data);
268
ivx::Image dstImage = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(dstMat.type()),
269
ivx::Image::createAddressing(dstMat), dstMat.data);
270
ivx::Scalar shift = ivx::Scalar::create<VX_TYPE_UINT32>(context, 0);
271
ivx::Scalar alpha = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _weight);
272
273
switch (opType)
274
{
275
case VX_ACCUMULATE_OP:
276
ivx::IVX_CHECK_STATUS(vxuAccumulateImage(context, srcImage, dstImage));
277
break;
278
case VX_ACCUMULATE_SQUARE_OP:
279
ivx::IVX_CHECK_STATUS(vxuAccumulateSquareImage(context, srcImage, shift, dstImage));
280
break;
281
case VX_ACCUMULATE_WEIGHTED_OP:
282
ivx::IVX_CHECK_STATUS(vxuAccumulateWeightedImage(context, srcImage, alpha, dstImage));
283
break;
284
default:
285
break;
286
}
287
288
#ifdef VX_VERSION_1_1
289
//we should take user memory back before release
290
//(it's not done automatically according to standard)
291
srcImage.swapHandle(); dstImage.swapHandle();
292
#endif
293
}
294
catch (ivx::RuntimeError & e)
295
{
296
VX_DbgThrow(e.what());
297
}
298
catch (ivx::WrapperError & e)
299
{
300
VX_DbgThrow(e.what());
301
}
302
303
return true;
304
}
305
}
306
#endif
307
308
void cv::accumulate( InputArray _src, InputOutputArray _dst, InputArray _mask )
309
{
310
CV_INSTRUMENT_REGION();
311
312
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
313
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
314
315
CV_Assert( _src.sameSize(_dst) && dcn == scn );
316
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
317
318
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
319
ocl_accumulate(_src, noArray(), _dst, 0.0, _mask, ACCUMULATE))
320
321
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && (_mask.empty() || _mask.isContinuous()))),
322
ipp_accumulate(_src, _dst, _mask));
323
324
CV_OVX_RUN(_src.dims() <= 2,
325
openvx_accumulate(_src, _dst, _mask, 0.0, VX_ACCUMULATE_OP))
326
327
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
328
329
330
int fidx = getAccTabIdx(sdepth, ddepth);
331
AccFunc func = fidx >= 0 ? accTab[fidx] : 0;
332
CV_Assert( func != 0 );
333
334
const Mat* arrays[] = {&src, &dst, &mask, 0};
335
uchar* ptrs[3] = {};
336
NAryMatIterator it(arrays, ptrs);
337
int len = (int)it.size;
338
339
for( size_t i = 0; i < it.nplanes; i++, ++it )
340
func(ptrs[0], ptrs[1], ptrs[2], len, scn);
341
}
342
343
#if defined(HAVE_IPP)
344
namespace cv
345
{
346
static bool ipp_accumulate_square(InputArray _src, InputOutputArray _dst, InputArray _mask)
347
{
348
CV_INSTRUMENT_REGION_IPP();
349
350
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
351
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype);
352
353
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
354
355
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && (mask.empty() || mask.isContinuous())))
356
{
357
typedef IppStatus (CV_STDCALL * ippiAddSquare)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep, IppiSize roiSize);
358
typedef IppStatus (CV_STDCALL * ippiAddSquareMask)(const void * pSrc, int srcStep, const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst,
359
int srcDstStep, IppiSize roiSize);
360
ippiAddSquare ippiAddSquare_I = 0;
361
ippiAddSquareMask ippiAddSquare_IM = 0;
362
363
if (mask.empty())
364
{
365
ippiAddSquare_I = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_8u32f_C1IR :
366
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_16u32f_C1IR :
367
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_32f_C1IR : 0;
368
}
369
else if (scn == 1)
370
{
371
ippiAddSquare_IM = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_8u32f_C1IMR :
372
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_16u32f_C1IMR :
373
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_32f_C1IMR : 0;
374
}
375
376
if (ippiAddSquare_I || ippiAddSquare_IM)
377
{
378
IppStatus status = ippStsErr;
379
380
Size size = src.size();
381
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
382
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
383
{
384
srcstep = static_cast<int>(src.total() * src.elemSize());
385
dststep = static_cast<int>(dst.total() * dst.elemSize());
386
maskstep = static_cast<int>(mask.total() * mask.elemSize());
387
size.width = static_cast<int>(src.total());
388
size.height = 1;
389
}
390
size.width *= scn;
391
392
if (ippiAddSquare_I)
393
status = CV_INSTRUMENT_FUN_IPP(ippiAddSquare_I, src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
394
else if (ippiAddSquare_IM)
395
status = CV_INSTRUMENT_FUN_IPP(ippiAddSquare_IM, src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
396
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
397
398
if (status >= 0)
399
return true;
400
}
401
}
402
return false;
403
}
404
}
405
#endif
406
407
void cv::accumulateSquare( InputArray _src, InputOutputArray _dst, InputArray _mask )
408
{
409
CV_INSTRUMENT_REGION();
410
411
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
412
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
413
414
CV_Assert( _src.sameSize(_dst) && dcn == scn );
415
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
416
417
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
418
ocl_accumulate(_src, noArray(), _dst, 0.0, _mask, ACCUMULATE_SQUARE))
419
420
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && (_mask.empty() || _mask.isContinuous()))),
421
ipp_accumulate_square(_src, _dst, _mask));
422
423
CV_OVX_RUN(_src.dims() <= 2,
424
openvx_accumulate(_src, _dst, _mask, 0.0, VX_ACCUMULATE_SQUARE_OP))
425
426
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
427
428
int fidx = getAccTabIdx(sdepth, ddepth);
429
AccFunc func = fidx >= 0 ? accSqrTab[fidx] : 0;
430
CV_Assert( func != 0 );
431
432
const Mat* arrays[] = {&src, &dst, &mask, 0};
433
uchar* ptrs[3] = {};
434
NAryMatIterator it(arrays, ptrs);
435
int len = (int)it.size;
436
437
for( size_t i = 0; i < it.nplanes; i++, ++it )
438
func(ptrs[0], ptrs[1], ptrs[2], len, scn);
439
}
440
441
#if defined(HAVE_IPP)
442
namespace cv
443
{
444
static bool ipp_accumulate_product(InputArray _src1, InputArray _src2,
445
InputOutputArray _dst, InputArray _mask)
446
{
447
CV_INSTRUMENT_REGION_IPP();
448
449
int stype = _src1.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
450
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype);
451
452
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
453
454
if (src1.dims <= 2 || (src1.isContinuous() && src2.isContinuous() && dst.isContinuous()))
455
{
456
typedef IppStatus (CV_STDCALL * ippiAddProduct)(const void * pSrc1, int src1Step, const void * pSrc2,
457
int src2Step, Ipp32f * pSrcDst, int srcDstStep, IppiSize roiSize);
458
typedef IppStatus (CV_STDCALL * ippiAddProductMask)(const void * pSrc1, int src1Step, const void * pSrc2, int src2Step,
459
const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst, int srcDstStep, IppiSize roiSize);
460
ippiAddProduct ippiAddProduct_I = 0;
461
ippiAddProductMask ippiAddProduct_IM = 0;
462
463
if (mask.empty())
464
{
465
ippiAddProduct_I = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_8u32f_C1IR :
466
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_16u32f_C1IR :
467
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_32f_C1IR : 0;
468
}
469
else if (scn == 1)
470
{
471
ippiAddProduct_IM = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_8u32f_C1IMR :
472
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_16u32f_C1IMR :
473
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_32f_C1IMR : 0;
474
}
475
476
if (ippiAddProduct_I || ippiAddProduct_IM)
477
{
478
IppStatus status = ippStsErr;
479
480
Size size = src1.size();
481
int src1step = (int)src1.step, src2step = (int)src2.step, dststep = (int)dst.step, maskstep = (int)mask.step;
482
if (src1.isContinuous() && src2.isContinuous() && dst.isContinuous() && mask.isContinuous())
483
{
484
src1step = static_cast<int>(src1.total() * src1.elemSize());
485
src2step = static_cast<int>(src2.total() * src2.elemSize());
486
dststep = static_cast<int>(dst.total() * dst.elemSize());
487
maskstep = static_cast<int>(mask.total() * mask.elemSize());
488
size.width = static_cast<int>(src1.total());
489
size.height = 1;
490
}
491
size.width *= scn;
492
493
if (ippiAddProduct_I)
494
status = CV_INSTRUMENT_FUN_IPP(ippiAddProduct_I, src1.ptr(), src1step, src2.ptr(), src2step, dst.ptr<Ipp32f>(),
495
dststep, ippiSize(size.width, size.height));
496
else if (ippiAddProduct_IM)
497
status = CV_INSTRUMENT_FUN_IPP(ippiAddProduct_IM, src1.ptr(), src1step, src2.ptr(), src2step, mask.ptr<Ipp8u>(), maskstep,
498
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
499
500
if (status >= 0)
501
return true;
502
}
503
}
504
return false;
505
}
506
}
507
#endif
508
509
510
511
void cv::accumulateProduct( InputArray _src1, InputArray _src2,
512
InputOutputArray _dst, InputArray _mask )
513
{
514
CV_INSTRUMENT_REGION();
515
516
int stype = _src1.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
517
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
518
519
CV_Assert( _src1.sameSize(_src2) && stype == _src2.type() );
520
CV_Assert( _src1.sameSize(_dst) && dcn == scn );
521
CV_Assert( _mask.empty() || (_src1.sameSize(_mask) && _mask.type() == CV_8U) );
522
523
CV_OCL_RUN(_src1.dims() <= 2 && _dst.isUMat(),
524
ocl_accumulate(_src1, _src2, _dst, 0.0, _mask, ACCUMULATE_PRODUCT))
525
526
CV_IPP_RUN( (_src1.dims() <= 2 || (_src1.isContinuous() && _src2.isContinuous() && _dst.isContinuous())),
527
ipp_accumulate_product(_src1, _src2, _dst, _mask));
528
529
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
530
531
int fidx = getAccTabIdx(sdepth, ddepth);
532
AccProdFunc func = fidx >= 0 ? accProdTab[fidx] : 0;
533
CV_Assert( func != 0 );
534
535
const Mat* arrays[] = {&src1, &src2, &dst, &mask, 0};
536
uchar* ptrs[4] = {};
537
NAryMatIterator it(arrays, ptrs);
538
int len = (int)it.size;
539
540
for( size_t i = 0; i < it.nplanes; i++, ++it )
541
func(ptrs[0], ptrs[1], ptrs[2], ptrs[3], len, scn);
542
}
543
544
#if defined(HAVE_IPP)
545
namespace cv
546
{
547
static bool ipp_accumulate_weighted( InputArray _src, InputOutputArray _dst,
548
double alpha, InputArray _mask )
549
{
550
CV_INSTRUMENT_REGION_IPP();
551
552
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
553
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype);
554
555
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
556
557
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && mask.isContinuous()))
558
{
559
typedef IppStatus (CV_STDCALL * ippiAddWeighted)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep,
560
IppiSize roiSize, Ipp32f alpha);
561
typedef IppStatus (CV_STDCALL * ippiAddWeightedMask)(const void * pSrc, int srcStep, const Ipp8u * pMask,
562
int maskStep, Ipp32f * pSrcDst,
563
int srcDstStep, IppiSize roiSize, Ipp32f alpha);
564
ippiAddWeighted ippiAddWeighted_I = 0;
565
ippiAddWeightedMask ippiAddWeighted_IM = 0;
566
567
if (mask.empty())
568
{
569
ippiAddWeighted_I = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_8u32f_C1IR :
570
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_16u32f_C1IR :
571
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_32f_C1IR : 0;
572
}
573
else if (scn == 1)
574
{
575
ippiAddWeighted_IM = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_8u32f_C1IMR :
576
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_16u32f_C1IMR :
577
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_32f_C1IMR : 0;
578
}
579
580
if (ippiAddWeighted_I || ippiAddWeighted_IM)
581
{
582
IppStatus status = ippStsErr;
583
584
Size size = src.size();
585
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
586
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
587
{
588
srcstep = static_cast<int>(src.total() * src.elemSize());
589
dststep = static_cast<int>(dst.total() * dst.elemSize());
590
maskstep = static_cast<int>(mask.total() * mask.elemSize());
591
size.width = static_cast<int>((int)src.total());
592
size.height = 1;
593
}
594
size.width *= scn;
595
596
if (ippiAddWeighted_I)
597
status = CV_INSTRUMENT_FUN_IPP(ippiAddWeighted_I, src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha);
598
else if (ippiAddWeighted_IM)
599
status = CV_INSTRUMENT_FUN_IPP(ippiAddWeighted_IM, src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
600
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha);
601
602
if (status >= 0)
603
return true;
604
}
605
}
606
return false;
607
}
608
}
609
#endif
610
611
void cv::accumulateWeighted( InputArray _src, InputOutputArray _dst,
612
double alpha, InputArray _mask )
613
{
614
CV_INSTRUMENT_REGION();
615
616
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
617
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
618
619
CV_Assert( _src.sameSize(_dst) && dcn == scn );
620
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
621
622
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
623
ocl_accumulate(_src, noArray(), _dst, alpha, _mask, ACCUMULATE_WEIGHTED))
624
625
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && _mask.isContinuous())), ipp_accumulate_weighted(_src, _dst, alpha, _mask));
626
627
CV_OVX_RUN(_src.dims() <= 2,
628
openvx_accumulate(_src, _dst, _mask, alpha, VX_ACCUMULATE_WEIGHTED_OP))
629
630
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
631
632
633
int fidx = getAccTabIdx(sdepth, ddepth);
634
AccWFunc func = fidx >= 0 ? accWTab[fidx] : 0;
635
CV_Assert( func != 0 );
636
637
const Mat* arrays[] = {&src, &dst, &mask, 0};
638
uchar* ptrs[3] = {};
639
NAryMatIterator it(arrays, ptrs);
640
int len = (int)it.size;
641
642
for( size_t i = 0; i < it.nplanes; i++, ++it )
643
func(ptrs[0], ptrs[1], ptrs[2], len, scn, alpha);
644
}
645
646
647
CV_IMPL void
648
cvAcc( const void* arr, void* sumarr, const void* maskarr )
649
{
650
cv::Mat src = cv::cvarrToMat(arr), dst = cv::cvarrToMat(sumarr), mask;
651
if( maskarr )
652
mask = cv::cvarrToMat(maskarr);
653
cv::accumulate( src, dst, mask );
654
}
655
656
CV_IMPL void
657
cvSquareAcc( const void* arr, void* sumarr, const void* maskarr )
658
{
659
cv::Mat src = cv::cvarrToMat(arr), dst = cv::cvarrToMat(sumarr), mask;
660
if( maskarr )
661
mask = cv::cvarrToMat(maskarr);
662
cv::accumulateSquare( src, dst, mask );
663
}
664
665
CV_IMPL void
666
cvMultiplyAcc( const void* arr1, const void* arr2,
667
void* sumarr, const void* maskarr )
668
{
669
cv::Mat src1 = cv::cvarrToMat(arr1), src2 = cv::cvarrToMat(arr2);
670
cv::Mat dst = cv::cvarrToMat(sumarr), mask;
671
if( maskarr )
672
mask = cv::cvarrToMat(maskarr);
673
cv::accumulateProduct( src1, src2, dst, mask );
674
}
675
676
CV_IMPL void
677
cvRunningAvg( const void* arr, void* sumarr, double alpha, const void* maskarr )
678
{
679
cv::Mat src = cv::cvarrToMat(arr), dst = cv::cvarrToMat(sumarr), mask;
680
if( maskarr )
681
mask = cv::cvarrToMat(maskarr);
682
cv::accumulateWeighted( src, dst, alpha, mask );
683
}
684
685
/* End of file. */
686
687