1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 #include "test_precomp.hpp"
6 namespace opencv_test { namespace {
8 const int ARITHM_NTESTS = 1000;
9 const int ARITHM_RNG_SEED = -1;
10 const int ARITHM_MAX_CHANNELS = 4;
11 const int ARITHM_MAX_NDIMS = 4;
12 const int ARITHM_MAX_SIZE_LOG = 10;
16 enum { FIX_ALPHA=1, FIX_BETA=2, FIX_GAMMA=4, REAL_GAMMA=8, SUPPORT_MASK=16, SCALAR_OUTPUT=32, SUPPORT_MULTICHANNELMASK=64 };
17 BaseElemWiseOp(int _ninputs, int _flags, double _alpha, double _beta,
18 Scalar _gamma=Scalar::all(0), int _context=1)
19 : ninputs(_ninputs), flags(_flags), alpha(_alpha), beta(_beta), gamma(_gamma), context(_context) {}
20 BaseElemWiseOp() { flags = 0; alpha = beta = 0; gamma = Scalar::all(0); ninputs = 0; context = 1; }
21 virtual ~BaseElemWiseOp() {}
22 virtual void op(const vector<Mat>&, Mat&, const Mat&) {}
23 virtual void refop(const vector<Mat>&, Mat&, const Mat&) {}
24 virtual void getValueRange(int depth, double& minval, double& maxval)
26 minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.;
27 maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.;
30 virtual void getRandomSize(RNG& rng, vector<int>& size)
32 cvtest::randomSize(rng, 2, ARITHM_MAX_NDIMS, ARITHM_MAX_SIZE_LOG, size);
35 virtual int getRandomType(RNG& rng)
37 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1,
38 ninputs > 1 ? ARITHM_MAX_CHANNELS : 4);
41 virtual double getMaxErr(int depth) { return depth < CV_32F ? 1 : depth == CV_32F ? 1e-5 : 1e-12; }
42 virtual void generateScalars(int depth, RNG& rng)
46 if( !(flags & FIX_ALPHA) )
48 alpha = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2);
49 alpha *= rng.uniform(0, 2) ? 1 : -1;
51 if( !(flags & FIX_BETA) )
53 beta = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2);
54 beta *= rng.uniform(0, 2) ? 1 : -1;
57 if( !(flags & FIX_GAMMA) )
59 for( int i = 0; i < 4; i++ )
61 gamma[i] = exp(rng.uniform(-1, 6)*m*CV_LOG2);
62 gamma[i] *= rng.uniform(0, 2) ? 1 : -1;
64 if( flags & REAL_GAMMA )
65 gamma = Scalar::all(gamma[0]);
72 db = Mat(1, 1, CV_64F, &alpha);
73 db.convertTo(fl, CV_32F);
74 fl.convertTo(db, CV_64F);
76 db = Mat(1, 1, CV_64F, &beta);
77 db.convertTo(fl, CV_32F);
78 fl.convertTo(db, CV_64F);
80 db = Mat(1, 4, CV_64F, &gamma[0]);
81 db.convertTo(fl, CV_32F);
82 fl.convertTo(db, CV_64F);
95 struct BaseAddOp : public BaseElemWiseOp
97 BaseAddOp(int _ninputs, int _flags, double _alpha, double _beta, Scalar _gamma=Scalar::all(0))
98 : BaseElemWiseOp(_ninputs, _flags, _alpha, _beta, _gamma) {}
100 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
105 cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, temp, src[0].type());
106 cvtest::copy(temp, dst, mask);
109 cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, dst, src[0].type());
114 struct AddOp : public BaseAddOp
116 AddOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {}
117 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
120 cv::add(src[0], src[1], dst);
122 cv::add(src[0], src[1], dst, mask);
127 struct SubOp : public BaseAddOp
129 SubOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, -1, Scalar::all(0)) {}
130 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
133 cv::subtract(src[0], src[1], dst);
135 cv::subtract(src[0], src[1], dst, mask);
140 struct AddSOp : public BaseAddOp
142 AddSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, 1, 0, Scalar::all(0)) {}
143 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
146 cv::add(src[0], gamma, dst);
148 cv::add(src[0], gamma, dst, mask);
153 struct SubRSOp : public BaseAddOp
155 SubRSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, -1, 0, Scalar::all(0)) {}
156 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
159 cv::subtract(gamma, src[0], dst);
161 cv::subtract(gamma, src[0], dst, mask);
166 struct ScaleAddOp : public BaseAddOp
168 ScaleAddOp() : BaseAddOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
169 void op(const vector<Mat>& src, Mat& dst, const Mat&)
171 cv::scaleAdd(src[0], alpha, src[1], dst);
173 double getMaxErr(int depth)
175 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-4 : 1e-12;
180 struct AddWeightedOp : public BaseAddOp
182 AddWeightedOp() : BaseAddOp(2, REAL_GAMMA, 1, 1, Scalar::all(0)) {}
183 void op(const vector<Mat>& src, Mat& dst, const Mat&)
185 cv::addWeighted(src[0], alpha, src[1], beta, gamma[0], dst);
187 double getMaxErr(int depth)
189 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-10;
193 struct MulOp : public BaseElemWiseOp
195 MulOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
196 void getValueRange(int depth, double& minval, double& maxval)
198 minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.;
199 maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.;
200 minval = std::max(minval, -30000.);
201 maxval = std::min(maxval, 30000.);
203 void op(const vector<Mat>& src, Mat& dst, const Mat&)
205 cv::multiply(src[0], src[1], dst, alpha);
207 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
209 cvtest::multiply(src[0], src[1], dst, alpha);
211 double getMaxErr(int depth)
213 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
217 struct DivOp : public BaseElemWiseOp
219 DivOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
220 void op(const vector<Mat>& src, Mat& dst, const Mat&)
222 cv::divide(src[0], src[1], dst, alpha);
224 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
226 cvtest::divide(src[0], src[1], dst, alpha);
228 double getMaxErr(int depth)
230 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
234 struct RecipOp : public BaseElemWiseOp
236 RecipOp() : BaseElemWiseOp(1, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
237 void op(const vector<Mat>& src, Mat& dst, const Mat&)
239 cv::divide(alpha, src[0], dst);
241 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
243 cvtest::divide(Mat(), src[0], dst, alpha);
245 double getMaxErr(int depth)
247 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
251 struct AbsDiffOp : public BaseAddOp
253 AbsDiffOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, -1, Scalar::all(0)) {}
254 void op(const vector<Mat>& src, Mat& dst, const Mat&)
256 absdiff(src[0], src[1], dst);
258 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
260 cvtest::add(src[0], 1, src[1], -1, Scalar::all(0), dst, src[0].type(), true);
264 struct AbsDiffSOp : public BaseAddOp
266 AbsDiffSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA, 1, 0, Scalar::all(0)) {}
267 void op(const vector<Mat>& src, Mat& dst, const Mat&)
269 absdiff(src[0], gamma, dst);
271 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
273 cvtest::add(src[0], 1, Mat(), 0, -gamma, dst, src[0].type(), true);
277 struct LogicOp : public BaseElemWiseOp
279 LogicOp(char _opcode) : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)), opcode(_opcode) {}
280 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
283 cv::bitwise_and(src[0], src[1], dst, mask);
284 else if( opcode == '|' )
285 cv::bitwise_or(src[0], src[1], dst, mask);
287 cv::bitwise_xor(src[0], src[1], dst, mask);
289 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
294 cvtest::logicOp(src[0], src[1], temp, opcode);
295 cvtest::copy(temp, dst, mask);
298 cvtest::logicOp(src[0], src[1], dst, opcode);
300 double getMaxErr(int)
307 struct LogicSOp : public BaseElemWiseOp
309 LogicSOp(char _opcode)
310 : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+(_opcode != '~' ? SUPPORT_MASK : 0), 1, 1, Scalar::all(0)), opcode(_opcode) {}
311 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
314 cv::bitwise_and(src[0], gamma, dst, mask);
315 else if( opcode == '|' )
316 cv::bitwise_or(src[0], gamma, dst, mask);
317 else if( opcode == '^' )
318 cv::bitwise_xor(src[0], gamma, dst, mask);
320 cv::bitwise_not(src[0], dst);
322 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
327 cvtest::logicOp(src[0], gamma, temp, opcode);
328 cvtest::copy(temp, dst, mask);
331 cvtest::logicOp(src[0], gamma, dst, opcode);
333 double getMaxErr(int)
340 struct MinOp : public BaseElemWiseOp
342 MinOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
343 void op(const vector<Mat>& src, Mat& dst, const Mat&)
345 cv::min(src[0], src[1], dst);
347 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
349 cvtest::min(src[0], src[1], dst);
351 double getMaxErr(int)
357 struct MaxOp : public BaseElemWiseOp
359 MaxOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
360 void op(const vector<Mat>& src, Mat& dst, const Mat&)
362 cv::max(src[0], src[1], dst);
364 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
366 cvtest::max(src[0], src[1], dst);
368 double getMaxErr(int)
374 struct MinSOp : public BaseElemWiseOp
376 MinSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
377 void op(const vector<Mat>& src, Mat& dst, const Mat&)
379 cv::min(src[0], gamma[0], dst);
381 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
383 cvtest::min(src[0], gamma[0], dst);
385 double getMaxErr(int)
391 struct MaxSOp : public BaseElemWiseOp
393 MaxSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
394 void op(const vector<Mat>& src, Mat& dst, const Mat&)
396 cv::max(src[0], gamma[0], dst);
398 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
400 cvtest::max(src[0], gamma[0], dst);
402 double getMaxErr(int)
408 struct CmpOp : public BaseElemWiseOp
410 CmpOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) { cmpop = 0; }
411 void generateScalars(int depth, RNG& rng)
413 BaseElemWiseOp::generateScalars(depth, rng);
414 cmpop = rng.uniform(0, 6);
416 void op(const vector<Mat>& src, Mat& dst, const Mat&)
418 cv::compare(src[0], src[1], dst, cmpop);
420 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
422 cvtest::compare(src[0], src[1], dst, cmpop);
424 int getRandomType(RNG& rng)
426 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
429 double getMaxErr(int)
436 struct CmpSOp : public BaseElemWiseOp
438 CmpSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) { cmpop = 0; }
439 void generateScalars(int depth, RNG& rng)
441 BaseElemWiseOp::generateScalars(depth, rng);
442 cmpop = rng.uniform(0, 6);
444 gamma[0] = cvRound(gamma[0]);
446 void op(const vector<Mat>& src, Mat& dst, const Mat&)
448 cv::compare(src[0], gamma[0], dst, cmpop);
450 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
452 cvtest::compare(src[0], gamma[0], dst, cmpop);
454 int getRandomType(RNG& rng)
456 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
458 double getMaxErr(int)
466 struct CopyOp : public BaseElemWiseOp
468 CopyOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SUPPORT_MULTICHANNELMASK, 1, 1, Scalar::all(0)) { }
469 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
471 src[0].copyTo(dst, mask);
473 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
475 cvtest::copy(src[0], dst, mask);
477 int getRandomType(RNG& rng)
479 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
481 double getMaxErr(int)
488 struct SetOp : public BaseElemWiseOp
490 SetOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+SUPPORT_MASK+SUPPORT_MULTICHANNELMASK, 1, 1, Scalar::all(0)) {}
491 void op(const vector<Mat>&, Mat& dst, const Mat& mask)
493 dst.setTo(gamma, mask);
495 void refop(const vector<Mat>&, Mat& dst, const Mat& mask)
497 cvtest::set(dst, gamma, mask);
499 int getRandomType(RNG& rng)
501 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
503 double getMaxErr(int)
509 template<typename _Tp, typename _WTp> static void
510 inRangeS_(const _Tp* src, const _WTp* a, const _WTp* b, uchar* dst, size_t total, int cn)
514 for( i = 0; i < total; i++ )
517 dst[i] = (a[0] <= val && val <= b[0]) ? uchar(255) : 0;
519 for( c = 1; c < cn; c++ )
521 for( i = 0; i < total; i++ )
523 _Tp val = src[i*cn + c];
524 dst[i] = a[c] <= val && val <= b[c] ? dst[i] : 0;
529 template<typename _Tp> static void inRange_(const _Tp* src, const _Tp* a, const _Tp* b, uchar* dst, size_t total, int cn)
533 for( i = 0; i < total; i++ )
536 dst[i] = a[i*cn] <= val && val <= b[i*cn] ? 255 : 0;
538 for( c = 1; c < cn; c++ )
540 for( i = 0; i < total; i++ )
542 _Tp val = src[i*cn + c];
543 dst[i] = a[i*cn + c] <= val && val <= b[i*cn + c] ? dst[i] : 0;
548 namespace reference {
550 static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst)
552 CV_Assert( src.type() == lb.type() && src.type() == rb.type() &&
553 src.size == lb.size && src.size == rb.size );
554 dst.create( src.dims, &src.size[0], CV_8U );
555 const Mat *arrays[]={&src, &lb, &rb, &dst, 0};
558 NAryMatIterator it(arrays, planes);
559 size_t total = planes[0].total();
560 size_t i, nplanes = it.nplanes;
561 int depth = src.depth(), cn = src.channels();
563 for( i = 0; i < nplanes; i++, ++it )
565 const uchar* sptr = planes[0].ptr();
566 const uchar* aptr = planes[1].ptr();
567 const uchar* bptr = planes[2].ptr();
568 uchar* dptr = planes[3].ptr();
573 inRange_((const uchar*)sptr, (const uchar*)aptr, (const uchar*)bptr, dptr, total, cn);
576 inRange_((const schar*)sptr, (const schar*)aptr, (const schar*)bptr, dptr, total, cn);
579 inRange_((const ushort*)sptr, (const ushort*)aptr, (const ushort*)bptr, dptr, total, cn);
582 inRange_((const short*)sptr, (const short*)aptr, (const short*)bptr, dptr, total, cn);
585 inRange_((const int*)sptr, (const int*)aptr, (const int*)bptr, dptr, total, cn);
588 inRange_((const float*)sptr, (const float*)aptr, (const float*)bptr, dptr, total, cn);
591 inRange_((const double*)sptr, (const double*)aptr, (const double*)bptr, dptr, total, cn);
594 CV_Error(CV_StsUnsupportedFormat, "");
599 static void inRangeS(const Mat& src, const Scalar& lb, const Scalar& rb, Mat& dst)
601 dst.create( src.dims, &src.size[0], CV_8U );
602 const Mat *arrays[]={&src, &dst, 0};
605 NAryMatIterator it(arrays, planes);
606 size_t total = planes[0].total();
607 size_t i, nplanes = it.nplanes;
608 int depth = src.depth(), cn = src.channels();
609 union { double d[4]; float f[4]; int i[4];} lbuf, rbuf;
610 int wtype = CV_MAKETYPE(depth <= CV_32S ? CV_32S : depth, cn);
611 scalarToRawData(lb, lbuf.d, wtype, cn);
612 scalarToRawData(rb, rbuf.d, wtype, cn);
614 for( i = 0; i < nplanes; i++, ++it )
616 const uchar* sptr = planes[0].ptr();
617 uchar* dptr = planes[1].ptr();
622 inRangeS_((const uchar*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
625 inRangeS_((const schar*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
628 inRangeS_((const ushort*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
631 inRangeS_((const short*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
634 inRangeS_((const int*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
637 inRangeS_((const float*)sptr, lbuf.f, rbuf.f, dptr, total, cn);
640 inRangeS_((const double*)sptr, lbuf.d, rbuf.d, dptr, total, cn);
643 CV_Error(CV_StsUnsupportedFormat, "");
649 CVTEST_GUARD_SYMBOL(inRange);
651 struct InRangeSOp : public BaseElemWiseOp
653 InRangeSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {}
654 void op(const vector<Mat>& src, Mat& dst, const Mat&)
656 cv::inRange(src[0], gamma, gamma1, dst);
658 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
660 reference::inRangeS(src[0], gamma, gamma1, dst);
662 double getMaxErr(int)
666 void generateScalars(int depth, RNG& rng)
668 BaseElemWiseOp::generateScalars(depth, rng);
670 BaseElemWiseOp::generateScalars(depth, rng);
671 for( int i = 0; i < 4; i++ )
673 gamma1[i] = std::max(gamma[i], temp[i]);
674 gamma[i] = std::min(gamma[i], temp[i]);
681 struct InRangeOp : public BaseElemWiseOp
683 InRangeOp() : BaseElemWiseOp(3, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
684 void op(const vector<Mat>& src, Mat& dst, const Mat&)
687 cvtest::min(src[1], src[2], lb);
688 cvtest::max(src[1], src[2], rb);
690 cv::inRange(src[0], lb, rb, dst);
692 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
695 cvtest::min(src[1], src[2], lb);
696 cvtest::max(src[1], src[2], rb);
698 reference::inRange(src[0], lb, rb, dst);
700 double getMaxErr(int)
707 struct ConvertScaleOp : public BaseElemWiseOp
709 ConvertScaleOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)), ddepth(0) { }
710 void op(const vector<Mat>& src, Mat& dst, const Mat&)
712 src[0].convertTo(dst, ddepth, alpha, gamma[0]);
714 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
716 cvtest::convert(src[0], dst, CV_MAKETYPE(ddepth, src[0].channels()), alpha, gamma[0]);
718 int getRandomType(RNG& rng)
720 int srctype = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
721 ddepth = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, 1);
724 double getMaxErr(int)
726 return ddepth <= CV_32S ? 2 : ddepth < CV_64F ? 1e-3 : 1e-12;
728 void generateScalars(int depth, RNG& rng)
730 if( rng.uniform(0, 2) )
731 BaseElemWiseOp::generateScalars(depth, rng);
735 gamma = Scalar::all(0);
741 struct ConvertScaleFp16Op : public BaseElemWiseOp
743 ConvertScaleFp16Op() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)), nextRange(0) { }
744 void op(const vector<Mat>& src, Mat& dst, const Mat&)
747 convertFp16(src[0], m);
750 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
752 cvtest::copy(src[0], dst);
754 int getRandomType(RNG&)
756 // 0: FP32 -> FP16 -> FP32
757 // 1: FP16 -> FP32 -> FP16
758 int srctype = (nextRange & 1) == 0 ? CV_32F : CV_16S;
761 void getValueRange(int, double& minval, double& maxval)
763 // 0: FP32 -> FP16 -> FP32
764 // 1: FP16 -> FP32 -> FP16
765 if( (nextRange & 1) == 0 )
767 // largest integer number that fp16 can express exactly
773 // 0: positive number range
774 // 1: negative number range
775 if( (nextRange & 2) == 0 )
777 minval = 0; // 0x0000 +0
778 maxval = 31744; // 0x7C00 +Inf
782 minval = -32768; // 0x8000 -0
783 maxval = -1024; // 0xFC00 -Inf
787 double getMaxErr(int)
791 void generateScalars(int, RNG& rng)
793 nextRange = rng.next();
798 struct ConvertScaleAbsOp : public BaseElemWiseOp
800 ConvertScaleAbsOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
801 void op(const vector<Mat>& src, Mat& dst, const Mat&)
803 cv::convertScaleAbs(src[0], dst, alpha, gamma[0]);
805 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
807 cvtest::add(src[0], alpha, Mat(), 0, Scalar::all(gamma[0]), dst, CV_8UC(src[0].channels()), true);
809 int getRandomType(RNG& rng)
811 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1,
812 ninputs > 1 ? ARITHM_MAX_CHANNELS : 4);
814 double getMaxErr(int)
818 void generateScalars(int depth, RNG& rng)
820 if( rng.uniform(0, 2) )
821 BaseElemWiseOp::generateScalars(depth, rng);
825 gamma = Scalar::all(0);
830 namespace reference {
832 static void flip(const Mat& src, Mat& dst, int flipcode)
834 CV_Assert(src.dims == 2);
835 dst.create(src.size(), src.type());
836 int i, j, k, esz = (int)src.elemSize(), width = src.cols*esz;
838 for( i = 0; i < dst.rows; i++ )
840 const uchar* sptr = src.ptr(flipcode == 1 ? i : dst.rows - i - 1);
841 uchar* dptr = dst.ptr(i);
843 memcpy(dptr, sptr, width);
846 for( j = 0; j < width; j += esz )
847 for( k = 0; k < esz; k++ )
848 dptr[j + k] = sptr[width - j - esz + k];
854 static void setIdentity(Mat& dst, const Scalar& s)
856 CV_Assert( dst.dims == 2 && dst.channels() <= 4 );
858 scalarToRawData(s, buf, dst.type(), 0);
859 int i, k, esz = (int)dst.elemSize(), width = dst.cols*esz;
861 for( i = 0; i < dst.rows; i++ )
863 uchar* dptr = dst.ptr(i);
864 memset( dptr, 0, width );
866 for( k = 0; k < esz; k++ )
867 dptr[i*esz + k] = ((uchar*)buf)[k];
873 struct FlipOp : public BaseElemWiseOp
875 FlipOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) { flipcode = 0; }
876 void getRandomSize(RNG& rng, vector<int>& size)
878 cvtest::randomSize(rng, 2, 2, ARITHM_MAX_SIZE_LOG, size);
880 void op(const vector<Mat>& src, Mat& dst, const Mat&)
882 cv::flip(src[0], dst, flipcode);
884 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
886 reference::flip(src[0], dst, flipcode);
888 void generateScalars(int, RNG& rng)
890 flipcode = rng.uniform(0, 3) - 1;
892 double getMaxErr(int)
899 struct TransposeOp : public BaseElemWiseOp
901 TransposeOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
902 void getRandomSize(RNG& rng, vector<int>& size)
904 cvtest::randomSize(rng, 2, 2, ARITHM_MAX_SIZE_LOG, size);
906 void op(const vector<Mat>& src, Mat& dst, const Mat&)
908 cv::transpose(src[0], dst);
910 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
912 cvtest::transpose(src[0], dst);
914 double getMaxErr(int)
920 struct SetIdentityOp : public BaseElemWiseOp
922 SetIdentityOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {}
923 void getRandomSize(RNG& rng, vector<int>& size)
925 cvtest::randomSize(rng, 2, 2, ARITHM_MAX_SIZE_LOG, size);
927 void op(const vector<Mat>&, Mat& dst, const Mat&)
929 cv::setIdentity(dst, gamma);
931 void refop(const vector<Mat>&, Mat& dst, const Mat&)
933 reference::setIdentity(dst, gamma);
935 double getMaxErr(int)
941 struct SetZeroOp : public BaseElemWiseOp
943 SetZeroOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
944 void op(const vector<Mat>&, Mat& dst, const Mat&)
946 dst = Scalar::all(0);
948 void refop(const vector<Mat>&, Mat& dst, const Mat&)
950 cvtest::set(dst, Scalar::all(0));
952 double getMaxErr(int)
958 namespace reference {
959 static void exp(const Mat& src, Mat& dst)
961 dst.create( src.dims, &src.size[0], src.type() );
962 const Mat *arrays[]={&src, &dst, 0};
965 NAryMatIterator it(arrays, planes);
966 size_t j, total = planes[0].total()*src.channels();
967 size_t i, nplanes = it.nplanes;
968 int depth = src.depth();
970 for( i = 0; i < nplanes; i++, ++it )
972 const uchar* sptr = planes[0].ptr();
973 uchar* dptr = planes[1].ptr();
975 if( depth == CV_32F )
977 for( j = 0; j < total; j++ )
978 ((float*)dptr)[j] = std::exp(((const float*)sptr)[j]);
980 else if( depth == CV_64F )
982 for( j = 0; j < total; j++ )
983 ((double*)dptr)[j] = std::exp(((const double*)sptr)[j]);
988 static void log(const Mat& src, Mat& dst)
990 dst.create( src.dims, &src.size[0], src.type() );
991 const Mat *arrays[]={&src, &dst, 0};
994 NAryMatIterator it(arrays, planes);
995 size_t j, total = planes[0].total()*src.channels();
996 size_t i, nplanes = it.nplanes;
997 int depth = src.depth();
999 for( i = 0; i < nplanes; i++, ++it )
1001 const uchar* sptr = planes[0].ptr();
1002 uchar* dptr = planes[1].ptr();
1004 if( depth == CV_32F )
1006 for( j = 0; j < total; j++ )
1007 ((float*)dptr)[j] = (float)std::log(fabs(((const float*)sptr)[j]));
1009 else if( depth == CV_64F )
1011 for( j = 0; j < total; j++ )
1012 ((double*)dptr)[j] = std::log(fabs(((const double*)sptr)[j]));
1019 struct ExpOp : public BaseElemWiseOp
1021 ExpOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
1022 int getRandomType(RNG& rng)
1024 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
1026 void getValueRange(int depth, double& minval, double& maxval)
1028 maxval = depth == CV_32F ? 50 : 100;
1031 void op(const vector<Mat>& src, Mat& dst, const Mat&)
1033 cv::exp(src[0], dst);
1035 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1037 reference::exp(src[0], dst);
1039 double getMaxErr(int depth)
1041 return depth == CV_32F ? 1e-5 : 1e-12;
1046 struct LogOp : public BaseElemWiseOp
1048 LogOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
1049 int getRandomType(RNG& rng)
1051 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
1053 void getValueRange(int depth, double& minval, double& maxval)
1055 maxval = depth == CV_32F ? 50 : 100;
1058 void op(const vector<Mat>& src, Mat& dst, const Mat&)
1061 reference::exp(src[0], temp);
1064 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1067 reference::exp(src[0], temp);
1068 reference::log(temp, dst);
1070 double getMaxErr(int depth)
1072 return depth == CV_32F ? 1e-5 : 1e-12;
1077 namespace reference {
1078 static void cartToPolar(const Mat& mx, const Mat& my, Mat& mmag, Mat& mangle, bool angleInDegrees)
1080 CV_Assert( (mx.type() == CV_32F || mx.type() == CV_64F) &&
1081 mx.type() == my.type() && mx.size == my.size );
1082 mmag.create( mx.dims, &mx.size[0], mx.type() );
1083 mangle.create( mx.dims, &mx.size[0], mx.type() );
1084 const Mat *arrays[]={&mx, &my, &mmag, &mangle, 0};
1087 NAryMatIterator it(arrays, planes);
1088 size_t j, total = planes[0].total();
1089 size_t i, nplanes = it.nplanes;
1090 int depth = mx.depth();
1091 double scale = angleInDegrees ? 180/CV_PI : 1;
1093 for( i = 0; i < nplanes; i++, ++it )
1095 if( depth == CV_32F )
1097 const float* xptr = planes[0].ptr<float>();
1098 const float* yptr = planes[1].ptr<float>();
1099 float* mptr = planes[2].ptr<float>();
1100 float* aptr = planes[3].ptr<float>();
1102 for( j = 0; j < total; j++ )
1104 mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]);
1105 double a = atan2((double)yptr[j], (double)xptr[j]);
1106 if( a < 0 ) a += CV_PI*2;
1107 aptr[j] = (float)(a*scale);
1112 const double* xptr = planes[0].ptr<double>();
1113 const double* yptr = planes[1].ptr<double>();
1114 double* mptr = planes[2].ptr<double>();
1115 double* aptr = planes[3].ptr<double>();
1117 for( j = 0; j < total; j++ )
1119 mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]);
1120 double a = atan2(yptr[j], xptr[j]);
1121 if( a < 0 ) a += CV_PI*2;
1130 struct CartToPolarToCartOp : public BaseElemWiseOp
1132 CartToPolarToCartOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0))
1135 angleInDegrees = true;
1137 int getRandomType(RNG& rng)
1139 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, 1);
1141 void op(const vector<Mat>& src, Mat& dst, const Mat&)
1143 Mat mag, angle, x, y;
1145 cv::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
1146 cv::polarToCart(mag, angle, x, y, angleInDegrees);
1148 Mat msrc[] = {mag, angle, x, y};
1149 int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
1150 dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
1151 cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
1153 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1156 reference::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
1157 Mat msrc[] = {mag, angle, src[0], src[1]};
1158 int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
1159 dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
1160 cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
1162 void generateScalars(int, RNG& rng)
1164 angleInDegrees = rng.uniform(0, 2) != 0;
1166 double getMaxErr(int)
1170 bool angleInDegrees;
1174 struct MeanOp : public BaseElemWiseOp
1176 MeanOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1180 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1182 dst.create(1, 1, CV_64FC4);
1183 dst.at<Scalar>(0,0) = cv::mean(src[0], mask);
1185 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1187 dst.create(1, 1, CV_64FC4);
1188 dst.at<Scalar>(0,0) = cvtest::mean(src[0], mask);
1190 double getMaxErr(int)
1197 struct SumOp : public BaseElemWiseOp
1199 SumOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1203 void op(const vector<Mat>& src, Mat& dst, const Mat&)
1205 dst.create(1, 1, CV_64FC4);
1206 dst.at<Scalar>(0,0) = cv::sum(src[0]);
1208 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1210 dst.create(1, 1, CV_64FC4);
1211 dst.at<Scalar>(0,0) = cvtest::mean(src[0])*(double)src[0].total();
1213 double getMaxErr(int)
1220 struct CountNonZeroOp : public BaseElemWiseOp
1222 CountNonZeroOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT+SUPPORT_MASK, 1, 1, Scalar::all(0))
1224 int getRandomType(RNG& rng)
1226 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, 1);
1228 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1231 src[0].copyTo(temp);
1233 temp.setTo(Scalar::all(0), mask);
1234 dst.create(1, 1, CV_32S);
1235 dst.at<int>(0,0) = cv::countNonZero(temp);
1237 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1240 cvtest::compare(src[0], 0, temp, CMP_NE);
1242 cvtest::set(temp, Scalar::all(0), mask);
1243 dst.create(1, 1, CV_32S);
1244 dst.at<int>(0,0) = saturate_cast<int>(cvtest::mean(temp)[0]/255*temp.total());
1246 double getMaxErr(int)
1253 struct MeanStdDevOp : public BaseElemWiseOp
1258 MeanStdDevOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1263 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1265 dst.create(1, 2, CV_64FC4);
1266 cv::meanStdDev(src[0], dst.at<Scalar>(0,0), dst.at<Scalar>(0,1), mask);
1268 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1271 cvtest::convert(src[0], temp, CV_64F);
1272 cvtest::multiply(temp, temp, temp);
1273 Scalar mean = cvtest::mean(src[0], mask);
1274 Scalar sqmean = cvtest::mean(temp, mask);
1277 cn = temp.channels();
1279 for( int c = 0; c < 4; c++ )
1280 sqmean[c] = std::sqrt(std::max(sqmean[c] - mean[c]*mean[c], 0.));
1282 dst.create(1, 2, CV_64FC4);
1283 dst.at<Scalar>(0,0) = mean;
1284 dst.at<Scalar>(0,1) = sqmean;
1286 double getMaxErr(int)
1289 double err = sqmeanRef[0];
1290 for(int i = 1; i < cn; ++i)
1291 err = std::max(err, sqmeanRef[i]);
1297 struct NormOp : public BaseElemWiseOp
1299 NormOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1304 int getRandomType(RNG& rng)
1306 int type = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 4);
1309 normType = rng.uniform(1, 8);
1310 if( normType == NORM_INF || normType == NORM_L1 ||
1311 normType == NORM_L2 || normType == NORM_L2SQR ||
1312 normType == NORM_HAMMING || normType == NORM_HAMMING2 )
1315 if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
1321 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1323 dst.create(1, 2, CV_64FC1);
1324 dst.at<double>(0,0) = cv::norm(src[0], normType, mask);
1325 dst.at<double>(0,1) = cv::norm(src[0], src[1], normType, mask);
1327 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1329 dst.create(1, 2, CV_64FC1);
1330 dst.at<double>(0,0) = cvtest::norm(src[0], normType, mask);
1331 dst.at<double>(0,1) = cvtest::norm(src[0], src[1], normType, mask);
1333 void generateScalars(int, RNG& /*rng*/)
1336 double getMaxErr(int)
1344 struct MinMaxLocOp : public BaseElemWiseOp
1346 MinMaxLocOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1348 context = ARITHM_MAX_NDIMS*2 + 2;
1350 int getRandomType(RNG& rng)
1352 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
1354 void saveOutput(const vector<int>& minidx, const vector<int>& maxidx,
1355 double minval, double maxval, Mat& dst)
1357 int i, ndims = (int)minidx.size();
1358 dst.create(1, ndims*2 + 2, CV_64FC1);
1360 for( i = 0; i < ndims; i++ )
1362 dst.at<double>(0,i) = minidx[i];
1363 dst.at<double>(0,i+ndims) = maxidx[i];
1365 dst.at<double>(0,ndims*2) = minval;
1366 dst.at<double>(0,ndims*2+1) = maxval;
1368 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1370 int ndims = src[0].dims;
1371 vector<int> minidx(ndims), maxidx(ndims);
1372 double minval=0, maxval=0;
1373 cv::minMaxIdx(src[0], &minval, &maxval, &minidx[0], &maxidx[0], mask);
1374 saveOutput(minidx, maxidx, minval, maxval, dst);
1376 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1378 int ndims=src[0].dims;
1379 vector<int> minidx(ndims), maxidx(ndims);
1380 double minval=0, maxval=0;
1381 cvtest::minMaxLoc(src[0], &minval, &maxval, &minidx, &maxidx, mask);
1382 saveOutput(minidx, maxidx, minval, maxval, dst);
1384 double getMaxErr(int)
1391 typedef Ptr<BaseElemWiseOp> ElemWiseOpPtr;
1392 class ElemWiseTest : public ::testing::TestWithParam<ElemWiseOpPtr> {};
1394 TEST_P(ElemWiseTest, accuracy)
1396 ElemWiseOpPtr op = GetParam();
1399 RNG rng((uint64)ARITHM_RNG_SEED);
1400 for( testIdx = 0; testIdx < ARITHM_NTESTS; testIdx++ )
1403 op->getRandomSize(rng, size);
1404 int type = op->getRandomType(rng);
1405 int depth = CV_MAT_DEPTH(type);
1406 bool haveMask = ((op->flags & BaseElemWiseOp::SUPPORT_MASK) != 0
1407 || (op->flags & BaseElemWiseOp::SUPPORT_MULTICHANNELMASK) != 0) && rng.uniform(0, 4) == 0;
1409 double minval=0, maxval=0;
1410 op->getValueRange(depth, minval, maxval);
1411 int i, ninputs = op->ninputs;
1412 vector<Mat> src(ninputs);
1413 for( i = 0; i < ninputs; i++ )
1414 src[i] = cvtest::randomMat(rng, size, type, minval, maxval, true);
1415 Mat dst0, dst, mask;
1417 bool multiChannelMask = (op->flags & BaseElemWiseOp::SUPPORT_MULTICHANNELMASK) != 0
1418 && rng.uniform(0, 2) == 0;
1419 int masktype = CV_8UC(multiChannelMask ? CV_MAT_CN(type) : 1);
1420 mask = cvtest::randomMat(rng, size, masktype, 0, 2, true);
1423 if( (haveMask || ninputs == 0) && !(op->flags & BaseElemWiseOp::SCALAR_OUTPUT))
1425 dst0 = cvtest::randomMat(rng, size, type, minval, maxval, false);
1426 dst = cvtest::randomMat(rng, size, type, minval, maxval, true);
1427 cvtest::copy(dst, dst0);
1429 op->generateScalars(depth, rng);
1431 op->refop(src, dst0, mask);
1432 op->op(src, dst, mask);
1434 double maxErr = op->getMaxErr(depth);
1435 ASSERT_PRED_FORMAT2(cvtest::MatComparator(maxErr, op->context), dst0, dst) << "\nsrc[0] ~ " <<
1436 cvtest::MatInfo(!src.empty() ? src[0] : Mat()) << "\ntestCase #" << testIdx << "\n";
1441 INSTANTIATE_TEST_CASE_P(Core_Copy, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CopyOp)));
1442 INSTANTIATE_TEST_CASE_P(Core_Set, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SetOp)));
1443 INSTANTIATE_TEST_CASE_P(Core_SetZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SetZeroOp)));
1444 INSTANTIATE_TEST_CASE_P(Core_ConvertScale, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ConvertScaleOp)));
1445 INSTANTIATE_TEST_CASE_P(Core_ConvertScaleFp16, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ConvertScaleFp16Op)));
1446 INSTANTIATE_TEST_CASE_P(Core_ConvertScaleAbs, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ConvertScaleAbsOp)));
1448 INSTANTIATE_TEST_CASE_P(Core_Add, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AddOp)));
1449 INSTANTIATE_TEST_CASE_P(Core_Sub, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SubOp)));
1450 INSTANTIATE_TEST_CASE_P(Core_AddS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AddSOp)));
1451 INSTANTIATE_TEST_CASE_P(Core_SubRS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SubRSOp)));
1452 INSTANTIATE_TEST_CASE_P(Core_ScaleAdd, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ScaleAddOp)));
1453 INSTANTIATE_TEST_CASE_P(Core_AddWeighted, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AddWeightedOp)));
1454 INSTANTIATE_TEST_CASE_P(Core_AbsDiff, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AbsDiffOp)));
1457 INSTANTIATE_TEST_CASE_P(Core_AbsDiffS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AbsDiffSOp)));
1459 INSTANTIATE_TEST_CASE_P(Core_And, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicOp('&'))));
1460 INSTANTIATE_TEST_CASE_P(Core_AndS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicSOp('&'))));
1461 INSTANTIATE_TEST_CASE_P(Core_Or, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicOp('|'))));
1462 INSTANTIATE_TEST_CASE_P(Core_OrS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicSOp('|'))));
1463 INSTANTIATE_TEST_CASE_P(Core_Xor, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicOp('^'))));
1464 INSTANTIATE_TEST_CASE_P(Core_XorS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicSOp('^'))));
1465 INSTANTIATE_TEST_CASE_P(Core_Not, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicSOp('~'))));
1467 INSTANTIATE_TEST_CASE_P(Core_Max, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MaxOp)));
1468 INSTANTIATE_TEST_CASE_P(Core_MaxS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MaxSOp)));
1469 INSTANTIATE_TEST_CASE_P(Core_Min, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MinOp)));
1470 INSTANTIATE_TEST_CASE_P(Core_MinS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MinSOp)));
1472 INSTANTIATE_TEST_CASE_P(Core_Mul, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MulOp)));
1473 INSTANTIATE_TEST_CASE_P(Core_Div, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new DivOp)));
1474 INSTANTIATE_TEST_CASE_P(Core_Recip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new RecipOp)));
1476 INSTANTIATE_TEST_CASE_P(Core_Cmp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CmpOp)));
1477 INSTANTIATE_TEST_CASE_P(Core_CmpS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CmpSOp)));
1479 INSTANTIATE_TEST_CASE_P(Core_InRangeS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new InRangeSOp)));
1480 INSTANTIATE_TEST_CASE_P(Core_InRange, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new InRangeOp)));
1482 INSTANTIATE_TEST_CASE_P(Core_Flip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new FlipOp)));
1483 INSTANTIATE_TEST_CASE_P(Core_Transpose, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new TransposeOp)));
1484 INSTANTIATE_TEST_CASE_P(Core_SetIdentity, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SetIdentityOp)));
1486 INSTANTIATE_TEST_CASE_P(Core_Exp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ExpOp)));
1487 INSTANTIATE_TEST_CASE_P(Core_Log, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogOp)));
1489 INSTANTIATE_TEST_CASE_P(Core_CountNonZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CountNonZeroOp)));
1490 INSTANTIATE_TEST_CASE_P(Core_Mean, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MeanOp)));
1491 INSTANTIATE_TEST_CASE_P(Core_MeanStdDev, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MeanStdDevOp)));
1492 INSTANTIATE_TEST_CASE_P(Core_Sum, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SumOp)));
1493 INSTANTIATE_TEST_CASE_P(Core_Norm, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new NormOp)));
1494 INSTANTIATE_TEST_CASE_P(Core_MinMaxLoc, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MinMaxLocOp)));
1495 INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CartToPolarToCartOp)));
1498 TEST(Core_ArithmMask, uninitialized)
1500 RNG& rng = theRNG();
1501 const int MAX_DIM=3;
1503 for( int iter = 0; iter < 100; iter++ )
1505 int dims = rng.uniform(1, MAX_DIM+1);
1506 int depth = rng.uniform(CV_8U, CV_64F+1);
1507 int cn = rng.uniform(1, 6);
1508 int type = CV_MAKETYPE(depth, cn);
1509 int op = rng.uniform(0, depth < CV_32F ? 5 : 2); // don't run binary operations between floating-point values
1510 int depth1 = op <= 1 ? CV_64F : depth;
1511 for (int k = 0; k < MAX_DIM; k++)
1513 sizes[k] = k < dims ? rng.uniform(1, 30) : 0;
1515 SCOPED_TRACE(cv::format("iter=%d dims=%d depth=%d cn=%d type=%d op=%d depth1=%d dims=[%d; %d; %d]",
1516 iter, dims, depth, cn, type, op, depth1, sizes[0], sizes[1], sizes[2]));
1518 Mat a(dims, sizes, type), a1;
1519 Mat b(dims, sizes, type), b1;
1520 Mat mask(dims, sizes, CV_8U);
1524 rng.fill(a, RNG::UNIFORM, 0, 100);
1525 rng.fill(b, RNG::UNIFORM, 0, 100);
1527 // [-2,2) range means that the each generated random number
1528 // will be one of -2, -1, 0, 1. Saturated to [0,255], it will become
1529 // 0, 0, 0, 1 => the mask will be filled by ~25%.
1530 rng.fill(mask, RNG::UNIFORM, -2, 2);
1532 a.convertTo(a1, depth1);
1533 b.convertTo(b1, depth1);
1535 cv::compare(mask, 0, mask1, CMP_EQ);
1541 cv::add(a, b, c, mask);
1546 cv::subtract(a, b, c, mask);
1547 cv::subtract(a1, b1, d);
1551 cv::bitwise_and(a, b, c, mask);
1552 cv::bitwise_and(a1, b1, d);
1556 cv::bitwise_or(a, b, c, mask);
1557 cv::bitwise_or(a1, b1, d);
1561 cv::bitwise_xor(a, b, c, mask);
1562 cv::bitwise_xor(a1, b1, d);
1565 d.convertTo(d1, depth);
1566 EXPECT_LE(cvtest::norm(c, d1, CV_C), DBL_EPSILON);
1569 Mat_<uchar> tmpSrc(100,100);
1571 Mat_<uchar> tmpMask(100,100);
1573 Mat_<uchar> tmpDst(100,100);
1575 tmpSrc.copyTo(tmpDst,tmpMask);
1578 TEST(Multiply, FloatingPointRounding)
1580 cv::Mat src(1, 1, CV_8UC1, cv::Scalar::all(110)), dst;
1581 cv::Scalar s(147.286359696927, 1, 1 ,1);
1583 cv::multiply(src, s, dst, 1, CV_16U);
1584 // with CV_32F this produce result 16202
1585 ASSERT_EQ(dst.at<ushort>(0,0), 16201);
1588 TEST(Core_Add, AddToColumnWhen3Rows)
1590 cv::Mat m1 = (cv::Mat_<double>(3, 2) << 1, 2, 3, 4, 5, 6);
1593 cv::Mat m2 = (cv::Mat_<double>(3, 2) << 1, 12, 3, 14, 5, 16);
1595 ASSERT_EQ(0, countNonZero(m1 - m2));
1598 TEST(Core_Add, AddToColumnWhen4Rows)
1600 cv::Mat m1 = (cv::Mat_<double>(4, 2) << 1, 2, 3, 4, 5, 6, 7, 8);
1603 cv::Mat m2 = (cv::Mat_<double>(4, 2) << 1, 12, 3, 14, 5, 16, 7, 18);
1605 ASSERT_EQ(0, countNonZero(m1 - m2));
1608 TEST(Core_round, CvRound)
1610 ASSERT_EQ(2, cvRound(2.0));
1611 ASSERT_EQ(2, cvRound(2.1));
1612 ASSERT_EQ(-2, cvRound(-2.1));
1613 ASSERT_EQ(3, cvRound(2.8));
1614 ASSERT_EQ(-3, cvRound(-2.8));
1615 ASSERT_EQ(2, cvRound(2.5));
1616 ASSERT_EQ(4, cvRound(3.5));
1617 ASSERT_EQ(-2, cvRound(-2.5));
1618 ASSERT_EQ(-4, cvRound(-3.5));
1622 typedef testing::TestWithParam<Size> Mul1;
1626 Size size = GetParam();
1627 cv::Mat src(size, CV_32FC1, cv::Scalar::all(2)), dst,
1628 ref_dst(size, CV_32FC1, cv::Scalar::all(6));
1630 cv::multiply(3, src, dst);
1632 ASSERT_EQ(0, cvtest::norm(dst, ref_dst, cv::NORM_INF));
1635 INSTANTIATE_TEST_CASE_P(Arithm, Mul1, testing::Values(Size(2, 2), Size(1, 1)));
1637 class SubtractOutputMatNotEmpty : public testing::TestWithParam< tuple<cv::Size, perf::MatType, perf::MatDepth, bool> >
1647 size = get<0>(GetParam());
1648 src_type = get<1>(GetParam());
1649 dst_depth = get<2>(GetParam());
1650 fixed = get<3>(GetParam());
1654 TEST_P(SubtractOutputMatNotEmpty, Mat_Mat)
1656 cv::Mat src1(size, src_type, cv::Scalar::all(16));
1657 cv::Mat src2(size, src_type, cv::Scalar::all(16));
1663 cv::subtract(src1, src2, dst, cv::noArray(), dst_depth);
1667 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
1668 cv::subtract(src1, src2, fixed_dst, cv::noArray(), dst_depth);
1670 dst_depth = fixed_dst.depth();
1673 ASSERT_FALSE(dst.empty());
1674 ASSERT_EQ(src1.size(), dst.size());
1675 ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
1676 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1679 TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_WithMask)
1681 cv::Mat src1(size, src_type, cv::Scalar::all(16));
1682 cv::Mat src2(size, src_type, cv::Scalar::all(16));
1683 cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
1689 cv::subtract(src1, src2, dst, mask, dst_depth);
1693 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
1694 cv::subtract(src1, src2, fixed_dst, mask, dst_depth);
1696 dst_depth = fixed_dst.depth();
1699 ASSERT_FALSE(dst.empty());
1700 ASSERT_EQ(src1.size(), dst.size());
1701 ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
1702 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1705 TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_Expr)
1707 cv::Mat src1(size, src_type, cv::Scalar::all(16));
1708 cv::Mat src2(size, src_type, cv::Scalar::all(16));
1710 cv::Mat dst = src1 - src2;
1712 ASSERT_FALSE(dst.empty());
1713 ASSERT_EQ(src1.size(), dst.size());
1714 ASSERT_EQ(src1.depth(), dst.depth());
1715 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1718 TEST_P(SubtractOutputMatNotEmpty, Mat_Scalar)
1720 cv::Mat src(size, src_type, cv::Scalar::all(16));
1726 cv::subtract(src, cv::Scalar::all(16), dst, cv::noArray(), dst_depth);
1730 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
1731 cv::subtract(src, cv::Scalar::all(16), fixed_dst, cv::noArray(), dst_depth);
1733 dst_depth = fixed_dst.depth();
1736 ASSERT_FALSE(dst.empty());
1737 ASSERT_EQ(src.size(), dst.size());
1738 ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
1739 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1742 TEST_P(SubtractOutputMatNotEmpty, Mat_Scalar_WithMask)
1744 cv::Mat src(size, src_type, cv::Scalar::all(16));
1745 cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
1751 cv::subtract(src, cv::Scalar::all(16), dst, mask, dst_depth);
1755 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
1756 cv::subtract(src, cv::Scalar::all(16), fixed_dst, mask, dst_depth);
1758 dst_depth = fixed_dst.depth();
1761 ASSERT_FALSE(dst.empty());
1762 ASSERT_EQ(src.size(), dst.size());
1763 ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
1764 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1767 TEST_P(SubtractOutputMatNotEmpty, Scalar_Mat)
1769 cv::Mat src(size, src_type, cv::Scalar::all(16));
1775 cv::subtract(cv::Scalar::all(16), src, dst, cv::noArray(), dst_depth);
1779 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
1780 cv::subtract(cv::Scalar::all(16), src, fixed_dst, cv::noArray(), dst_depth);
1782 dst_depth = fixed_dst.depth();
1785 ASSERT_FALSE(dst.empty());
1786 ASSERT_EQ(src.size(), dst.size());
1787 ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
1788 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1791 TEST_P(SubtractOutputMatNotEmpty, Scalar_Mat_WithMask)
1793 cv::Mat src(size, src_type, cv::Scalar::all(16));
1794 cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
1800 cv::subtract(cv::Scalar::all(16), src, dst, mask, dst_depth);
1804 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
1805 cv::subtract(cv::Scalar::all(16), src, fixed_dst, mask, dst_depth);
1807 dst_depth = fixed_dst.depth();
1810 ASSERT_FALSE(dst.empty());
1811 ASSERT_EQ(src.size(), dst.size());
1812 ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
1813 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1816 TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_3d)
1818 int dims[] = {5, size.height, size.width};
1820 cv::Mat src1(3, dims, src_type, cv::Scalar::all(16));
1821 cv::Mat src2(3, dims, src_type, cv::Scalar::all(16));
1827 cv::subtract(src1, src2, dst, cv::noArray(), dst_depth);
1831 const cv::Mat fixed_dst(3, dims, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
1832 cv::subtract(src1, src2, fixed_dst, cv::noArray(), dst_depth);
1834 dst_depth = fixed_dst.depth();
1837 ASSERT_FALSE(dst.empty());
1838 ASSERT_EQ(src1.dims, dst.dims);
1839 ASSERT_EQ(src1.size, dst.size);
1840 ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
1841 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1844 INSTANTIATE_TEST_CASE_P(Arithm, SubtractOutputMatNotEmpty, testing::Combine(
1845 testing::Values(cv::Size(16, 16), cv::Size(13, 13), cv::Size(16, 13), cv::Size(13, 16)),
1846 testing::Values(perf::MatType(CV_8UC1), CV_8UC3, CV_8UC4, CV_16SC1, CV_16SC3),
1847 testing::Values(-1, CV_16S, CV_32S, CV_32F),
1850 TEST(Core_FindNonZero, singular)
1852 Mat img(10, 10, CV_8U, Scalar::all(0));
1853 vector<Point> pts, pts2(10);
1854 findNonZero(img, pts);
1855 findNonZero(img, pts2);
1856 ASSERT_TRUE(pts.empty() && pts2.empty());
1859 TEST(Core_BoolVector, support)
1861 std::vector<bool> test;
1865 for( i = 0; i < n; i++ )
1867 test[i] = theRNG().uniform(0, 2) != 0;
1870 ASSERT_EQ( nz, countNonZero(test) );
1871 ASSERT_FLOAT_EQ((float)nz/n, (float)(cv::mean(test)[0]));
1874 TEST(MinMaxLoc, Mat_UcharMax_Without_Loc)
1876 Mat_<uchar> mat(50, 50);
1877 uchar iMaxVal = std::numeric_limits<uchar>::max();
1881 Point minLoc, maxLoc;
1883 minMaxLoc(mat, &min, &max, &minLoc, &maxLoc, Mat());
1885 ASSERT_EQ(iMaxVal, min);
1886 ASSERT_EQ(iMaxVal, max);
1888 ASSERT_EQ(Point(0, 0), minLoc);
1889 ASSERT_EQ(Point(0, 0), maxLoc);
1892 TEST(MinMaxLoc, Mat_IntMax_Without_Mask)
1894 Mat_<int> mat(50, 50);
1895 int iMaxVal = std::numeric_limits<int>::max();
1899 Point minLoc, maxLoc;
1901 minMaxLoc(mat, &min, &max, &minLoc, &maxLoc, Mat());
1903 ASSERT_EQ(iMaxVal, min);
1904 ASSERT_EQ(iMaxVal, max);
1906 ASSERT_EQ(Point(0, 0), minLoc);
1907 ASSERT_EQ(Point(0, 0), maxLoc);
1910 TEST(Normalize, regression_5876_inplace_change_type)
1912 double initial_values[] = {1, 2, 5, 4, 3};
1913 float result_values[] = {0, 0.25, 1, 0.75, 0.5};
1914 Mat m(Size(5, 1), CV_64FC1, initial_values);
1915 Mat result(Size(5, 1), CV_32FC1, result_values);
1917 normalize(m, m, 1, 0, NORM_MINMAX, CV_32F);
1918 EXPECT_EQ(0, cvtest::norm(m, result, NORM_INF));
1921 TEST(Normalize, regression_6125)
1923 float initial_values[] = {
1924 1888, 1692, 369, 263, 199,
1925 280, 326, 129, 143, 126,
1926 233, 221, 130, 126, 150,
1927 249, 575, 574, 63, 12
1930 Mat src(Size(20, 1), CV_32F, initial_values);
1931 float min = 0., max = 400.;
1932 normalize(src, src, 0, 400, NORM_MINMAX, CV_32F);
1933 for(int i = 0; i < 20; i++)
1935 EXPECT_GE(src.at<float>(i), min) << "Value should be >= 0";
1936 EXPECT_LE(src.at<float>(i), max) << "Value should be <= 400";
1940 TEST(MinMaxLoc, regression_4955_nans)
1942 cv::Mat one_mat(2, 2, CV_32F, cv::Scalar(1));
1943 cv::minMaxLoc(one_mat, NULL, NULL, NULL, NULL);
1945 cv::Mat nan_mat(2, 2, CV_32F, cv::Scalar(std::numeric_limits<float>::quiet_NaN()));
1946 cv::minMaxLoc(nan_mat, NULL, NULL, NULL, NULL);
1949 TEST(Subtract, scalarc1_matc3)
1952 cv::Mat srcImage(5, 5, CV_8UC3, cv::Scalar::all(5)), destImage;
1953 cv::subtract(scalar, srcImage, destImage);
1955 ASSERT_EQ(0, cv::norm(cv::Mat(5, 5, CV_8UC3, cv::Scalar::all(250)), destImage, cv::NORM_INF));
1958 TEST(Subtract, scalarc4_matc4)
1960 cv::Scalar sc(255, 255, 255, 255);
1961 cv::Mat srcImage(5, 5, CV_8UC4, cv::Scalar::all(5)), destImage;
1962 cv::subtract(sc, srcImage, destImage);
1964 ASSERT_EQ(0, cv::norm(cv::Mat(5, 5, CV_8UC4, cv::Scalar::all(250)), destImage, cv::NORM_INF));
1967 TEST(Compare, empty)
1969 cv::Mat temp, dst1, dst2;
1970 cv::compare(temp, temp, dst1, cv::CMP_EQ);
1973 EXPECT_TRUE(dst1.empty());
1974 EXPECT_TRUE(dst2.empty());
1977 TEST(Compare, regression_8999)
1979 Mat_<double> A(4,1); A << 1, 3, 2, 4;
1980 Mat_<double> B(1,1); B << 2;
1983 cv::compare(A, B, C, CMP_LT);
1988 TEST(Core_minMaxIdx, regression_9207_1)
1992 uchar mask_[rows*cols] = {
1998 uchar src_[rows*cols] = {
2004 Mat mask(Size(cols, rows), CV_8UC1, mask_);
2005 Mat src(Size(cols, rows), CV_8UC1, src_);
2006 double minVal = -0.0, maxVal = -0.0;
2007 int minIdx[2] = { -2, -2 }, maxIdx[2] = { -2, -2 };
2008 cv::minMaxIdx(src, &minVal, &maxVal, minIdx, maxIdx, mask);
2009 EXPECT_EQ(0, minIdx[0]);
2010 EXPECT_EQ(0, minIdx[1]);
2011 EXPECT_EQ(0, maxIdx[0]);
2012 EXPECT_EQ(0, maxIdx[1]);
2016 TEST(Core_minMaxIdx, regression_9207_2)
2018 const int rows = 13;
2019 const int cols = 15;
2020 uchar mask_[rows*cols] = {
2021 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
2022 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
2023 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
2024 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
2025 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255,
2026 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 255,
2027 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 0,
2028 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 0,
2029 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0,
2030 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0,
2031 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2032 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2033 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2035 uchar src_[15*13] = {
2036 5, 5, 5, 5, 5, 6, 5, 2, 0, 4, 6, 6, 4, 1, 0,
2037 6, 5, 4, 4, 5, 6, 6, 5, 2, 0, 4, 6, 5, 2, 0,
2038 3, 2, 1, 1, 2, 4, 6, 6, 4, 2, 3, 4, 4, 2, 0,
2039 1, 0, 0, 0, 0, 1, 4, 5, 4, 4, 4, 4, 3, 2, 0,
2040 0, 0, 0, 0, 0, 0, 2, 3, 4, 4, 4, 3, 2, 1, 0,
2041 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 3, 2, 1, 0, 0,
2042 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1,
2043 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
2044 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1,
2045 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 3, 3, 1, 0, 1,
2046 0, 0, 0, 0, 0, 0, 1, 4, 5, 6, 5, 4, 3, 2, 0,
2047 1, 0, 0, 0, 0, 0, 3, 5, 5, 4, 3, 4, 4, 3, 0,
2048 2, 0, 0, 0, 0, 2, 5, 6, 5, 2, 2, 5, 4, 3, 0
2050 Mat mask(Size(cols, rows), CV_8UC1, mask_);
2051 Mat src(Size(cols, rows), CV_8UC1, src_);
2052 double minVal = -0.0, maxVal = -0.0;
2053 int minIdx[2] = { -2, -2 }, maxIdx[2] = { -2, -2 };
2054 cv::minMaxIdx(src, &minVal, &maxVal, minIdx, maxIdx, mask);
2055 EXPECT_EQ(0, minIdx[0]);
2056 EXPECT_EQ(14, minIdx[1]);
2057 EXPECT_EQ(0, maxIdx[0]);
2058 EXPECT_EQ(14, maxIdx[1]);
2061 TEST(Core_Set, regression_11044)
2063 Mat testFloat(Size(3, 3), CV_32FC1);
2064 Mat testDouble(Size(3, 3), CV_64FC1);
2067 EXPECT_EQ(1, testFloat.at<float>(0,0));
2068 testFloat.setTo(std::numeric_limits<float>::infinity());
2069 EXPECT_EQ(std::numeric_limits<float>::infinity(), testFloat.at<float>(0, 0));
2071 EXPECT_EQ(1, testFloat.at<float>(0, 0));
2072 testFloat.setTo(std::numeric_limits<double>::infinity());
2073 EXPECT_EQ(std::numeric_limits<float>::infinity(), testFloat.at<float>(0, 0));
2075 testDouble.setTo(1);
2076 EXPECT_EQ(1, testDouble.at<double>(0, 0));
2077 testDouble.setTo(std::numeric_limits<float>::infinity());
2078 EXPECT_EQ(std::numeric_limits<double>::infinity(), testDouble.at<double>(0, 0));
2079 testDouble.setTo(1);
2080 EXPECT_EQ(1, testDouble.at<double>(0, 0));
2081 testDouble.setTo(std::numeric_limits<double>::infinity());
2082 EXPECT_EQ(std::numeric_limits<double>::infinity(), testDouble.at<double>(0, 0));
2084 Mat testMask(Size(3, 3), CV_8UC1, Scalar(1));
2087 EXPECT_EQ(1, testFloat.at<float>(0, 0));
2088 testFloat.setTo(std::numeric_limits<float>::infinity(), testMask);
2089 EXPECT_EQ(std::numeric_limits<float>::infinity(), testFloat.at<float>(0, 0));
2091 EXPECT_EQ(1, testFloat.at<float>(0, 0));
2092 testFloat.setTo(std::numeric_limits<double>::infinity(), testMask);
2093 EXPECT_EQ(std::numeric_limits<float>::infinity(), testFloat.at<float>(0, 0));
2096 testDouble.setTo(1);
2097 EXPECT_EQ(1, testDouble.at<double>(0, 0));
2098 testDouble.setTo(std::numeric_limits<float>::infinity(), testMask);
2099 EXPECT_EQ(std::numeric_limits<double>::infinity(), testDouble.at<double>(0, 0));
2100 testDouble.setTo(1);
2101 EXPECT_EQ(1, testDouble.at<double>(0, 0));
2102 testDouble.setTo(std::numeric_limits<double>::infinity(), testMask);
2103 EXPECT_EQ(std::numeric_limits<double>::infinity(), testDouble.at<double>(0, 0));
2106 TEST(Core_Norm, IPP_regression_NORM_L1_16UC3_small)
2109 Size sz(9, 4); // width < 16
2110 Mat a(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(1));
2111 Mat b(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(2));
2112 uchar mask_[9*4] = {
2113 255, 255, 255, 0, 255, 255, 0, 255, 0,
2114 0, 255, 0, 0, 255, 255, 255, 255, 0,
2115 0, 0, 0, 255, 0, 255, 0, 255, 255,
2116 0, 0, 255, 0, 255, 255, 255, 0, 255
2118 Mat mask(sz, CV_8UC1, mask_);
2120 EXPECT_EQ((double)9*4*cn, cv::norm(a, b, NORM_L1)); // without mask, IPP works well
2121 EXPECT_EQ((double)20*cn, cv::norm(a, b, NORM_L1, mask));