1 #include "test_precomp.hpp"
9 const int ARITHM_NTESTS = 1000;
10 const int ARITHM_RNG_SEED = -1;
11 const int ARITHM_MAX_CHANNELS = 4;
12 const int ARITHM_MAX_NDIMS = 4;
13 const int ARITHM_MAX_SIZE_LOG = 10;
17 enum { FIX_ALPHA=1, FIX_BETA=2, FIX_GAMMA=4, REAL_GAMMA=8, SUPPORT_MASK=16, SCALAR_OUTPUT=32 };
18 BaseElemWiseOp(int _ninputs, int _flags, double _alpha, double _beta,
19 Scalar _gamma=Scalar::all(0), int _context=1)
20 : ninputs(_ninputs), flags(_flags), alpha(_alpha), beta(_beta), gamma(_gamma), context(_context) {}
21 BaseElemWiseOp() { flags = 0; alpha = beta = 0; gamma = Scalar::all(0); }
22 virtual ~BaseElemWiseOp() {}
23 virtual void op(const vector<Mat>&, Mat&, const Mat&) {}
24 virtual void refop(const vector<Mat>&, Mat&, const Mat&) {}
25 virtual void getValueRange(int depth, double& minval, double& maxval)
27 minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.;
28 maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.;
31 virtual void getRandomSize(RNG& rng, vector<int>& size)
33 cvtest::randomSize(rng, 2, ARITHM_MAX_NDIMS, cvtest::ARITHM_MAX_SIZE_LOG, size);
36 virtual int getRandomType(RNG& rng)
38 return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1,
39 ninputs > 1 ? ARITHM_MAX_CHANNELS : 4);
42 virtual double getMaxErr(int depth) { return depth < CV_32F ? 1 : depth == CV_32F ? 1e-5 : 1e-12; }
43 virtual void generateScalars(int depth, RNG& rng)
47 if( !(flags & FIX_ALPHA) )
49 alpha = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2);
50 alpha *= rng.uniform(0, 2) ? 1 : -1;
52 if( !(flags & FIX_BETA) )
54 beta = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2);
55 beta *= rng.uniform(0, 2) ? 1 : -1;
58 if( !(flags & FIX_GAMMA) )
60 for( int i = 0; i < 4; i++ )
62 gamma[i] = exp(rng.uniform(-1, 6)*m*CV_LOG2);
63 gamma[i] *= rng.uniform(0, 2) ? 1 : -1;
65 if( flags & REAL_GAMMA )
66 gamma = Scalar::all(gamma[0]);
73 db = Mat(1, 1, CV_64F, &alpha);
74 db.convertTo(fl, CV_32F);
75 fl.convertTo(db, CV_64F);
77 db = Mat(1, 1, CV_64F, &beta);
78 db.convertTo(fl, CV_32F);
79 fl.convertTo(db, CV_64F);
81 db = Mat(1, 4, CV_64F, &gamma[0]);
82 db.convertTo(fl, CV_32F);
83 fl.convertTo(db, CV_64F);
97 struct BaseAddOp : public BaseElemWiseOp
99 BaseAddOp(int _ninputs, int _flags, double _alpha, double _beta, Scalar _gamma=Scalar::all(0))
100 : BaseElemWiseOp(_ninputs, _flags, _alpha, _beta, _gamma) {}
102 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
107 cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, temp, src[0].type());
108 cvtest::copy(temp, dst, mask);
111 cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, dst, src[0].type());
116 struct AddOp : public BaseAddOp
118 AddOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {};
119 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
122 add(src[0], src[1], dst);
124 add(src[0], src[1], dst, mask);
129 struct SubOp : public BaseAddOp
131 SubOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, -1, Scalar::all(0)) {};
132 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
135 subtract(src[0], src[1], dst);
137 subtract(src[0], src[1], dst, mask);
142 struct AddSOp : public BaseAddOp
144 AddSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, 1, 0, Scalar::all(0)) {};
145 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
148 add(src[0], gamma, dst);
150 add(src[0], gamma, dst, mask);
155 struct SubRSOp : public BaseAddOp
157 SubRSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, -1, 0, Scalar::all(0)) {};
158 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
161 subtract(gamma, src[0], dst);
163 subtract(gamma, src[0], dst, mask);
168 struct ScaleAddOp : public BaseAddOp
170 ScaleAddOp() : BaseAddOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
171 void op(const vector<Mat>& src, Mat& dst, const Mat&)
173 scaleAdd(src[0], alpha, src[1], dst);
175 double getMaxErr(int depth)
177 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-4 : 1e-12;
182 struct AddWeightedOp : public BaseAddOp
184 AddWeightedOp() : BaseAddOp(2, REAL_GAMMA, 1, 1, Scalar::all(0)) {};
185 void op(const vector<Mat>& src, Mat& dst, const Mat&)
187 addWeighted(src[0], alpha, src[1], beta, gamma[0], dst);
189 double getMaxErr(int depth)
191 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-10;
195 struct MulOp : public BaseElemWiseOp
197 MulOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
198 void getValueRange(int depth, double& minval, double& maxval)
200 minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.;
201 maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.;
202 minval = std::max(minval, -30000.);
203 maxval = std::min(maxval, 30000.);
205 void op(const vector<Mat>& src, Mat& dst, const Mat&)
207 cv::multiply(src[0], src[1], dst, alpha);
209 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
211 cvtest::multiply(src[0], src[1], dst, alpha);
213 double getMaxErr(int depth)
215 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
219 struct DivOp : public BaseElemWiseOp
221 DivOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
222 void op(const vector<Mat>& src, Mat& dst, const Mat&)
224 cv::divide(src[0], src[1], dst, alpha);
226 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
228 cvtest::divide(src[0], src[1], dst, alpha);
230 double getMaxErr(int depth)
232 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
236 struct RecipOp : public BaseElemWiseOp
238 RecipOp() : BaseElemWiseOp(1, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
239 void op(const vector<Mat>& src, Mat& dst, const Mat&)
241 cv::divide(alpha, src[0], dst);
243 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
245 cvtest::divide(Mat(), src[0], dst, alpha);
247 double getMaxErr(int depth)
249 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
253 struct AbsDiffOp : public BaseAddOp
255 AbsDiffOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, -1, Scalar::all(0)) {};
256 void op(const vector<Mat>& src, Mat& dst, const Mat&)
258 absdiff(src[0], src[1], dst);
260 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
262 cvtest::add(src[0], 1, src[1], -1, Scalar::all(0), dst, src[0].type(), true);
266 struct AbsDiffSOp : public BaseAddOp
268 AbsDiffSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA, 1, 0, Scalar::all(0)) {};
269 void op(const vector<Mat>& src, Mat& dst, const Mat&)
271 absdiff(src[0], gamma, dst);
273 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
275 cvtest::add(src[0], 1, Mat(), 0, -gamma, dst, src[0].type(), true);
279 struct LogicOp : public BaseElemWiseOp
281 LogicOp(char _opcode) : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)), opcode(_opcode) {};
282 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
285 bitwise_and(src[0], src[1], dst, mask);
286 else if( opcode == '|' )
287 bitwise_or(src[0], src[1], dst, mask);
289 bitwise_xor(src[0], src[1], dst, mask);
291 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
296 cvtest::logicOp(src[0], src[1], temp, opcode);
297 cvtest::copy(temp, dst, mask);
300 cvtest::logicOp(src[0], src[1], dst, opcode);
302 double getMaxErr(int)
309 struct LogicSOp : public BaseElemWiseOp
311 LogicSOp(char _opcode)
312 : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+(_opcode != '~' ? SUPPORT_MASK : 0), 1, 1, Scalar::all(0)), opcode(_opcode) {};
313 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
316 bitwise_and(src[0], gamma, dst, mask);
317 else if( opcode == '|' )
318 bitwise_or(src[0], gamma, dst, mask);
319 else if( opcode == '^' )
320 bitwise_xor(src[0], gamma, dst, mask);
322 bitwise_not(src[0], dst);
324 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
329 cvtest::logicOp(src[0], gamma, temp, opcode);
330 cvtest::copy(temp, dst, mask);
333 cvtest::logicOp(src[0], gamma, dst, opcode);
335 double getMaxErr(int)
342 struct MinOp : public BaseElemWiseOp
344 MinOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
345 void op(const vector<Mat>& src, Mat& dst, const Mat&)
347 cv::min(src[0], src[1], dst);
349 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
351 cvtest::min(src[0], src[1], dst);
353 double getMaxErr(int)
359 struct MaxOp : public BaseElemWiseOp
361 MaxOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
362 void op(const vector<Mat>& src, Mat& dst, const Mat&)
364 cv::max(src[0], src[1], dst);
366 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
368 cvtest::max(src[0], src[1], dst);
370 double getMaxErr(int)
376 struct MinSOp : public BaseElemWiseOp
378 MinSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {};
379 void op(const vector<Mat>& src, Mat& dst, const Mat&)
381 cv::min(src[0], gamma[0], dst);
383 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
385 cvtest::min(src[0], gamma[0], dst);
387 double getMaxErr(int)
393 struct MaxSOp : public BaseElemWiseOp
395 MaxSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {};
396 void op(const vector<Mat>& src, Mat& dst, const Mat&)
398 cv::max(src[0], gamma[0], dst);
400 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
402 cvtest::max(src[0], gamma[0], dst);
404 double getMaxErr(int)
410 struct CmpOp : public BaseElemWiseOp
412 CmpOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
413 void generateScalars(int depth, RNG& rng)
415 BaseElemWiseOp::generateScalars(depth, rng);
416 cmpop = rng.uniform(0, 6);
418 void op(const vector<Mat>& src, Mat& dst, const Mat&)
420 cv::compare(src[0], src[1], dst, cmpop);
422 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
424 cvtest::compare(src[0], src[1], dst, cmpop);
426 int getRandomType(RNG& rng)
428 return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1);
431 double getMaxErr(int)
438 struct CmpSOp : public BaseElemWiseOp
440 CmpSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {};
441 void generateScalars(int depth, RNG& rng)
443 BaseElemWiseOp::generateScalars(depth, rng);
444 cmpop = rng.uniform(0, 6);
446 gamma[0] = cvRound(gamma[0]);
448 void op(const vector<Mat>& src, Mat& dst, const Mat&)
450 cv::compare(src[0], gamma[0], dst, cmpop);
452 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
454 cvtest::compare(src[0], gamma[0], dst, cmpop);
456 int getRandomType(RNG& rng)
458 return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1);
460 double getMaxErr(int)
468 struct CopyOp : public BaseElemWiseOp
470 CopyOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {};
471 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
473 src[0].copyTo(dst, mask);
475 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
477 cvtest::copy(src[0], dst, mask);
479 int getRandomType(RNG& rng)
481 return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
483 double getMaxErr(int)
491 struct SetOp : public BaseElemWiseOp
493 SetOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {};
494 void op(const vector<Mat>&, Mat& dst, const Mat& mask)
496 dst.setTo(gamma, mask);
498 void refop(const vector<Mat>&, Mat& dst, const Mat& mask)
500 cvtest::set(dst, gamma, mask);
502 int getRandomType(RNG& rng)
504 return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
506 double getMaxErr(int)
512 template<typename _Tp, typename _WTp> static void
513 inRangeS_(const _Tp* src, const _WTp* a, const _WTp* b, uchar* dst, size_t total, int cn)
517 for( i = 0; i < total; i++ )
520 dst[i] = (a[0] <= val && val <= b[0]) ? uchar(255) : 0;
522 for( c = 1; c < cn; c++ )
524 for( i = 0; i < total; i++ )
526 _Tp val = src[i*cn + c];
527 dst[i] = a[c] <= val && val <= b[c] ? dst[i] : 0;
532 template<typename _Tp> static void inRange_(const _Tp* src, const _Tp* a, const _Tp* b, uchar* dst, size_t total, int cn)
536 for( i = 0; i < total; i++ )
539 dst[i] = a[i*cn] <= val && val <= b[i*cn] ? 255 : 0;
541 for( c = 1; c < cn; c++ )
543 for( i = 0; i < total; i++ )
545 _Tp val = src[i*cn + c];
546 dst[i] = a[i*cn + c] <= val && val <= b[i*cn + c] ? dst[i] : 0;
552 static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst)
554 CV_Assert( src.type() == lb.type() && src.type() == rb.type() &&
555 src.size == lb.size && src.size == rb.size );
556 dst.create( src.dims, &src.size[0], CV_8U );
557 const Mat *arrays[]={&src, &lb, &rb, &dst, 0};
560 NAryMatIterator it(arrays, planes);
561 size_t total = planes[0].total();
562 size_t i, nplanes = it.nplanes;
563 int depth = src.depth(), cn = src.channels();
565 for( i = 0; i < nplanes; i++, ++it )
567 const uchar* sptr = planes[0].data;
568 const uchar* aptr = planes[1].data;
569 const uchar* bptr = planes[2].data;
570 uchar* dptr = planes[3].data;
575 inRange_((const uchar*)sptr, (const uchar*)aptr, (const uchar*)bptr, dptr, total, cn);
578 inRange_((const schar*)sptr, (const schar*)aptr, (const schar*)bptr, dptr, total, cn);
581 inRange_((const ushort*)sptr, (const ushort*)aptr, (const ushort*)bptr, dptr, total, cn);
584 inRange_((const short*)sptr, (const short*)aptr, (const short*)bptr, dptr, total, cn);
587 inRange_((const int*)sptr, (const int*)aptr, (const int*)bptr, dptr, total, cn);
590 inRange_((const float*)sptr, (const float*)aptr, (const float*)bptr, dptr, total, cn);
593 inRange_((const double*)sptr, (const double*)aptr, (const double*)bptr, dptr, total, cn);
596 CV_Error(CV_StsUnsupportedFormat, "");
602 static void inRangeS(const Mat& src, const Scalar& lb, const Scalar& rb, Mat& dst)
604 dst.create( src.dims, &src.size[0], CV_8U );
605 const Mat *arrays[]={&src, &dst, 0};
608 NAryMatIterator it(arrays, planes);
609 size_t total = planes[0].total();
610 size_t i, nplanes = it.nplanes;
611 int depth = src.depth(), cn = src.channels();
612 union { double d[4]; float f[4]; int i[4];} lbuf, rbuf;
613 int wtype = CV_MAKETYPE(depth <= CV_32S ? CV_32S : depth, cn);
614 scalarToRawData(lb, lbuf.d, wtype, cn);
615 scalarToRawData(rb, rbuf.d, wtype, cn);
617 for( i = 0; i < nplanes; i++, ++it )
619 const uchar* sptr = planes[0].data;
620 uchar* dptr = planes[1].data;
625 inRangeS_((const uchar*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
628 inRangeS_((const schar*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
631 inRangeS_((const ushort*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
634 inRangeS_((const short*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
637 inRangeS_((const int*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
640 inRangeS_((const float*)sptr, lbuf.f, rbuf.f, dptr, total, cn);
643 inRangeS_((const double*)sptr, lbuf.d, rbuf.d, dptr, total, cn);
646 CV_Error(CV_StsUnsupportedFormat, "");
652 struct InRangeSOp : public BaseElemWiseOp
654 InRangeSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {};
655 void op(const vector<Mat>& src, Mat& dst, const Mat&)
657 cv::inRange(src[0], gamma, gamma1, dst);
659 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
661 cvtest::inRangeS(src[0], gamma, gamma1, dst);
663 double getMaxErr(int)
667 void generateScalars(int depth, RNG& rng)
669 BaseElemWiseOp::generateScalars(depth, rng);
671 BaseElemWiseOp::generateScalars(depth, rng);
672 for( int i = 0; i < 4; i++ )
674 gamma1[i] = std::max(gamma[i], temp[i]);
675 gamma[i] = std::min(gamma[i], temp[i]);
682 struct InRangeOp : public BaseElemWiseOp
684 InRangeOp() : BaseElemWiseOp(3, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
685 void op(const vector<Mat>& src, Mat& dst, const Mat&)
688 cvtest::min(src[1], src[2], lb);
689 cvtest::max(src[1], src[2], rb);
691 cv::inRange(src[0], lb, rb, dst);
693 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
696 cvtest::min(src[1], src[2], lb);
697 cvtest::max(src[1], src[2], rb);
699 cvtest::inRange(src[0], lb, rb, dst);
701 double getMaxErr(int)
708 struct ConvertScaleOp : public BaseElemWiseOp
710 ConvertScaleOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)), ddepth(0) { };
711 void op(const vector<Mat>& src, Mat& dst, const Mat&)
713 src[0].convertTo(dst, ddepth, alpha, gamma[0]);
715 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
717 cvtest::convert(src[0], dst, CV_MAKETYPE(ddepth, src[0].channels()), alpha, gamma[0]);
719 int getRandomType(RNG& rng)
721 int srctype = cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
722 ddepth = cvtest::randomType(rng, DEPTH_MASK_ALL, 1, 1);
725 double getMaxErr(int)
727 return ddepth <= CV_32S ? 2 : ddepth < CV_64F ? 1e-3 : 1e-12;
729 void generateScalars(int depth, RNG& rng)
731 if( rng.uniform(0, 2) )
732 BaseElemWiseOp::generateScalars(depth, rng);
736 gamma = Scalar::all(0);
743 struct ConvertScaleAbsOp : public BaseElemWiseOp
745 ConvertScaleAbsOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {};
746 void op(const vector<Mat>& src, Mat& dst, const Mat&)
748 cv::convertScaleAbs(src[0], dst, alpha, gamma[0]);
750 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
752 cvtest::add(src[0], alpha, Mat(), 0, Scalar::all(gamma[0]), dst, CV_8UC(src[0].channels()), true);
754 double getMaxErr(int)
758 void generateScalars(int depth, RNG& rng)
760 if( rng.uniform(0, 2) )
761 BaseElemWiseOp::generateScalars(depth, rng);
765 gamma = Scalar::all(0);
771 static void flip(const Mat& src, Mat& dst, int flipcode)
773 CV_Assert(src.dims == 2);
774 dst.create(src.size(), src.type());
775 int i, j, k, esz = (int)src.elemSize(), width = src.cols*esz;
777 for( i = 0; i < dst.rows; i++ )
779 const uchar* sptr = src.ptr(flipcode == 1 ? i : dst.rows - i - 1);
780 uchar* dptr = dst.ptr(i);
782 memcpy(dptr, sptr, width);
785 for( j = 0; j < width; j += esz )
786 for( k = 0; k < esz; k++ )
787 dptr[j + k] = sptr[width - j - esz + k];
793 static void setIdentity(Mat& dst, const Scalar& s)
795 CV_Assert( dst.dims == 2 && dst.channels() <= 4 );
797 scalarToRawData(s, buf, dst.type(), 0);
798 int i, k, esz = (int)dst.elemSize(), width = dst.cols*esz;
800 for( i = 0; i < dst.rows; i++ )
802 uchar* dptr = dst.ptr(i);
803 memset( dptr, 0, width );
805 for( k = 0; k < esz; k++ )
806 dptr[i*esz + k] = ((uchar*)buf)[k];
811 struct FlipOp : public BaseElemWiseOp
813 FlipOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
814 void getRandomSize(RNG& rng, vector<int>& size)
816 cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size);
818 void op(const vector<Mat>& src, Mat& dst, const Mat&)
820 cv::flip(src[0], dst, flipcode);
822 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
824 cvtest::flip(src[0], dst, flipcode);
826 void generateScalars(int, RNG& rng)
828 flipcode = rng.uniform(0, 3) - 1;
830 double getMaxErr(int)
837 struct TransposeOp : public BaseElemWiseOp
839 TransposeOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
840 void getRandomSize(RNG& rng, vector<int>& size)
842 cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size);
844 void op(const vector<Mat>& src, Mat& dst, const Mat&)
846 cv::transpose(src[0], dst);
848 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
850 cvtest::transpose(src[0], dst);
852 double getMaxErr(int)
858 struct SetIdentityOp : public BaseElemWiseOp
860 SetIdentityOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {};
861 void getRandomSize(RNG& rng, vector<int>& size)
863 cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size);
865 void op(const vector<Mat>&, Mat& dst, const Mat&)
867 cv::setIdentity(dst, gamma);
869 void refop(const vector<Mat>&, Mat& dst, const Mat&)
871 cvtest::setIdentity(dst, gamma);
873 double getMaxErr(int)
879 struct SetZeroOp : public BaseElemWiseOp
881 SetZeroOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
882 void op(const vector<Mat>&, Mat& dst, const Mat&)
884 dst = Scalar::all(0);
886 void refop(const vector<Mat>&, Mat& dst, const Mat&)
888 cvtest::set(dst, Scalar::all(0));
890 double getMaxErr(int)
897 static void exp(const Mat& src, Mat& dst)
899 dst.create( src.dims, &src.size[0], src.type() );
900 const Mat *arrays[]={&src, &dst, 0};
903 NAryMatIterator it(arrays, planes);
904 size_t j, total = planes[0].total()*src.channels();
905 size_t i, nplanes = it.nplanes;
906 int depth = src.depth();
908 for( i = 0; i < nplanes; i++, ++it )
910 const uchar* sptr = planes[0].data;
911 uchar* dptr = planes[1].data;
913 if( depth == CV_32F )
915 for( j = 0; j < total; j++ )
916 ((float*)dptr)[j] = std::exp(((const float*)sptr)[j]);
918 else if( depth == CV_64F )
920 for( j = 0; j < total; j++ )
921 ((double*)dptr)[j] = std::exp(((const double*)sptr)[j]);
926 static void log(const Mat& src, Mat& dst)
928 dst.create( src.dims, &src.size[0], src.type() );
929 const Mat *arrays[]={&src, &dst, 0};
932 NAryMatIterator it(arrays, planes);
933 size_t j, total = planes[0].total()*src.channels();
934 size_t i, nplanes = it.nplanes;
935 int depth = src.depth();
937 for( i = 0; i < nplanes; i++, ++it )
939 const uchar* sptr = planes[0].data;
940 uchar* dptr = planes[1].data;
942 if( depth == CV_32F )
944 for( j = 0; j < total; j++ )
945 ((float*)dptr)[j] = (float)std::log(fabs(((const float*)sptr)[j]));
947 else if( depth == CV_64F )
949 for( j = 0; j < total; j++ )
950 ((double*)dptr)[j] = std::log(fabs(((const double*)sptr)[j]));
955 struct ExpOp : public BaseElemWiseOp
957 ExpOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
958 int getRandomType(RNG& rng)
960 return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
962 void getValueRange(int depth, double& minval, double& maxval)
964 maxval = depth == CV_32F ? 50 : 100;
967 void op(const vector<Mat>& src, Mat& dst, const Mat&)
969 cv::exp(src[0], dst);
971 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
973 cvtest::exp(src[0], dst);
975 double getMaxErr(int depth)
977 return depth == CV_32F ? 1e-5 : 1e-12;
982 struct LogOp : public BaseElemWiseOp
984 LogOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
985 int getRandomType(RNG& rng)
987 return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
989 void getValueRange(int depth, double& minval, double& maxval)
991 maxval = depth == CV_32F ? 50 : 100;
994 void op(const vector<Mat>& src, Mat& dst, const Mat&)
997 cvtest::exp(src[0], temp);
1000 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1003 cvtest::exp(src[0], temp);
1004 cvtest::log(temp, dst);
1006 double getMaxErr(int depth)
1008 return depth == CV_32F ? 1e-5 : 1e-12;
1013 static void cartToPolar(const Mat& mx, const Mat& my, Mat& mmag, Mat& mangle, bool angleInDegrees)
1015 CV_Assert( (mx.type() == CV_32F || mx.type() == CV_64F) &&
1016 mx.type() == my.type() && mx.size == my.size );
1017 mmag.create( mx.dims, &mx.size[0], mx.type() );
1018 mangle.create( mx.dims, &mx.size[0], mx.type() );
1019 const Mat *arrays[]={&mx, &my, &mmag, &mangle, 0};
1022 NAryMatIterator it(arrays, planes);
1023 size_t j, total = planes[0].total();
1024 size_t i, nplanes = it.nplanes;
1025 int depth = mx.depth();
1026 double scale = angleInDegrees ? 180/CV_PI : 1;
1028 for( i = 0; i < nplanes; i++, ++it )
1030 if( depth == CV_32F )
1032 const float* xptr = (const float*)planes[0].data;
1033 const float* yptr = (const float*)planes[1].data;
1034 float* mptr = (float*)planes[2].data;
1035 float* aptr = (float*)planes[3].data;
1037 for( j = 0; j < total; j++ )
1039 mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]);
1040 double a = atan2((double)yptr[j], (double)xptr[j]);
1041 if( a < 0 ) a += CV_PI*2;
1042 aptr[j] = (float)(a*scale);
1047 const double* xptr = (const double*)planes[0].data;
1048 const double* yptr = (const double*)planes[1].data;
1049 double* mptr = (double*)planes[2].data;
1050 double* aptr = (double*)planes[3].data;
1052 for( j = 0; j < total; j++ )
1054 mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]);
1055 double a = atan2(yptr[j], xptr[j]);
1056 if( a < 0 ) a += CV_PI*2;
1064 struct CartToPolarToCartOp : public BaseElemWiseOp
1066 CartToPolarToCartOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0))
1069 angleInDegrees = true;
1071 int getRandomType(RNG& rng)
1073 return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, 1);
1075 void op(const vector<Mat>& src, Mat& dst, const Mat&)
1077 Mat mag, angle, x, y;
1079 cv::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
1080 cv::polarToCart(mag, angle, x, y, angleInDegrees);
1082 Mat msrc[] = {mag, angle, x, y};
1083 int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
1084 dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
1085 cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
1087 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1090 cvtest::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
1091 Mat msrc[] = {mag, angle, src[0], src[1]};
1092 int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
1093 dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
1094 cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
1096 void generateScalars(int, RNG& rng)
1098 angleInDegrees = rng.uniform(0, 2) != 0;
1100 double getMaxErr(int)
1104 bool angleInDegrees;
1108 struct MeanOp : public BaseElemWiseOp
1110 MeanOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1114 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1116 dst.create(1, 1, CV_64FC4);
1117 dst.at<Scalar>(0,0) = cv::mean(src[0], mask);
1119 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1121 dst.create(1, 1, CV_64FC4);
1122 dst.at<Scalar>(0,0) = cvtest::mean(src[0], mask);
1124 double getMaxErr(int)
1131 struct SumOp : public BaseElemWiseOp
1133 SumOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1137 void op(const vector<Mat>& src, Mat& dst, const Mat&)
1139 dst.create(1, 1, CV_64FC4);
1140 dst.at<Scalar>(0,0) = cv::sum(src[0]);
1142 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1144 dst.create(1, 1, CV_64FC4);
1145 dst.at<Scalar>(0,0) = cvtest::mean(src[0])*(double)src[0].total();
1147 double getMaxErr(int)
1154 struct CountNonZeroOp : public BaseElemWiseOp
1156 CountNonZeroOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT+SUPPORT_MASK, 1, 1, Scalar::all(0))
1158 int getRandomType(RNG& rng)
1160 return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, 1);
1162 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1165 src[0].copyTo(temp);
1167 temp.setTo(Scalar::all(0), mask);
1168 dst.create(1, 1, CV_32S);
1169 dst.at<int>(0,0) = cv::countNonZero(temp);
1171 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1174 cvtest::compare(src[0], 0, temp, CMP_NE);
1176 cvtest::set(temp, Scalar::all(0), mask);
1177 dst.create(1, 1, CV_32S);
1178 dst.at<int>(0,0) = saturate_cast<int>(cvtest::mean(temp)[0]/255*temp.total());
1180 double getMaxErr(int)
1187 struct MeanStdDevOp : public BaseElemWiseOp
1192 MeanStdDevOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1197 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1199 dst.create(1, 2, CV_64FC4);
1200 cv::meanStdDev(src[0], dst.at<Scalar>(0,0), dst.at<Scalar>(0,1), mask);
1202 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1205 cvtest::convert(src[0], temp, CV_64F);
1206 cvtest::multiply(temp, temp, temp);
1207 Scalar mean = cvtest::mean(src[0], mask);
1208 Scalar sqmean = cvtest::mean(temp, mask);
1211 cn = temp.channels();
1213 for( int c = 0; c < 4; c++ )
1214 sqmean[c] = std::sqrt(std::max(sqmean[c] - mean[c]*mean[c], 0.));
1216 dst.create(1, 2, CV_64FC4);
1217 dst.at<Scalar>(0,0) = mean;
1218 dst.at<Scalar>(0,1) = sqmean;
1220 double getMaxErr(int)
1223 double err = sqmeanRef[0];
1224 for(int i = 1; i < cn; ++i)
1225 err = std::max(err, sqmeanRef[i]);
1231 struct NormOp : public BaseElemWiseOp
1233 NormOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1238 int getRandomType(RNG& rng)
1240 int type = cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 4);
1243 normType = rng.uniform(1, 8);
1244 if( normType == NORM_INF || normType == NORM_L1 ||
1245 normType == NORM_L2 || normType == NORM_L2SQR ||
1246 normType == NORM_HAMMING || normType == NORM_HAMMING2 )
1249 if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
1255 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1257 dst.create(1, 2, CV_64FC1);
1258 dst.at<double>(0,0) = cv::norm(src[0], normType, mask);
1259 dst.at<double>(0,1) = cv::norm(src[0], src[1], normType, mask);
1261 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1263 dst.create(1, 2, CV_64FC1);
1264 dst.at<double>(0,0) = cvtest::norm(src[0], normType, mask);
1265 dst.at<double>(0,1) = cvtest::norm(src[0], src[1], normType, mask);
1267 void generateScalars(int, RNG& /*rng*/)
1270 double getMaxErr(int)
1278 struct MinMaxLocOp : public BaseElemWiseOp
1280 MinMaxLocOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1282 context = ARITHM_MAX_NDIMS*2 + 2;
1284 int getRandomType(RNG& rng)
1286 return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1);
1288 void saveOutput(const vector<int>& minidx, const vector<int>& maxidx,
1289 double minval, double maxval, Mat& dst)
1291 int i, ndims = (int)minidx.size();
1292 dst.create(1, ndims*2 + 2, CV_64FC1);
1294 for( i = 0; i < ndims; i++ )
1296 dst.at<double>(0,i) = minidx[i];
1297 dst.at<double>(0,i+ndims) = maxidx[i];
1299 dst.at<double>(0,ndims*2) = minval;
1300 dst.at<double>(0,ndims*2+1) = maxval;
1302 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1304 int ndims = src[0].dims;
1305 vector<int> minidx(ndims), maxidx(ndims);
1306 double minval=0, maxval=0;
1307 cv::minMaxIdx(src[0], &minval, &maxval, &minidx[0], &maxidx[0], mask);
1308 saveOutput(minidx, maxidx, minval, maxval, dst);
1310 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1312 int ndims=src[0].dims;
1313 vector<int> minidx(ndims), maxidx(ndims);
1314 double minval=0, maxval=0;
1315 cvtest::minMaxLoc(src[0], &minval, &maxval, &minidx, &maxidx, mask);
1316 saveOutput(minidx, maxidx, minval, maxval, dst);
1318 double getMaxErr(int)
1327 typedef Ptr<cvtest::BaseElemWiseOp> ElemWiseOpPtr;
1328 class ElemWiseTest : public ::testing::TestWithParam<ElemWiseOpPtr> {};
1330 TEST_P(ElemWiseTest, accuracy)
1332 ElemWiseOpPtr op = GetParam();
1335 RNG rng((uint64)cvtest::ARITHM_RNG_SEED);
1336 for( testIdx = 0; testIdx < cvtest::ARITHM_NTESTS; testIdx++ )
1339 op->getRandomSize(rng, size);
1340 int type = op->getRandomType(rng);
1341 int depth = CV_MAT_DEPTH(type);
1342 bool haveMask = (op->flags & cvtest::BaseElemWiseOp::SUPPORT_MASK) != 0 && rng.uniform(0, 4) == 0;
1344 double minval=0, maxval=0;
1345 op->getValueRange(depth, minval, maxval);
1346 int i, ninputs = op->ninputs;
1347 vector<Mat> src(ninputs);
1348 for( i = 0; i < ninputs; i++ )
1349 src[i] = cvtest::randomMat(rng, size, type, minval, maxval, true);
1350 Mat dst0, dst, mask;
1352 mask = cvtest::randomMat(rng, size, CV_8U, 0, 2, true);
1354 if( (haveMask || ninputs == 0) && !(op->flags & cvtest::BaseElemWiseOp::SCALAR_OUTPUT))
1356 dst0 = cvtest::randomMat(rng, size, type, minval, maxval, false);
1357 dst = cvtest::randomMat(rng, size, type, minval, maxval, true);
1358 cvtest::copy(dst, dst0);
1360 op->generateScalars(depth, rng);
1362 op->refop(src, dst0, mask);
1363 op->op(src, dst, mask);
1365 double maxErr = op->getMaxErr(depth);
1367 ASSERT_PRED_FORMAT2(cvtest::MatComparator(maxErr, op->context), dst0, dst) << "\nsrc[0] ~ " << cvtest::MatInfo(!src.empty() ? src[0] : Mat()) << "\ntestCase #" << testIdx << "\n";
1372 INSTANTIATE_TEST_CASE_P(Core_Copy, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CopyOp)));
1373 INSTANTIATE_TEST_CASE_P(Core_Set, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetOp)));
1374 INSTANTIATE_TEST_CASE_P(Core_SetZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetZeroOp)));
1375 INSTANTIATE_TEST_CASE_P(Core_ConvertScale, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ConvertScaleOp)));
1376 INSTANTIATE_TEST_CASE_P(Core_ConvertScaleAbs, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ConvertScaleAbsOp)));
1378 INSTANTIATE_TEST_CASE_P(Core_Add, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddOp)));
1379 INSTANTIATE_TEST_CASE_P(Core_Sub, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SubOp)));
1380 INSTANTIATE_TEST_CASE_P(Core_AddS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddSOp)));
1381 INSTANTIATE_TEST_CASE_P(Core_SubRS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SubRSOp)));
1382 INSTANTIATE_TEST_CASE_P(Core_ScaleAdd, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ScaleAddOp)));
1383 INSTANTIATE_TEST_CASE_P(Core_AddWeighted, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddWeightedOp)));
1384 INSTANTIATE_TEST_CASE_P(Core_AbsDiff, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AbsDiffOp)));
1387 INSTANTIATE_TEST_CASE_P(Core_AbsDiffS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AbsDiffSOp)));
1389 INSTANTIATE_TEST_CASE_P(Core_And, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('&'))));
1390 INSTANTIATE_TEST_CASE_P(Core_AndS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('&'))));
1391 INSTANTIATE_TEST_CASE_P(Core_Or, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('|'))));
1392 INSTANTIATE_TEST_CASE_P(Core_OrS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('|'))));
1393 INSTANTIATE_TEST_CASE_P(Core_Xor, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('^'))));
1394 INSTANTIATE_TEST_CASE_P(Core_XorS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('^'))));
1395 INSTANTIATE_TEST_CASE_P(Core_Not, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('~'))));
1397 INSTANTIATE_TEST_CASE_P(Core_Max, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MaxOp)));
1398 INSTANTIATE_TEST_CASE_P(Core_MaxS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MaxSOp)));
1399 INSTANTIATE_TEST_CASE_P(Core_Min, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinOp)));
1400 INSTANTIATE_TEST_CASE_P(Core_MinS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinSOp)));
1402 INSTANTIATE_TEST_CASE_P(Core_Mul, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MulOp)));
1403 INSTANTIATE_TEST_CASE_P(Core_Div, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::DivOp)));
1404 INSTANTIATE_TEST_CASE_P(Core_Recip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::RecipOp)));
1406 INSTANTIATE_TEST_CASE_P(Core_Cmp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CmpOp)));
1407 INSTANTIATE_TEST_CASE_P(Core_CmpS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CmpSOp)));
1409 INSTANTIATE_TEST_CASE_P(Core_InRangeS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::InRangeSOp)));
1410 INSTANTIATE_TEST_CASE_P(Core_InRange, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::InRangeOp)));
1412 INSTANTIATE_TEST_CASE_P(Core_Flip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::FlipOp)));
1413 INSTANTIATE_TEST_CASE_P(Core_Transpose, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::TransposeOp)));
1414 INSTANTIATE_TEST_CASE_P(Core_SetIdentity, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetIdentityOp)));
1416 INSTANTIATE_TEST_CASE_P(Core_Exp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ExpOp)));
1417 INSTANTIATE_TEST_CASE_P(Core_Log, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogOp)));
1419 INSTANTIATE_TEST_CASE_P(Core_CountNonZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CountNonZeroOp)));
1420 INSTANTIATE_TEST_CASE_P(Core_Mean, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MeanOp)));
1421 INSTANTIATE_TEST_CASE_P(Core_MeanStdDev, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MeanStdDevOp)));
1422 INSTANTIATE_TEST_CASE_P(Core_Sum, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SumOp)));
1423 INSTANTIATE_TEST_CASE_P(Core_Norm, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::NormOp)));
1424 INSTANTIATE_TEST_CASE_P(Core_MinMaxLoc, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinMaxLocOp)));
1425 INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CartToPolarToCartOp)));
1428 class CV_ArithmMaskTest : public cvtest::BaseTest
1431 CV_ArithmMaskTest() {}
1432 ~CV_ArithmMaskTest() {}
1438 RNG& rng = theRNG();
1439 const int MAX_DIM=3;
1441 for( int iter = 0; iter < 100; iter++ )
1443 //ts->printf(cvtest::TS::LOG, ".");
1445 ts->update_context(this, iter, true);
1446 int k, dims = rng.uniform(1, MAX_DIM+1), p = 1;
1447 int depth = rng.uniform(CV_8U, CV_64F+1);
1448 int cn = rng.uniform(1, 6);
1449 int type = CV_MAKETYPE(depth, cn);
1450 int op = rng.uniform(0, 5);
1451 int depth1 = op <= 1 ? CV_64F : depth;
1452 for( k = 0; k < dims; k++ )
1454 sizes[k] = rng.uniform(1, 30);
1457 Mat a(dims, sizes, type), a1;
1458 Mat b(dims, sizes, type), b1;
1459 Mat mask(dims, sizes, CV_8U);
1463 rng.fill(a, RNG::UNIFORM, 0, 100);
1464 rng.fill(b, RNG::UNIFORM, 0, 100);
1466 // [-2,2) range means that the each generated random number
1467 // will be one of -2, -1, 0, 1. Saturated to [0,255], it will become
1468 // 0, 0, 0, 1 => the mask will be filled by ~25%.
1469 rng.fill(mask, RNG::UNIFORM, -2, 2);
1471 a.convertTo(a1, depth1);
1472 b.convertTo(b1, depth1);
1474 compare(mask, 0, mask1, CMP_EQ);
1485 subtract(a, b, c, mask);
1486 subtract(a1, b1, d);
1490 bitwise_and(a, b, c, mask);
1491 bitwise_and(a1, b1, d);
1495 bitwise_or(a, b, c, mask);
1496 bitwise_or(a1, b1, d);
1500 bitwise_xor(a, b, c, mask);
1501 bitwise_xor(a1, b1, d);
1504 d.convertTo(d1, depth);
1505 CV_Assert( norm(c, d1, CV_C) <= DBL_EPSILON );
1508 Mat_<uchar> tmpSrc(100,100);
1510 Mat_<uchar> tmpMask(100,100);
1512 Mat_<uchar> tmpDst(100,100);
1514 tmpSrc.copyTo(tmpDst,tmpMask);
1518 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
1523 TEST(Core_ArithmMask, uninitialized) { CV_ArithmMaskTest test; test.safe_run(); }
1525 TEST(Multiply, FloatingPointRounding)
1527 cv::Mat src(1, 1, CV_8UC1, cv::Scalar::all(110)), dst;
1528 cv::Scalar s(147.286359696927, 1, 1 ,1);
1530 cv::multiply(src, s, dst, 1, CV_16U);
1531 // with CV_32F this produce result 16202
1532 ASSERT_EQ(dst.at<ushort>(0,0), 16201);
1535 TEST(Core_Add, AddToColumnWhen3Rows)
1537 cv::Mat m1 = (cv::Mat_<double>(3, 2) << 1, 2, 3, 4, 5, 6);
1540 cv::Mat m2 = (cv::Mat_<double>(3, 2) << 1, 12, 3, 14, 5, 16);
1542 ASSERT_EQ(0, countNonZero(m1 - m2));
1545 TEST(Core_Add, AddToColumnWhen4Rows)
1547 cv::Mat m1 = (cv::Mat_<double>(4, 2) << 1, 2, 3, 4, 5, 6, 7, 8);
1550 cv::Mat m2 = (cv::Mat_<double>(4, 2) << 1, 12, 3, 14, 5, 16, 7, 18);
1552 ASSERT_EQ(0, countNonZero(m1 - m2));
1555 TEST(Core_round, CvRound)
1557 ASSERT_EQ(2, cvRound(2.0));
1558 ASSERT_EQ(2, cvRound(2.1));
1559 ASSERT_EQ(-2, cvRound(-2.1));
1560 ASSERT_EQ(3, cvRound(2.8));
1561 ASSERT_EQ(-3, cvRound(-2.8));
1562 ASSERT_EQ(2, cvRound(2.5));
1563 ASSERT_EQ(4, cvRound(3.5));
1564 ASSERT_EQ(-2, cvRound(-2.5));
1565 ASSERT_EQ(-4, cvRound(-3.5));