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
getAccTabIdx(int sdepth,int ddepth)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
ocl_accumulate(InputArray _src,InputArray _src2,InputOutputArray _dst,double alpha,InputArray _mask,int op_type)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 {
ipp_accumulate(InputArray _src,InputOutputArray _dst,InputArray _mask)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 {
skipSmallImages(int w,int h)245 template <> inline bool skipSmallImages<VX_KERNEL_ACCUMULATE>(int w, int h) { return w*h < 120 * 60; }
246 }
openvx_accumulate(InputArray _src,InputOutputArray _dst,InputArray _mask,double _weight,int opType)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 (const ivx::RuntimeError & e)
295 {
296 VX_DbgThrow(e.what());
297 }
298 catch (const ivx::WrapperError & e)
299 {
300 VX_DbgThrow(e.what());
301 }
302
303 return true;
304 }
305 }
306 #endif
307
accumulate(InputArray _src,InputOutputArray _dst,InputArray _mask)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 {
ipp_accumulate_square(InputArray _src,InputOutputArray _dst,InputArray _mask)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
accumulateSquare(InputArray _src,InputOutputArray _dst,InputArray _mask)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 {
ipp_accumulate_product(InputArray _src1,InputArray _src2,InputOutputArray _dst,InputArray _mask)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
accumulateProduct(InputArray _src1,InputArray _src2,InputOutputArray _dst,InputArray _mask)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 {
ipp_accumulate_weighted(InputArray _src,InputOutputArray _dst,double alpha,InputArray _mask)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
accumulateWeighted(InputArray _src,InputOutputArray _dst,double alpha,InputArray _mask)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
cvAcc(const void * arr,void * sumarr,const void * maskarr)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
cvSquareAcc(const void * arr,void * sumarr,const void * maskarr)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
cvMultiplyAcc(const void * arr1,const void * arr2,void * sumarr,const void * maskarr)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
cvRunningAvg(const void * arr,void * sumarr,double alpha,const void * maskarr)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