1 #include "test_precomp.hpp"
2
3 using namespace cv;
4 using namespace std;
5
6 namespace cvtest
7 {
8
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;
14
15 struct BaseElemWiseOp
16 {
17 enum { FIX_ALPHA=1, FIX_BETA=2, FIX_GAMMA=4, REAL_GAMMA=8, SUPPORT_MASK=16, SCALAR_OUTPUT=32 };
BaseElemWiseOpcvtest::BaseElemWiseOp18 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) {}
BaseElemWiseOpcvtest::BaseElemWiseOp21 BaseElemWiseOp() { flags = 0; alpha = beta = 0; gamma = Scalar::all(0); ninputs = 0; context = 1; }
~BaseElemWiseOpcvtest::BaseElemWiseOp22 virtual ~BaseElemWiseOp() {}
opcvtest::BaseElemWiseOp23 virtual void op(const vector<Mat>&, Mat&, const Mat&) {}
refopcvtest::BaseElemWiseOp24 virtual void refop(const vector<Mat>&, Mat&, const Mat&) {}
getValueRangecvtest::BaseElemWiseOp25 virtual void getValueRange(int depth, double& minval, double& maxval)
26 {
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.;
29 }
30
getRandomSizecvtest::BaseElemWiseOp31 virtual void getRandomSize(RNG& rng, vector<int>& size)
32 {
33 cvtest::randomSize(rng, 2, ARITHM_MAX_NDIMS, cvtest::ARITHM_MAX_SIZE_LOG, size);
34 }
35
getRandomTypecvtest::BaseElemWiseOp36 virtual int getRandomType(RNG& rng)
37 {
38 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1,
39 ninputs > 1 ? ARITHM_MAX_CHANNELS : 4);
40 }
41
getMaxErrcvtest::BaseElemWiseOp42 virtual double getMaxErr(int depth) { return depth < CV_32F ? 1 : depth == CV_32F ? 1e-5 : 1e-12; }
generateScalarscvtest::BaseElemWiseOp43 virtual void generateScalars(int depth, RNG& rng)
44 {
45 const double m = 3.;
46
47 if( !(flags & FIX_ALPHA) )
48 {
49 alpha = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2);
50 alpha *= rng.uniform(0, 2) ? 1 : -1;
51 }
52 if( !(flags & FIX_BETA) )
53 {
54 beta = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2);
55 beta *= rng.uniform(0, 2) ? 1 : -1;
56 }
57
58 if( !(flags & FIX_GAMMA) )
59 {
60 for( int i = 0; i < 4; i++ )
61 {
62 gamma[i] = exp(rng.uniform(-1, 6)*m*CV_LOG2);
63 gamma[i] *= rng.uniform(0, 2) ? 1 : -1;
64 }
65 if( flags & REAL_GAMMA )
66 gamma = Scalar::all(gamma[0]);
67 }
68
69 if( depth == CV_32F )
70 {
71 Mat fl, db;
72
73 db = Mat(1, 1, CV_64F, &alpha);
74 db.convertTo(fl, CV_32F);
75 fl.convertTo(db, CV_64F);
76
77 db = Mat(1, 1, CV_64F, &beta);
78 db.convertTo(fl, CV_32F);
79 fl.convertTo(db, CV_64F);
80
81 db = Mat(1, 4, CV_64F, &gamma[0]);
82 db.convertTo(fl, CV_32F);
83 fl.convertTo(db, CV_64F);
84 }
85 }
86
87 int ninputs;
88 int flags;
89 double alpha;
90 double beta;
91 Scalar gamma;
92 int context;
93 };
94
95
96 struct BaseAddOp : public BaseElemWiseOp
97 {
BaseAddOpcvtest::BaseAddOp98 BaseAddOp(int _ninputs, int _flags, double _alpha, double _beta, Scalar _gamma=Scalar::all(0))
99 : BaseElemWiseOp(_ninputs, _flags, _alpha, _beta, _gamma) {}
100
refopcvtest::BaseAddOp101 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
102 {
103 Mat temp;
104 if( !mask.empty() )
105 {
106 cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, temp, src[0].type());
107 cvtest::copy(temp, dst, mask);
108 }
109 else
110 cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, dst, src[0].type());
111 }
112 };
113
114
115 struct AddOp : public BaseAddOp
116 {
AddOpcvtest::AddOp117 AddOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {}
opcvtest::AddOp118 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
119 {
120 if( mask.empty() )
121 add(src[0], src[1], dst);
122 else
123 add(src[0], src[1], dst, mask);
124 }
125 };
126
127
128 struct SubOp : public BaseAddOp
129 {
SubOpcvtest::SubOp130 SubOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, -1, Scalar::all(0)) {}
opcvtest::SubOp131 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
132 {
133 if( mask.empty() )
134 subtract(src[0], src[1], dst);
135 else
136 subtract(src[0], src[1], dst, mask);
137 }
138 };
139
140
141 struct AddSOp : public BaseAddOp
142 {
AddSOpcvtest::AddSOp143 AddSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, 1, 0, Scalar::all(0)) {}
opcvtest::AddSOp144 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
145 {
146 if( mask.empty() )
147 add(src[0], gamma, dst);
148 else
149 add(src[0], gamma, dst, mask);
150 }
151 };
152
153
154 struct SubRSOp : public BaseAddOp
155 {
SubRSOpcvtest::SubRSOp156 SubRSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, -1, 0, Scalar::all(0)) {}
opcvtest::SubRSOp157 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
158 {
159 if( mask.empty() )
160 subtract(gamma, src[0], dst);
161 else
162 subtract(gamma, src[0], dst, mask);
163 }
164 };
165
166
167 struct ScaleAddOp : public BaseAddOp
168 {
ScaleAddOpcvtest::ScaleAddOp169 ScaleAddOp() : BaseAddOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::ScaleAddOp170 void op(const vector<Mat>& src, Mat& dst, const Mat&)
171 {
172 scaleAdd(src[0], alpha, src[1], dst);
173 }
getMaxErrcvtest::ScaleAddOp174 double getMaxErr(int depth)
175 {
176 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-4 : 1e-12;
177 }
178 };
179
180
181 struct AddWeightedOp : public BaseAddOp
182 {
AddWeightedOpcvtest::AddWeightedOp183 AddWeightedOp() : BaseAddOp(2, REAL_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::AddWeightedOp184 void op(const vector<Mat>& src, Mat& dst, const Mat&)
185 {
186 addWeighted(src[0], alpha, src[1], beta, gamma[0], dst);
187 }
getMaxErrcvtest::AddWeightedOp188 double getMaxErr(int depth)
189 {
190 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-10;
191 }
192 };
193
194 struct MulOp : public BaseElemWiseOp
195 {
MulOpcvtest::MulOp196 MulOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
getValueRangecvtest::MulOp197 void getValueRange(int depth, double& minval, double& maxval)
198 {
199 minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.;
200 maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.;
201 minval = std::max(minval, -30000.);
202 maxval = std::min(maxval, 30000.);
203 }
opcvtest::MulOp204 void op(const vector<Mat>& src, Mat& dst, const Mat&)
205 {
206 cv::multiply(src[0], src[1], dst, alpha);
207 }
refopcvtest::MulOp208 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
209 {
210 cvtest::multiply(src[0], src[1], dst, alpha);
211 }
getMaxErrcvtest::MulOp212 double getMaxErr(int depth)
213 {
214 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
215 }
216 };
217
218 struct DivOp : public BaseElemWiseOp
219 {
DivOpcvtest::DivOp220 DivOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::DivOp221 void op(const vector<Mat>& src, Mat& dst, const Mat&)
222 {
223 cv::divide(src[0], src[1], dst, alpha);
224 }
refopcvtest::DivOp225 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
226 {
227 cvtest::divide(src[0], src[1], dst, alpha);
228 }
getMaxErrcvtest::DivOp229 double getMaxErr(int depth)
230 {
231 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
232 }
233 };
234
235 struct RecipOp : public BaseElemWiseOp
236 {
RecipOpcvtest::RecipOp237 RecipOp() : BaseElemWiseOp(1, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::RecipOp238 void op(const vector<Mat>& src, Mat& dst, const Mat&)
239 {
240 cv::divide(alpha, src[0], dst);
241 }
refopcvtest::RecipOp242 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
243 {
244 cvtest::divide(Mat(), src[0], dst, alpha);
245 }
getMaxErrcvtest::RecipOp246 double getMaxErr(int depth)
247 {
248 return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12;
249 }
250 };
251
252 struct AbsDiffOp : public BaseAddOp
253 {
AbsDiffOpcvtest::AbsDiffOp254 AbsDiffOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, -1, Scalar::all(0)) {}
opcvtest::AbsDiffOp255 void op(const vector<Mat>& src, Mat& dst, const Mat&)
256 {
257 absdiff(src[0], src[1], dst);
258 }
refopcvtest::AbsDiffOp259 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
260 {
261 cvtest::add(src[0], 1, src[1], -1, Scalar::all(0), dst, src[0].type(), true);
262 }
263 };
264
265 struct AbsDiffSOp : public BaseAddOp
266 {
AbsDiffSOpcvtest::AbsDiffSOp267 AbsDiffSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA, 1, 0, Scalar::all(0)) {}
opcvtest::AbsDiffSOp268 void op(const vector<Mat>& src, Mat& dst, const Mat&)
269 {
270 absdiff(src[0], gamma, dst);
271 }
refopcvtest::AbsDiffSOp272 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
273 {
274 cvtest::add(src[0], 1, Mat(), 0, -gamma, dst, src[0].type(), true);
275 }
276 };
277
278 struct LogicOp : public BaseElemWiseOp
279 {
LogicOpcvtest::LogicOp280 LogicOp(char _opcode) : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)), opcode(_opcode) {}
opcvtest::LogicOp281 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
282 {
283 if( opcode == '&' )
284 bitwise_and(src[0], src[1], dst, mask);
285 else if( opcode == '|' )
286 bitwise_or(src[0], src[1], dst, mask);
287 else
288 bitwise_xor(src[0], src[1], dst, mask);
289 }
refopcvtest::LogicOp290 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
291 {
292 Mat temp;
293 if( !mask.empty() )
294 {
295 cvtest::logicOp(src[0], src[1], temp, opcode);
296 cvtest::copy(temp, dst, mask);
297 }
298 else
299 cvtest::logicOp(src[0], src[1], dst, opcode);
300 }
getMaxErrcvtest::LogicOp301 double getMaxErr(int)
302 {
303 return 0;
304 }
305 char opcode;
306 };
307
308 struct LogicSOp : public BaseElemWiseOp
309 {
LogicSOpcvtest::LogicSOp310 LogicSOp(char _opcode)
311 : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+(_opcode != '~' ? SUPPORT_MASK : 0), 1, 1, Scalar::all(0)), opcode(_opcode) {}
opcvtest::LogicSOp312 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
313 {
314 if( opcode == '&' )
315 bitwise_and(src[0], gamma, dst, mask);
316 else if( opcode == '|' )
317 bitwise_or(src[0], gamma, dst, mask);
318 else if( opcode == '^' )
319 bitwise_xor(src[0], gamma, dst, mask);
320 else
321 bitwise_not(src[0], dst);
322 }
refopcvtest::LogicSOp323 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
324 {
325 Mat temp;
326 if( !mask.empty() )
327 {
328 cvtest::logicOp(src[0], gamma, temp, opcode);
329 cvtest::copy(temp, dst, mask);
330 }
331 else
332 cvtest::logicOp(src[0], gamma, dst, opcode);
333 }
getMaxErrcvtest::LogicSOp334 double getMaxErr(int)
335 {
336 return 0;
337 }
338 char opcode;
339 };
340
341 struct MinOp : public BaseElemWiseOp
342 {
MinOpcvtest::MinOp343 MinOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::MinOp344 void op(const vector<Mat>& src, Mat& dst, const Mat&)
345 {
346 cv::min(src[0], src[1], dst);
347 }
refopcvtest::MinOp348 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
349 {
350 cvtest::min(src[0], src[1], dst);
351 }
getMaxErrcvtest::MinOp352 double getMaxErr(int)
353 {
354 return 0;
355 }
356 };
357
358 struct MaxOp : public BaseElemWiseOp
359 {
MaxOpcvtest::MaxOp360 MaxOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::MaxOp361 void op(const vector<Mat>& src, Mat& dst, const Mat&)
362 {
363 cv::max(src[0], src[1], dst);
364 }
refopcvtest::MaxOp365 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
366 {
367 cvtest::max(src[0], src[1], dst);
368 }
getMaxErrcvtest::MaxOp369 double getMaxErr(int)
370 {
371 return 0;
372 }
373 };
374
375 struct MinSOp : public BaseElemWiseOp
376 {
MinSOpcvtest::MinSOp377 MinSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::MinSOp378 void op(const vector<Mat>& src, Mat& dst, const Mat&)
379 {
380 cv::min(src[0], gamma[0], dst);
381 }
refopcvtest::MinSOp382 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
383 {
384 cvtest::min(src[0], gamma[0], dst);
385 }
getMaxErrcvtest::MinSOp386 double getMaxErr(int)
387 {
388 return 0;
389 }
390 };
391
392 struct MaxSOp : public BaseElemWiseOp
393 {
MaxSOpcvtest::MaxSOp394 MaxSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::MaxSOp395 void op(const vector<Mat>& src, Mat& dst, const Mat&)
396 {
397 cv::max(src[0], gamma[0], dst);
398 }
refopcvtest::MaxSOp399 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
400 {
401 cvtest::max(src[0], gamma[0], dst);
402 }
getMaxErrcvtest::MaxSOp403 double getMaxErr(int)
404 {
405 return 0;
406 }
407 };
408
409 struct CmpOp : public BaseElemWiseOp
410 {
CmpOpcvtest::CmpOp411 CmpOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) { cmpop = 0; }
generateScalarscvtest::CmpOp412 void generateScalars(int depth, RNG& rng)
413 {
414 BaseElemWiseOp::generateScalars(depth, rng);
415 cmpop = rng.uniform(0, 6);
416 }
opcvtest::CmpOp417 void op(const vector<Mat>& src, Mat& dst, const Mat&)
418 {
419 cv::compare(src[0], src[1], dst, cmpop);
420 }
refopcvtest::CmpOp421 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
422 {
423 cvtest::compare(src[0], src[1], dst, cmpop);
424 }
getRandomTypecvtest::CmpOp425 int getRandomType(RNG& rng)
426 {
427 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
428 }
429
getMaxErrcvtest::CmpOp430 double getMaxErr(int)
431 {
432 return 0;
433 }
434 int cmpop;
435 };
436
437 struct CmpSOp : public BaseElemWiseOp
438 {
CmpSOpcvtest::CmpSOp439 CmpSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) { cmpop = 0; }
generateScalarscvtest::CmpSOp440 void generateScalars(int depth, RNG& rng)
441 {
442 BaseElemWiseOp::generateScalars(depth, rng);
443 cmpop = rng.uniform(0, 6);
444 if( depth < CV_32F )
445 gamma[0] = cvRound(gamma[0]);
446 }
opcvtest::CmpSOp447 void op(const vector<Mat>& src, Mat& dst, const Mat&)
448 {
449 cv::compare(src[0], gamma[0], dst, cmpop);
450 }
refopcvtest::CmpSOp451 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
452 {
453 cvtest::compare(src[0], gamma[0], dst, cmpop);
454 }
getRandomTypecvtest::CmpSOp455 int getRandomType(RNG& rng)
456 {
457 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
458 }
getMaxErrcvtest::CmpSOp459 double getMaxErr(int)
460 {
461 return 0;
462 }
463 int cmpop;
464 };
465
466
467 struct CopyOp : public BaseElemWiseOp
468 {
CopyOpcvtest::CopyOp469 CopyOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)) { }
opcvtest::CopyOp470 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
471 {
472 src[0].copyTo(dst, mask);
473 }
refopcvtest::CopyOp474 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
475 {
476 cvtest::copy(src[0], dst, mask);
477 }
getRandomTypecvtest::CopyOp478 int getRandomType(RNG& rng)
479 {
480 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
481 }
getMaxErrcvtest::CopyOp482 double getMaxErr(int)
483 {
484 return 0;
485 }
486 };
487
488
489 struct SetOp : public BaseElemWiseOp
490 {
SetOpcvtest::SetOp491 SetOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {}
opcvtest::SetOp492 void op(const vector<Mat>&, Mat& dst, const Mat& mask)
493 {
494 dst.setTo(gamma, mask);
495 }
refopcvtest::SetOp496 void refop(const vector<Mat>&, Mat& dst, const Mat& mask)
497 {
498 cvtest::set(dst, gamma, mask);
499 }
getRandomTypecvtest::SetOp500 int getRandomType(RNG& rng)
501 {
502 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
503 }
getMaxErrcvtest::SetOp504 double getMaxErr(int)
505 {
506 return 0;
507 }
508 };
509
510 template<typename _Tp, typename _WTp> static void
inRangeS_(const _Tp * src,const _WTp * a,const _WTp * b,uchar * dst,size_t total,int cn)511 inRangeS_(const _Tp* src, const _WTp* a, const _WTp* b, uchar* dst, size_t total, int cn)
512 {
513 size_t i;
514 int c;
515 for( i = 0; i < total; i++ )
516 {
517 _Tp val = src[i*cn];
518 dst[i] = (a[0] <= val && val <= b[0]) ? uchar(255) : 0;
519 }
520 for( c = 1; c < cn; c++ )
521 {
522 for( i = 0; i < total; i++ )
523 {
524 _Tp val = src[i*cn + c];
525 dst[i] = a[c] <= val && val <= b[c] ? dst[i] : 0;
526 }
527 }
528 }
529
inRange_(const _Tp * src,const _Tp * a,const _Tp * b,uchar * dst,size_t total,int cn)530 template<typename _Tp> static void inRange_(const _Tp* src, const _Tp* a, const _Tp* b, uchar* dst, size_t total, int cn)
531 {
532 size_t i;
533 int c;
534 for( i = 0; i < total; i++ )
535 {
536 _Tp val = src[i*cn];
537 dst[i] = a[i*cn] <= val && val <= b[i*cn] ? 255 : 0;
538 }
539 for( c = 1; c < cn; c++ )
540 {
541 for( i = 0; i < total; i++ )
542 {
543 _Tp val = src[i*cn + c];
544 dst[i] = a[i*cn + c] <= val && val <= b[i*cn + c] ? dst[i] : 0;
545 }
546 }
547 }
548
549
inRange(const Mat & src,const Mat & lb,const Mat & rb,Mat & dst)550 static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst)
551 {
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};
556 Mat planes[4];
557
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();
562
563 for( i = 0; i < nplanes; i++, ++it )
564 {
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();
569
570 switch( depth )
571 {
572 case CV_8U:
573 inRange_((const uchar*)sptr, (const uchar*)aptr, (const uchar*)bptr, dptr, total, cn);
574 break;
575 case CV_8S:
576 inRange_((const schar*)sptr, (const schar*)aptr, (const schar*)bptr, dptr, total, cn);
577 break;
578 case CV_16U:
579 inRange_((const ushort*)sptr, (const ushort*)aptr, (const ushort*)bptr, dptr, total, cn);
580 break;
581 case CV_16S:
582 inRange_((const short*)sptr, (const short*)aptr, (const short*)bptr, dptr, total, cn);
583 break;
584 case CV_32S:
585 inRange_((const int*)sptr, (const int*)aptr, (const int*)bptr, dptr, total, cn);
586 break;
587 case CV_32F:
588 inRange_((const float*)sptr, (const float*)aptr, (const float*)bptr, dptr, total, cn);
589 break;
590 case CV_64F:
591 inRange_((const double*)sptr, (const double*)aptr, (const double*)bptr, dptr, total, cn);
592 break;
593 default:
594 CV_Error(CV_StsUnsupportedFormat, "");
595 }
596 }
597 }
598
599
inRangeS(const Mat & src,const Scalar & lb,const Scalar & rb,Mat & dst)600 static void inRangeS(const Mat& src, const Scalar& lb, const Scalar& rb, Mat& dst)
601 {
602 dst.create( src.dims, &src.size[0], CV_8U );
603 const Mat *arrays[]={&src, &dst, 0};
604 Mat planes[2];
605
606 NAryMatIterator it(arrays, planes);
607 size_t total = planes[0].total();
608 size_t i, nplanes = it.nplanes;
609 int depth = src.depth(), cn = src.channels();
610 union { double d[4]; float f[4]; int i[4];} lbuf, rbuf;
611 int wtype = CV_MAKETYPE(depth <= CV_32S ? CV_32S : depth, cn);
612 scalarToRawData(lb, lbuf.d, wtype, cn);
613 scalarToRawData(rb, rbuf.d, wtype, cn);
614
615 for( i = 0; i < nplanes; i++, ++it )
616 {
617 const uchar* sptr = planes[0].ptr();
618 uchar* dptr = planes[1].ptr();
619
620 switch( depth )
621 {
622 case CV_8U:
623 inRangeS_((const uchar*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
624 break;
625 case CV_8S:
626 inRangeS_((const schar*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
627 break;
628 case CV_16U:
629 inRangeS_((const ushort*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
630 break;
631 case CV_16S:
632 inRangeS_((const short*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
633 break;
634 case CV_32S:
635 inRangeS_((const int*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
636 break;
637 case CV_32F:
638 inRangeS_((const float*)sptr, lbuf.f, rbuf.f, dptr, total, cn);
639 break;
640 case CV_64F:
641 inRangeS_((const double*)sptr, lbuf.d, rbuf.d, dptr, total, cn);
642 break;
643 default:
644 CV_Error(CV_StsUnsupportedFormat, "");
645 }
646 }
647 }
648
649
650 struct InRangeSOp : public BaseElemWiseOp
651 {
InRangeSOpcvtest::InRangeSOp652 InRangeSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {}
opcvtest::InRangeSOp653 void op(const vector<Mat>& src, Mat& dst, const Mat&)
654 {
655 cv::inRange(src[0], gamma, gamma1, dst);
656 }
refopcvtest::InRangeSOp657 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
658 {
659 cvtest::inRangeS(src[0], gamma, gamma1, dst);
660 }
getMaxErrcvtest::InRangeSOp661 double getMaxErr(int)
662 {
663 return 0;
664 }
generateScalarscvtest::InRangeSOp665 void generateScalars(int depth, RNG& rng)
666 {
667 BaseElemWiseOp::generateScalars(depth, rng);
668 Scalar temp = gamma;
669 BaseElemWiseOp::generateScalars(depth, rng);
670 for( int i = 0; i < 4; i++ )
671 {
672 gamma1[i] = std::max(gamma[i], temp[i]);
673 gamma[i] = std::min(gamma[i], temp[i]);
674 }
675 }
676 Scalar gamma1;
677 };
678
679
680 struct InRangeOp : public BaseElemWiseOp
681 {
InRangeOpcvtest::InRangeOp682 InRangeOp() : BaseElemWiseOp(3, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::InRangeOp683 void op(const vector<Mat>& src, Mat& dst, const Mat&)
684 {
685 Mat lb, rb;
686 cvtest::min(src[1], src[2], lb);
687 cvtest::max(src[1], src[2], rb);
688
689 cv::inRange(src[0], lb, rb, dst);
690 }
refopcvtest::InRangeOp691 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
692 {
693 Mat lb, rb;
694 cvtest::min(src[1], src[2], lb);
695 cvtest::max(src[1], src[2], rb);
696
697 cvtest::inRange(src[0], lb, rb, dst);
698 }
getMaxErrcvtest::InRangeOp699 double getMaxErr(int)
700 {
701 return 0;
702 }
703 };
704
705
706 struct ConvertScaleOp : public BaseElemWiseOp
707 {
ConvertScaleOpcvtest::ConvertScaleOp708 ConvertScaleOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)), ddepth(0) { }
opcvtest::ConvertScaleOp709 void op(const vector<Mat>& src, Mat& dst, const Mat&)
710 {
711 src[0].convertTo(dst, ddepth, alpha, gamma[0]);
712 }
refopcvtest::ConvertScaleOp713 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
714 {
715 cvtest::convert(src[0], dst, CV_MAKETYPE(ddepth, src[0].channels()), alpha, gamma[0]);
716 }
getRandomTypecvtest::ConvertScaleOp717 int getRandomType(RNG& rng)
718 {
719 int srctype = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
720 ddepth = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, 1);
721 return srctype;
722 }
getMaxErrcvtest::ConvertScaleOp723 double getMaxErr(int)
724 {
725 return ddepth <= CV_32S ? 2 : ddepth < CV_64F ? 1e-3 : 1e-12;
726 }
generateScalarscvtest::ConvertScaleOp727 void generateScalars(int depth, RNG& rng)
728 {
729 if( rng.uniform(0, 2) )
730 BaseElemWiseOp::generateScalars(depth, rng);
731 else
732 {
733 alpha = 1;
734 gamma = Scalar::all(0);
735 }
736 }
737 int ddepth;
738 };
739
740
741 struct ConvertScaleAbsOp : public BaseElemWiseOp
742 {
ConvertScaleAbsOpcvtest::ConvertScaleAbsOp743 ConvertScaleAbsOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::ConvertScaleAbsOp744 void op(const vector<Mat>& src, Mat& dst, const Mat&)
745 {
746 cv::convertScaleAbs(src[0], dst, alpha, gamma[0]);
747 }
refopcvtest::ConvertScaleAbsOp748 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
749 {
750 cvtest::add(src[0], alpha, Mat(), 0, Scalar::all(gamma[0]), dst, CV_8UC(src[0].channels()), true);
751 }
getMaxErrcvtest::ConvertScaleAbsOp752 double getMaxErr(int)
753 {
754 return 1;
755 }
generateScalarscvtest::ConvertScaleAbsOp756 void generateScalars(int depth, RNG& rng)
757 {
758 if( rng.uniform(0, 2) )
759 BaseElemWiseOp::generateScalars(depth, rng);
760 else
761 {
762 alpha = 1;
763 gamma = Scalar::all(0);
764 }
765 }
766 };
767
768
flip(const Mat & src,Mat & dst,int flipcode)769 static void flip(const Mat& src, Mat& dst, int flipcode)
770 {
771 CV_Assert(src.dims == 2);
772 dst.create(src.size(), src.type());
773 int i, j, k, esz = (int)src.elemSize(), width = src.cols*esz;
774
775 for( i = 0; i < dst.rows; i++ )
776 {
777 const uchar* sptr = src.ptr(flipcode == 1 ? i : dst.rows - i - 1);
778 uchar* dptr = dst.ptr(i);
779 if( flipcode == 0 )
780 memcpy(dptr, sptr, width);
781 else
782 {
783 for( j = 0; j < width; j += esz )
784 for( k = 0; k < esz; k++ )
785 dptr[j + k] = sptr[width - j - esz + k];
786 }
787 }
788 }
789
790
setIdentity(Mat & dst,const Scalar & s)791 static void setIdentity(Mat& dst, const Scalar& s)
792 {
793 CV_Assert( dst.dims == 2 && dst.channels() <= 4 );
794 double buf[4];
795 scalarToRawData(s, buf, dst.type(), 0);
796 int i, k, esz = (int)dst.elemSize(), width = dst.cols*esz;
797
798 for( i = 0; i < dst.rows; i++ )
799 {
800 uchar* dptr = dst.ptr(i);
801 memset( dptr, 0, width );
802 if( i < dst.cols )
803 for( k = 0; k < esz; k++ )
804 dptr[i*esz + k] = ((uchar*)buf)[k];
805 }
806 }
807
808
809 struct FlipOp : public BaseElemWiseOp
810 {
FlipOpcvtest::FlipOp811 FlipOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) { flipcode = 0; }
getRandomSizecvtest::FlipOp812 void getRandomSize(RNG& rng, vector<int>& size)
813 {
814 cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size);
815 }
opcvtest::FlipOp816 void op(const vector<Mat>& src, Mat& dst, const Mat&)
817 {
818 cv::flip(src[0], dst, flipcode);
819 }
refopcvtest::FlipOp820 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
821 {
822 cvtest::flip(src[0], dst, flipcode);
823 }
generateScalarscvtest::FlipOp824 void generateScalars(int, RNG& rng)
825 {
826 flipcode = rng.uniform(0, 3) - 1;
827 }
getMaxErrcvtest::FlipOp828 double getMaxErr(int)
829 {
830 return 0;
831 }
832 int flipcode;
833 };
834
835 struct TransposeOp : public BaseElemWiseOp
836 {
TransposeOpcvtest::TransposeOp837 TransposeOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
getRandomSizecvtest::TransposeOp838 void getRandomSize(RNG& rng, vector<int>& size)
839 {
840 cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size);
841 }
opcvtest::TransposeOp842 void op(const vector<Mat>& src, Mat& dst, const Mat&)
843 {
844 cv::transpose(src[0], dst);
845 }
refopcvtest::TransposeOp846 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
847 {
848 cvtest::transpose(src[0], dst);
849 }
getMaxErrcvtest::TransposeOp850 double getMaxErr(int)
851 {
852 return 0;
853 }
854 };
855
856 struct SetIdentityOp : public BaseElemWiseOp
857 {
SetIdentityOpcvtest::SetIdentityOp858 SetIdentityOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {}
getRandomSizecvtest::SetIdentityOp859 void getRandomSize(RNG& rng, vector<int>& size)
860 {
861 cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size);
862 }
opcvtest::SetIdentityOp863 void op(const vector<Mat>&, Mat& dst, const Mat&)
864 {
865 cv::setIdentity(dst, gamma);
866 }
refopcvtest::SetIdentityOp867 void refop(const vector<Mat>&, Mat& dst, const Mat&)
868 {
869 cvtest::setIdentity(dst, gamma);
870 }
getMaxErrcvtest::SetIdentityOp871 double getMaxErr(int)
872 {
873 return 0;
874 }
875 };
876
877 struct SetZeroOp : public BaseElemWiseOp
878 {
SetZeroOpcvtest::SetZeroOp879 SetZeroOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
opcvtest::SetZeroOp880 void op(const vector<Mat>&, Mat& dst, const Mat&)
881 {
882 dst = Scalar::all(0);
883 }
refopcvtest::SetZeroOp884 void refop(const vector<Mat>&, Mat& dst, const Mat&)
885 {
886 cvtest::set(dst, Scalar::all(0));
887 }
getMaxErrcvtest::SetZeroOp888 double getMaxErr(int)
889 {
890 return 0;
891 }
892 };
893
894
exp(const Mat & src,Mat & dst)895 static void exp(const Mat& src, Mat& dst)
896 {
897 dst.create( src.dims, &src.size[0], src.type() );
898 const Mat *arrays[]={&src, &dst, 0};
899 Mat planes[2];
900
901 NAryMatIterator it(arrays, planes);
902 size_t j, total = planes[0].total()*src.channels();
903 size_t i, nplanes = it.nplanes;
904 int depth = src.depth();
905
906 for( i = 0; i < nplanes; i++, ++it )
907 {
908 const uchar* sptr = planes[0].ptr();
909 uchar* dptr = planes[1].ptr();
910
911 if( depth == CV_32F )
912 {
913 for( j = 0; j < total; j++ )
914 ((float*)dptr)[j] = std::exp(((const float*)sptr)[j]);
915 }
916 else if( depth == CV_64F )
917 {
918 for( j = 0; j < total; j++ )
919 ((double*)dptr)[j] = std::exp(((const double*)sptr)[j]);
920 }
921 }
922 }
923
log(const Mat & src,Mat & dst)924 static void log(const Mat& src, Mat& dst)
925 {
926 dst.create( src.dims, &src.size[0], src.type() );
927 const Mat *arrays[]={&src, &dst, 0};
928 Mat planes[2];
929
930 NAryMatIterator it(arrays, planes);
931 size_t j, total = planes[0].total()*src.channels();
932 size_t i, nplanes = it.nplanes;
933 int depth = src.depth();
934
935 for( i = 0; i < nplanes; i++, ++it )
936 {
937 const uchar* sptr = planes[0].ptr();
938 uchar* dptr = planes[1].ptr();
939
940 if( depth == CV_32F )
941 {
942 for( j = 0; j < total; j++ )
943 ((float*)dptr)[j] = (float)std::log(fabs(((const float*)sptr)[j]));
944 }
945 else if( depth == CV_64F )
946 {
947 for( j = 0; j < total; j++ )
948 ((double*)dptr)[j] = std::log(fabs(((const double*)sptr)[j]));
949 }
950 }
951 }
952
953 struct ExpOp : public BaseElemWiseOp
954 {
ExpOpcvtest::ExpOp955 ExpOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
getRandomTypecvtest::ExpOp956 int getRandomType(RNG& rng)
957 {
958 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
959 }
getValueRangecvtest::ExpOp960 void getValueRange(int depth, double& minval, double& maxval)
961 {
962 maxval = depth == CV_32F ? 50 : 100;
963 minval = -maxval;
964 }
opcvtest::ExpOp965 void op(const vector<Mat>& src, Mat& dst, const Mat&)
966 {
967 cv::exp(src[0], dst);
968 }
refopcvtest::ExpOp969 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
970 {
971 cvtest::exp(src[0], dst);
972 }
getMaxErrcvtest::ExpOp973 double getMaxErr(int depth)
974 {
975 return depth == CV_32F ? 1e-5 : 1e-12;
976 }
977 };
978
979
980 struct LogOp : public BaseElemWiseOp
981 {
LogOpcvtest::LogOp982 LogOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
getRandomTypecvtest::LogOp983 int getRandomType(RNG& rng)
984 {
985 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
986 }
getValueRangecvtest::LogOp987 void getValueRange(int depth, double& minval, double& maxval)
988 {
989 maxval = depth == CV_32F ? 50 : 100;
990 minval = -maxval;
991 }
opcvtest::LogOp992 void op(const vector<Mat>& src, Mat& dst, const Mat&)
993 {
994 Mat temp;
995 cvtest::exp(src[0], temp);
996 cv::log(temp, dst);
997 }
refopcvtest::LogOp998 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
999 {
1000 Mat temp;
1001 cvtest::exp(src[0], temp);
1002 cvtest::log(temp, dst);
1003 }
getMaxErrcvtest::LogOp1004 double getMaxErr(int depth)
1005 {
1006 return depth == CV_32F ? 1e-5 : 1e-12;
1007 }
1008 };
1009
1010
cartToPolar(const Mat & mx,const Mat & my,Mat & mmag,Mat & mangle,bool angleInDegrees)1011 static void cartToPolar(const Mat& mx, const Mat& my, Mat& mmag, Mat& mangle, bool angleInDegrees)
1012 {
1013 CV_Assert( (mx.type() == CV_32F || mx.type() == CV_64F) &&
1014 mx.type() == my.type() && mx.size == my.size );
1015 mmag.create( mx.dims, &mx.size[0], mx.type() );
1016 mangle.create( mx.dims, &mx.size[0], mx.type() );
1017 const Mat *arrays[]={&mx, &my, &mmag, &mangle, 0};
1018 Mat planes[4];
1019
1020 NAryMatIterator it(arrays, planes);
1021 size_t j, total = planes[0].total();
1022 size_t i, nplanes = it.nplanes;
1023 int depth = mx.depth();
1024 double scale = angleInDegrees ? 180/CV_PI : 1;
1025
1026 for( i = 0; i < nplanes; i++, ++it )
1027 {
1028 if( depth == CV_32F )
1029 {
1030 const float* xptr = planes[0].ptr<float>();
1031 const float* yptr = planes[1].ptr<float>();
1032 float* mptr = planes[2].ptr<float>();
1033 float* aptr = planes[3].ptr<float>();
1034
1035 for( j = 0; j < total; j++ )
1036 {
1037 mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]);
1038 double a = atan2((double)yptr[j], (double)xptr[j]);
1039 if( a < 0 ) a += CV_PI*2;
1040 aptr[j] = (float)(a*scale);
1041 }
1042 }
1043 else
1044 {
1045 const double* xptr = planes[0].ptr<double>();
1046 const double* yptr = planes[1].ptr<double>();
1047 double* mptr = planes[2].ptr<double>();
1048 double* aptr = planes[3].ptr<double>();
1049
1050 for( j = 0; j < total; j++ )
1051 {
1052 mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]);
1053 double a = atan2(yptr[j], xptr[j]);
1054 if( a < 0 ) a += CV_PI*2;
1055 aptr[j] = a*scale;
1056 }
1057 }
1058 }
1059 }
1060
1061
1062 struct CartToPolarToCartOp : public BaseElemWiseOp
1063 {
CartToPolarToCartOpcvtest::CartToPolarToCartOp1064 CartToPolarToCartOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0))
1065 {
1066 context = 3;
1067 angleInDegrees = true;
1068 }
getRandomTypecvtest::CartToPolarToCartOp1069 int getRandomType(RNG& rng)
1070 {
1071 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, 1);
1072 }
opcvtest::CartToPolarToCartOp1073 void op(const vector<Mat>& src, Mat& dst, const Mat&)
1074 {
1075 Mat mag, angle, x, y;
1076
1077 cv::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
1078 cv::polarToCart(mag, angle, x, y, angleInDegrees);
1079
1080 Mat msrc[] = {mag, angle, x, y};
1081 int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
1082 dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
1083 cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
1084 }
refopcvtest::CartToPolarToCartOp1085 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1086 {
1087 Mat mag, angle;
1088 cvtest::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
1089 Mat msrc[] = {mag, angle, src[0], src[1]};
1090 int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
1091 dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
1092 cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
1093 }
generateScalarscvtest::CartToPolarToCartOp1094 void generateScalars(int, RNG& rng)
1095 {
1096 angleInDegrees = rng.uniform(0, 2) != 0;
1097 }
getMaxErrcvtest::CartToPolarToCartOp1098 double getMaxErr(int)
1099 {
1100 return 1e-3;
1101 }
1102 bool angleInDegrees;
1103 };
1104
1105
1106 struct MeanOp : public BaseElemWiseOp
1107 {
MeanOpcvtest::MeanOp1108 MeanOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1109 {
1110 context = 3;
1111 };
opcvtest::MeanOp1112 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1113 {
1114 dst.create(1, 1, CV_64FC4);
1115 dst.at<Scalar>(0,0) = cv::mean(src[0], mask);
1116 }
refopcvtest::MeanOp1117 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1118 {
1119 dst.create(1, 1, CV_64FC4);
1120 dst.at<Scalar>(0,0) = cvtest::mean(src[0], mask);
1121 }
getMaxErrcvtest::MeanOp1122 double getMaxErr(int)
1123 {
1124 return 1e-5;
1125 }
1126 };
1127
1128
1129 struct SumOp : public BaseElemWiseOp
1130 {
SumOpcvtest::SumOp1131 SumOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1132 {
1133 context = 3;
1134 };
opcvtest::SumOp1135 void op(const vector<Mat>& src, Mat& dst, const Mat&)
1136 {
1137 dst.create(1, 1, CV_64FC4);
1138 dst.at<Scalar>(0,0) = cv::sum(src[0]);
1139 }
refopcvtest::SumOp1140 void refop(const vector<Mat>& src, Mat& dst, const Mat&)
1141 {
1142 dst.create(1, 1, CV_64FC4);
1143 dst.at<Scalar>(0,0) = cvtest::mean(src[0])*(double)src[0].total();
1144 }
getMaxErrcvtest::SumOp1145 double getMaxErr(int)
1146 {
1147 return 1e-5;
1148 }
1149 };
1150
1151
1152 struct CountNonZeroOp : public BaseElemWiseOp
1153 {
CountNonZeroOpcvtest::CountNonZeroOp1154 CountNonZeroOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT+SUPPORT_MASK, 1, 1, Scalar::all(0))
1155 {}
getRandomTypecvtest::CountNonZeroOp1156 int getRandomType(RNG& rng)
1157 {
1158 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, 1);
1159 }
opcvtest::CountNonZeroOp1160 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1161 {
1162 Mat temp;
1163 src[0].copyTo(temp);
1164 if( !mask.empty() )
1165 temp.setTo(Scalar::all(0), mask);
1166 dst.create(1, 1, CV_32S);
1167 dst.at<int>(0,0) = cv::countNonZero(temp);
1168 }
refopcvtest::CountNonZeroOp1169 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1170 {
1171 Mat temp;
1172 cvtest::compare(src[0], 0, temp, CMP_NE);
1173 if( !mask.empty() )
1174 cvtest::set(temp, Scalar::all(0), mask);
1175 dst.create(1, 1, CV_32S);
1176 dst.at<int>(0,0) = saturate_cast<int>(cvtest::mean(temp)[0]/255*temp.total());
1177 }
getMaxErrcvtest::CountNonZeroOp1178 double getMaxErr(int)
1179 {
1180 return 0;
1181 }
1182 };
1183
1184
1185 struct MeanStdDevOp : public BaseElemWiseOp
1186 {
1187 Scalar sqmeanRef;
1188 int cn;
1189
MeanStdDevOpcvtest::MeanStdDevOp1190 MeanStdDevOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1191 {
1192 cn = 0;
1193 context = 7;
1194 };
opcvtest::MeanStdDevOp1195 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1196 {
1197 dst.create(1, 2, CV_64FC4);
1198 cv::meanStdDev(src[0], dst.at<Scalar>(0,0), dst.at<Scalar>(0,1), mask);
1199 }
refopcvtest::MeanStdDevOp1200 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1201 {
1202 Mat temp;
1203 cvtest::convert(src[0], temp, CV_64F);
1204 cvtest::multiply(temp, temp, temp);
1205 Scalar mean = cvtest::mean(src[0], mask);
1206 Scalar sqmean = cvtest::mean(temp, mask);
1207
1208 sqmeanRef = sqmean;
1209 cn = temp.channels();
1210
1211 for( int c = 0; c < 4; c++ )
1212 sqmean[c] = std::sqrt(std::max(sqmean[c] - mean[c]*mean[c], 0.));
1213
1214 dst.create(1, 2, CV_64FC4);
1215 dst.at<Scalar>(0,0) = mean;
1216 dst.at<Scalar>(0,1) = sqmean;
1217 }
getMaxErrcvtest::MeanStdDevOp1218 double getMaxErr(int)
1219 {
1220 CV_Assert(cn > 0);
1221 double err = sqmeanRef[0];
1222 for(int i = 1; i < cn; ++i)
1223 err = std::max(err, sqmeanRef[i]);
1224 return 3e-7 * err;
1225 }
1226 };
1227
1228
1229 struct NormOp : public BaseElemWiseOp
1230 {
NormOpcvtest::NormOp1231 NormOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1232 {
1233 context = 1;
1234 normType = 0;
1235 };
getRandomTypecvtest::NormOp1236 int getRandomType(RNG& rng)
1237 {
1238 int type = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 4);
1239 for(;;)
1240 {
1241 normType = rng.uniform(1, 8);
1242 if( normType == NORM_INF || normType == NORM_L1 ||
1243 normType == NORM_L2 || normType == NORM_L2SQR ||
1244 normType == NORM_HAMMING || normType == NORM_HAMMING2 )
1245 break;
1246 }
1247 if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
1248 {
1249 type = CV_8U;
1250 }
1251 return type;
1252 }
opcvtest::NormOp1253 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1254 {
1255 dst.create(1, 2, CV_64FC1);
1256 dst.at<double>(0,0) = cv::norm(src[0], normType, mask);
1257 dst.at<double>(0,1) = cv::norm(src[0], src[1], normType, mask);
1258 }
refopcvtest::NormOp1259 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1260 {
1261 dst.create(1, 2, CV_64FC1);
1262 dst.at<double>(0,0) = cvtest::norm(src[0], normType, mask);
1263 dst.at<double>(0,1) = cvtest::norm(src[0], src[1], normType, mask);
1264 }
generateScalarscvtest::NormOp1265 void generateScalars(int, RNG& /*rng*/)
1266 {
1267 }
getMaxErrcvtest::NormOp1268 double getMaxErr(int)
1269 {
1270 return 1e-6;
1271 }
1272 int normType;
1273 };
1274
1275
1276 struct MinMaxLocOp : public BaseElemWiseOp
1277 {
MinMaxLocOpcvtest::MinMaxLocOp1278 MinMaxLocOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
1279 {
1280 context = ARITHM_MAX_NDIMS*2 + 2;
1281 };
getRandomTypecvtest::MinMaxLocOp1282 int getRandomType(RNG& rng)
1283 {
1284 return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
1285 }
saveOutputcvtest::MinMaxLocOp1286 void saveOutput(const vector<int>& minidx, const vector<int>& maxidx,
1287 double minval, double maxval, Mat& dst)
1288 {
1289 int i, ndims = (int)minidx.size();
1290 dst.create(1, ndims*2 + 2, CV_64FC1);
1291
1292 for( i = 0; i < ndims; i++ )
1293 {
1294 dst.at<double>(0,i) = minidx[i];
1295 dst.at<double>(0,i+ndims) = maxidx[i];
1296 }
1297 dst.at<double>(0,ndims*2) = minval;
1298 dst.at<double>(0,ndims*2+1) = maxval;
1299 }
opcvtest::MinMaxLocOp1300 void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
1301 {
1302 int ndims = src[0].dims;
1303 vector<int> minidx(ndims), maxidx(ndims);
1304 double minval=0, maxval=0;
1305 cv::minMaxIdx(src[0], &minval, &maxval, &minidx[0], &maxidx[0], mask);
1306 saveOutput(minidx, maxidx, minval, maxval, dst);
1307 }
refopcvtest::MinMaxLocOp1308 void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
1309 {
1310 int ndims=src[0].dims;
1311 vector<int> minidx(ndims), maxidx(ndims);
1312 double minval=0, maxval=0;
1313 cvtest::minMaxLoc(src[0], &minval, &maxval, &minidx, &maxidx, mask);
1314 saveOutput(minidx, maxidx, minval, maxval, dst);
1315 }
getMaxErrcvtest::MinMaxLocOp1316 double getMaxErr(int)
1317 {
1318 return 0;
1319 }
1320 };
1321
1322
1323 }
1324
1325 typedef Ptr<cvtest::BaseElemWiseOp> ElemWiseOpPtr;
1326 class ElemWiseTest : public ::testing::TestWithParam<ElemWiseOpPtr> {};
1327
TEST_P(ElemWiseTest,accuracy)1328 TEST_P(ElemWiseTest, accuracy)
1329 {
1330 ElemWiseOpPtr op = GetParam();
1331
1332 int testIdx = 0;
1333 RNG rng((uint64)cvtest::ARITHM_RNG_SEED);
1334 for( testIdx = 0; testIdx < cvtest::ARITHM_NTESTS; testIdx++ )
1335 {
1336 vector<int> size;
1337 op->getRandomSize(rng, size);
1338 int type = op->getRandomType(rng);
1339 int depth = CV_MAT_DEPTH(type);
1340 bool haveMask = (op->flags & cvtest::BaseElemWiseOp::SUPPORT_MASK) != 0 && rng.uniform(0, 4) == 0;
1341
1342 double minval=0, maxval=0;
1343 op->getValueRange(depth, minval, maxval);
1344 int i, ninputs = op->ninputs;
1345 vector<Mat> src(ninputs);
1346 for( i = 0; i < ninputs; i++ )
1347 src[i] = cvtest::randomMat(rng, size, type, minval, maxval, true);
1348 Mat dst0, dst, mask;
1349 if( haveMask )
1350 mask = cvtest::randomMat(rng, size, CV_8U, 0, 2, true);
1351
1352 if( (haveMask || ninputs == 0) && !(op->flags & cvtest::BaseElemWiseOp::SCALAR_OUTPUT))
1353 {
1354 dst0 = cvtest::randomMat(rng, size, type, minval, maxval, false);
1355 dst = cvtest::randomMat(rng, size, type, minval, maxval, true);
1356 cvtest::copy(dst, dst0);
1357 }
1358 op->generateScalars(depth, rng);
1359
1360 op->refop(src, dst0, mask);
1361 op->op(src, dst, mask);
1362
1363 double maxErr = op->getMaxErr(depth);
1364 ASSERT_PRED_FORMAT2(cvtest::MatComparator(maxErr, op->context), dst0, dst) << "\nsrc[0] ~ " <<
1365 cvtest::MatInfo(!src.empty() ? src[0] : Mat()) << "\ntestCase #" << testIdx << "\n";
1366 }
1367 }
1368
1369
1370 INSTANTIATE_TEST_CASE_P(Core_Copy, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CopyOp)));
1371 INSTANTIATE_TEST_CASE_P(Core_Set, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetOp)));
1372 INSTANTIATE_TEST_CASE_P(Core_SetZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetZeroOp)));
1373 INSTANTIATE_TEST_CASE_P(Core_ConvertScale, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ConvertScaleOp)));
1374 INSTANTIATE_TEST_CASE_P(Core_ConvertScaleAbs, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ConvertScaleAbsOp)));
1375
1376 INSTANTIATE_TEST_CASE_P(Core_Add, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddOp)));
1377 INSTANTIATE_TEST_CASE_P(Core_Sub, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SubOp)));
1378 INSTANTIATE_TEST_CASE_P(Core_AddS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddSOp)));
1379 INSTANTIATE_TEST_CASE_P(Core_SubRS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SubRSOp)));
1380 INSTANTIATE_TEST_CASE_P(Core_ScaleAdd, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ScaleAddOp)));
1381 INSTANTIATE_TEST_CASE_P(Core_AddWeighted, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddWeightedOp)));
1382 INSTANTIATE_TEST_CASE_P(Core_AbsDiff, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AbsDiffOp)));
1383
1384
1385 INSTANTIATE_TEST_CASE_P(Core_AbsDiffS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AbsDiffSOp)));
1386
1387 INSTANTIATE_TEST_CASE_P(Core_And, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('&'))));
1388 INSTANTIATE_TEST_CASE_P(Core_AndS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('&'))));
1389 INSTANTIATE_TEST_CASE_P(Core_Or, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('|'))));
1390 INSTANTIATE_TEST_CASE_P(Core_OrS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('|'))));
1391 INSTANTIATE_TEST_CASE_P(Core_Xor, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('^'))));
1392 INSTANTIATE_TEST_CASE_P(Core_XorS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('^'))));
1393 INSTANTIATE_TEST_CASE_P(Core_Not, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('~'))));
1394
1395 INSTANTIATE_TEST_CASE_P(Core_Max, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MaxOp)));
1396 INSTANTIATE_TEST_CASE_P(Core_MaxS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MaxSOp)));
1397 INSTANTIATE_TEST_CASE_P(Core_Min, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinOp)));
1398 INSTANTIATE_TEST_CASE_P(Core_MinS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinSOp)));
1399
1400 INSTANTIATE_TEST_CASE_P(Core_Mul, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MulOp)));
1401 INSTANTIATE_TEST_CASE_P(Core_Div, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::DivOp)));
1402 INSTANTIATE_TEST_CASE_P(Core_Recip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::RecipOp)));
1403
1404 INSTANTIATE_TEST_CASE_P(Core_Cmp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CmpOp)));
1405 INSTANTIATE_TEST_CASE_P(Core_CmpS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CmpSOp)));
1406
1407 INSTANTIATE_TEST_CASE_P(Core_InRangeS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::InRangeSOp)));
1408 INSTANTIATE_TEST_CASE_P(Core_InRange, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::InRangeOp)));
1409
1410 INSTANTIATE_TEST_CASE_P(Core_Flip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::FlipOp)));
1411 INSTANTIATE_TEST_CASE_P(Core_Transpose, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::TransposeOp)));
1412 INSTANTIATE_TEST_CASE_P(Core_SetIdentity, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetIdentityOp)));
1413
1414 INSTANTIATE_TEST_CASE_P(Core_Exp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ExpOp)));
1415 INSTANTIATE_TEST_CASE_P(Core_Log, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogOp)));
1416
1417 INSTANTIATE_TEST_CASE_P(Core_CountNonZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CountNonZeroOp)));
1418 INSTANTIATE_TEST_CASE_P(Core_Mean, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MeanOp)));
1419 INSTANTIATE_TEST_CASE_P(Core_MeanStdDev, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MeanStdDevOp)));
1420 INSTANTIATE_TEST_CASE_P(Core_Sum, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SumOp)));
1421 INSTANTIATE_TEST_CASE_P(Core_Norm, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::NormOp)));
1422 INSTANTIATE_TEST_CASE_P(Core_MinMaxLoc, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinMaxLocOp)));
1423 INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CartToPolarToCartOp)));
1424
1425
1426 class CV_ArithmMaskTest : public cvtest::BaseTest
1427 {
1428 public:
CV_ArithmMaskTest()1429 CV_ArithmMaskTest() {}
~CV_ArithmMaskTest()1430 ~CV_ArithmMaskTest() {}
1431 protected:
run(int)1432 void run(int)
1433 {
1434 try
1435 {
1436 RNG& rng = theRNG();
1437 const int MAX_DIM=3;
1438 int sizes[MAX_DIM];
1439 for( int iter = 0; iter < 100; iter++ )
1440 {
1441 //ts->printf(cvtest::TS::LOG, ".");
1442
1443 ts->update_context(this, iter, true);
1444 int k, dims = rng.uniform(1, MAX_DIM+1), p = 1;
1445 int depth = rng.uniform(CV_8U, CV_64F+1);
1446 int cn = rng.uniform(1, 6);
1447 int type = CV_MAKETYPE(depth, cn);
1448 int op = rng.uniform(0, 5);
1449 int depth1 = op <= 1 ? CV_64F : depth;
1450 for( k = 0; k < dims; k++ )
1451 {
1452 sizes[k] = rng.uniform(1, 30);
1453 p *= sizes[k];
1454 }
1455 Mat a(dims, sizes, type), a1;
1456 Mat b(dims, sizes, type), b1;
1457 Mat mask(dims, sizes, CV_8U);
1458 Mat mask1;
1459 Mat c, d;
1460
1461 rng.fill(a, RNG::UNIFORM, 0, 100);
1462 rng.fill(b, RNG::UNIFORM, 0, 100);
1463
1464 // [-2,2) range means that the each generated random number
1465 // will be one of -2, -1, 0, 1. Saturated to [0,255], it will become
1466 // 0, 0, 0, 1 => the mask will be filled by ~25%.
1467 rng.fill(mask, RNG::UNIFORM, -2, 2);
1468
1469 a.convertTo(a1, depth1);
1470 b.convertTo(b1, depth1);
1471 // invert the mask
1472 compare(mask, 0, mask1, CMP_EQ);
1473 a1.setTo(0, mask1);
1474 b1.setTo(0, mask1);
1475
1476 if( op == 0 )
1477 {
1478 add(a, b, c, mask);
1479 add(a1, b1, d);
1480 }
1481 else if( op == 1 )
1482 {
1483 subtract(a, b, c, mask);
1484 subtract(a1, b1, d);
1485 }
1486 else if( op == 2 )
1487 {
1488 bitwise_and(a, b, c, mask);
1489 bitwise_and(a1, b1, d);
1490 }
1491 else if( op == 3 )
1492 {
1493 bitwise_or(a, b, c, mask);
1494 bitwise_or(a1, b1, d);
1495 }
1496 else if( op == 4 )
1497 {
1498 bitwise_xor(a, b, c, mask);
1499 bitwise_xor(a1, b1, d);
1500 }
1501 Mat d1;
1502 d.convertTo(d1, depth);
1503 CV_Assert( cvtest::norm(c, d1, CV_C) <= DBL_EPSILON );
1504 }
1505
1506 Mat_<uchar> tmpSrc(100,100);
1507 tmpSrc = 124;
1508 Mat_<uchar> tmpMask(100,100);
1509 tmpMask = 255;
1510 Mat_<uchar> tmpDst(100,100);
1511 tmpDst = 2;
1512 tmpSrc.copyTo(tmpDst,tmpMask);
1513 }
1514 catch(...)
1515 {
1516 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
1517 }
1518 }
1519 };
1520
TEST(Core_ArithmMask,uninitialized)1521 TEST(Core_ArithmMask, uninitialized) { CV_ArithmMaskTest test; test.safe_run(); }
1522
TEST(Multiply,FloatingPointRounding)1523 TEST(Multiply, FloatingPointRounding)
1524 {
1525 cv::Mat src(1, 1, CV_8UC1, cv::Scalar::all(110)), dst;
1526 cv::Scalar s(147.286359696927, 1, 1 ,1);
1527
1528 cv::multiply(src, s, dst, 1, CV_16U);
1529 // with CV_32F this produce result 16202
1530 ASSERT_EQ(dst.at<ushort>(0,0), 16201);
1531 }
1532
TEST(Core_Add,AddToColumnWhen3Rows)1533 TEST(Core_Add, AddToColumnWhen3Rows)
1534 {
1535 cv::Mat m1 = (cv::Mat_<double>(3, 2) << 1, 2, 3, 4, 5, 6);
1536 m1.col(1) += 10;
1537
1538 cv::Mat m2 = (cv::Mat_<double>(3, 2) << 1, 12, 3, 14, 5, 16);
1539
1540 ASSERT_EQ(0, countNonZero(m1 - m2));
1541 }
1542
TEST(Core_Add,AddToColumnWhen4Rows)1543 TEST(Core_Add, AddToColumnWhen4Rows)
1544 {
1545 cv::Mat m1 = (cv::Mat_<double>(4, 2) << 1, 2, 3, 4, 5, 6, 7, 8);
1546 m1.col(1) += 10;
1547
1548 cv::Mat m2 = (cv::Mat_<double>(4, 2) << 1, 12, 3, 14, 5, 16, 7, 18);
1549
1550 ASSERT_EQ(0, countNonZero(m1 - m2));
1551 }
1552
TEST(Core_round,CvRound)1553 TEST(Core_round, CvRound)
1554 {
1555 ASSERT_EQ(2, cvRound(2.0));
1556 ASSERT_EQ(2, cvRound(2.1));
1557 ASSERT_EQ(-2, cvRound(-2.1));
1558 ASSERT_EQ(3, cvRound(2.8));
1559 ASSERT_EQ(-3, cvRound(-2.8));
1560 ASSERT_EQ(2, cvRound(2.5));
1561 ASSERT_EQ(4, cvRound(3.5));
1562 ASSERT_EQ(-2, cvRound(-2.5));
1563 ASSERT_EQ(-4, cvRound(-3.5));
1564 }
1565
1566
1567 typedef testing::TestWithParam<Size> Mul1;
1568
TEST_P(Mul1,One)1569 TEST_P(Mul1, One)
1570 {
1571 Size size = GetParam();
1572 cv::Mat src(size, CV_32FC1, cv::Scalar::all(2)), dst,
1573 ref_dst(size, CV_32FC1, cv::Scalar::all(6));
1574
1575 cv::multiply(3, src, dst);
1576
1577 ASSERT_EQ(0, cvtest::norm(dst, ref_dst, cv::NORM_INF));
1578 }
1579
1580 INSTANTIATE_TEST_CASE_P(Arithm, Mul1, testing::Values(Size(2, 2), Size(1, 1)));
1581
1582 class SubtractOutputMatNotEmpty : public testing::TestWithParam< std::tr1::tuple<cv::Size, perf::MatType, perf::MatDepth, bool> >
1583 {
1584 public:
1585 cv::Size size;
1586 int src_type;
1587 int dst_depth;
1588 bool fixed;
1589
SetUp()1590 void SetUp()
1591 {
1592 size = std::tr1::get<0>(GetParam());
1593 src_type = std::tr1::get<1>(GetParam());
1594 dst_depth = std::tr1::get<2>(GetParam());
1595 fixed = std::tr1::get<3>(GetParam());
1596 }
1597 };
1598
TEST_P(SubtractOutputMatNotEmpty,Mat_Mat)1599 TEST_P(SubtractOutputMatNotEmpty, Mat_Mat)
1600 {
1601 cv::Mat src1(size, src_type, cv::Scalar::all(16));
1602 cv::Mat src2(size, src_type, cv::Scalar::all(16));
1603
1604 cv::Mat dst;
1605
1606 if (!fixed)
1607 {
1608 cv::subtract(src1, src2, dst, cv::noArray(), dst_depth);
1609 }
1610 else
1611 {
1612 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
1613 cv::subtract(src1, src2, fixed_dst, cv::noArray(), dst_depth);
1614 dst = fixed_dst;
1615 dst_depth = fixed_dst.depth();
1616 }
1617
1618 ASSERT_FALSE(dst.empty());
1619 ASSERT_EQ(src1.size(), dst.size());
1620 ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
1621 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1622 }
1623
TEST_P(SubtractOutputMatNotEmpty,Mat_Mat_WithMask)1624 TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_WithMask)
1625 {
1626 cv::Mat src1(size, src_type, cv::Scalar::all(16));
1627 cv::Mat src2(size, src_type, cv::Scalar::all(16));
1628 cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
1629
1630 cv::Mat dst;
1631
1632 if (!fixed)
1633 {
1634 cv::subtract(src1, src2, dst, mask, dst_depth);
1635 }
1636 else
1637 {
1638 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
1639 cv::subtract(src1, src2, fixed_dst, mask, dst_depth);
1640 dst = fixed_dst;
1641 dst_depth = fixed_dst.depth();
1642 }
1643
1644 ASSERT_FALSE(dst.empty());
1645 ASSERT_EQ(src1.size(), dst.size());
1646 ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
1647 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1648 }
1649
TEST_P(SubtractOutputMatNotEmpty,Mat_Mat_Expr)1650 TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_Expr)
1651 {
1652 cv::Mat src1(size, src_type, cv::Scalar::all(16));
1653 cv::Mat src2(size, src_type, cv::Scalar::all(16));
1654
1655 cv::Mat dst = src1 - src2;
1656
1657 ASSERT_FALSE(dst.empty());
1658 ASSERT_EQ(src1.size(), dst.size());
1659 ASSERT_EQ(src1.depth(), dst.depth());
1660 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1661 }
1662
TEST_P(SubtractOutputMatNotEmpty,Mat_Scalar)1663 TEST_P(SubtractOutputMatNotEmpty, Mat_Scalar)
1664 {
1665 cv::Mat src(size, src_type, cv::Scalar::all(16));
1666
1667 cv::Mat dst;
1668
1669 if (!fixed)
1670 {
1671 cv::subtract(src, cv::Scalar::all(16), dst, cv::noArray(), dst_depth);
1672 }
1673 else
1674 {
1675 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
1676 cv::subtract(src, cv::Scalar::all(16), fixed_dst, cv::noArray(), dst_depth);
1677 dst = fixed_dst;
1678 dst_depth = fixed_dst.depth();
1679 }
1680
1681 ASSERT_FALSE(dst.empty());
1682 ASSERT_EQ(src.size(), dst.size());
1683 ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
1684 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1685 }
1686
TEST_P(SubtractOutputMatNotEmpty,Mat_Scalar_WithMask)1687 TEST_P(SubtractOutputMatNotEmpty, Mat_Scalar_WithMask)
1688 {
1689 cv::Mat src(size, src_type, cv::Scalar::all(16));
1690 cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
1691
1692 cv::Mat dst;
1693
1694 if (!fixed)
1695 {
1696 cv::subtract(src, cv::Scalar::all(16), dst, mask, dst_depth);
1697 }
1698 else
1699 {
1700 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
1701 cv::subtract(src, cv::Scalar::all(16), fixed_dst, mask, dst_depth);
1702 dst = fixed_dst;
1703 dst_depth = fixed_dst.depth();
1704 }
1705
1706 ASSERT_FALSE(dst.empty());
1707 ASSERT_EQ(src.size(), dst.size());
1708 ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
1709 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1710 }
1711
TEST_P(SubtractOutputMatNotEmpty,Scalar_Mat)1712 TEST_P(SubtractOutputMatNotEmpty, Scalar_Mat)
1713 {
1714 cv::Mat src(size, src_type, cv::Scalar::all(16));
1715
1716 cv::Mat dst;
1717
1718 if (!fixed)
1719 {
1720 cv::subtract(cv::Scalar::all(16), src, dst, cv::noArray(), dst_depth);
1721 }
1722 else
1723 {
1724 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
1725 cv::subtract(cv::Scalar::all(16), src, fixed_dst, cv::noArray(), dst_depth);
1726 dst = fixed_dst;
1727 dst_depth = fixed_dst.depth();
1728 }
1729
1730 ASSERT_FALSE(dst.empty());
1731 ASSERT_EQ(src.size(), dst.size());
1732 ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
1733 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1734 }
1735
TEST_P(SubtractOutputMatNotEmpty,Scalar_Mat_WithMask)1736 TEST_P(SubtractOutputMatNotEmpty, Scalar_Mat_WithMask)
1737 {
1738 cv::Mat src(size, src_type, cv::Scalar::all(16));
1739 cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
1740
1741 cv::Mat dst;
1742
1743 if (!fixed)
1744 {
1745 cv::subtract(cv::Scalar::all(16), src, dst, mask, dst_depth);
1746 }
1747 else
1748 {
1749 const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
1750 cv::subtract(cv::Scalar::all(16), src, fixed_dst, mask, dst_depth);
1751 dst = fixed_dst;
1752 dst_depth = fixed_dst.depth();
1753 }
1754
1755 ASSERT_FALSE(dst.empty());
1756 ASSERT_EQ(src.size(), dst.size());
1757 ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
1758 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1759 }
1760
TEST_P(SubtractOutputMatNotEmpty,Mat_Mat_3d)1761 TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_3d)
1762 {
1763 int dims[] = {5, size.height, size.width};
1764
1765 cv::Mat src1(3, dims, src_type, cv::Scalar::all(16));
1766 cv::Mat src2(3, dims, src_type, cv::Scalar::all(16));
1767
1768 cv::Mat dst;
1769
1770 if (!fixed)
1771 {
1772 cv::subtract(src1, src2, dst, cv::noArray(), dst_depth);
1773 }
1774 else
1775 {
1776 const cv::Mat fixed_dst(3, dims, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
1777 cv::subtract(src1, src2, fixed_dst, cv::noArray(), dst_depth);
1778 dst = fixed_dst;
1779 dst_depth = fixed_dst.depth();
1780 }
1781
1782 ASSERT_FALSE(dst.empty());
1783 ASSERT_EQ(src1.dims, dst.dims);
1784 ASSERT_EQ(src1.size, dst.size);
1785 ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
1786 ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
1787 }
1788
1789 INSTANTIATE_TEST_CASE_P(Arithm, SubtractOutputMatNotEmpty, testing::Combine(
1790 testing::Values(cv::Size(16, 16), cv::Size(13, 13), cv::Size(16, 13), cv::Size(13, 16)),
1791 testing::Values(perf::MatType(CV_8UC1), CV_8UC3, CV_8UC4, CV_16SC1, CV_16SC3),
1792 testing::Values(-1, CV_16S, CV_32S, CV_32F),
1793 testing::Bool()));
1794
1795
TEST(Core_FindNonZero,singular)1796 TEST(Core_FindNonZero, singular)
1797 {
1798 Mat img(10, 10, CV_8U, Scalar::all(0));
1799 vector<Point> pts, pts2(10);
1800 findNonZero(img, pts);
1801 findNonZero(img, pts2);
1802 ASSERT_TRUE(pts.empty() && pts2.empty());
1803 }
1804
TEST(Core_BoolVector,support)1805 TEST(Core_BoolVector, support)
1806 {
1807 std::vector<bool> test;
1808 int i, n = 205;
1809 int nz = 0;
1810 test.resize(n);
1811 for( i = 0; i < n; i++ )
1812 {
1813 test[i] = theRNG().uniform(0, 2) != 0;
1814 nz += (int)test[i];
1815 }
1816 ASSERT_EQ( nz, countNonZero(test) );
1817 ASSERT_FLOAT_EQ((float)nz/n, (float)(mean(test)[0]));
1818 }
1819