1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html
4
5 #include "precomp.hpp"
6 #include "opencv2/core/mat.hpp"
7
8 namespace cv {
9
10 /*************************************************************************************************\
11 Input/Output Array
12 \*************************************************************************************************/
13
getMat_(int i) const14 Mat _InputArray::getMat_(int i) const
15 {
16 _InputArray::KindFlag k = kind();
17 AccessFlag accessFlags = flags & ACCESS_MASK;
18
19 if( k == MAT )
20 {
21 const Mat* m = (const Mat*)obj;
22 if( i < 0 )
23 return *m;
24 return m->row(i);
25 }
26
27 if( k == UMAT )
28 {
29 const UMat* m = (const UMat*)obj;
30 if( i < 0 )
31 return m->getMat(accessFlags);
32 return m->getMat(accessFlags).row(i);
33 }
34
35 if (k == MATX)
36 {
37 CV_Assert( i < 0 );
38 return Mat(sz, flags, obj);
39 }
40
41 if( k == STD_VECTOR )
42 {
43 CV_Assert( i < 0 );
44 int t = CV_MAT_TYPE(flags);
45 const std::vector<uchar>& v = *(const std::vector<uchar>*)obj;
46
47 return !v.empty() ? Mat(size(), t, (void*)&v[0]) : Mat();
48 }
49
50 if( k == STD_BOOL_VECTOR )
51 {
52 CV_Assert( i < 0 );
53 int t = CV_8U;
54 const std::vector<bool>& v = *(const std::vector<bool>*)obj;
55 int j, n = (int)v.size();
56 if( n == 0 )
57 return Mat();
58 Mat m(1, n, t);
59 uchar* dst = m.data;
60 for( j = 0; j < n; j++ )
61 dst[j] = (uchar)v[j];
62 return m;
63 }
64
65 if( k == NONE )
66 return Mat();
67
68 if( k == STD_VECTOR_VECTOR )
69 {
70 int t = type(i);
71 const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
72 CV_Assert( 0 <= i && i < (int)vv.size() );
73 const std::vector<uchar>& v = vv[i];
74
75 return !v.empty() ? Mat(size(i), t, (void*)&v[0]) : Mat();
76 }
77
78 if( k == STD_VECTOR_MAT )
79 {
80 const std::vector<Mat>& v = *(const std::vector<Mat>*)obj;
81 CV_Assert( 0 <= i && i < (int)v.size() );
82
83 return v[i];
84 }
85
86 if( k == STD_ARRAY_MAT )
87 {
88 const Mat* v = (const Mat*)obj;
89 CV_Assert( 0 <= i && i < sz.height );
90
91 return v[i];
92 }
93
94 if( k == STD_VECTOR_UMAT )
95 {
96 const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
97 CV_Assert( 0 <= i && i < (int)v.size() );
98
99 return v[i].getMat(accessFlags);
100 }
101
102 if( k == OPENGL_BUFFER )
103 {
104 CV_Assert( i < 0 );
105 CV_Error(cv::Error::StsNotImplemented, "You should explicitly call mapHost/unmapHost methods for ogl::Buffer object");
106 }
107
108 if( k == CUDA_GPU_MAT )
109 {
110 CV_Assert( i < 0 );
111 CV_Error(cv::Error::StsNotImplemented, "You should explicitly call download method for cuda::GpuMat object");
112 }
113
114 if( k == CUDA_HOST_MEM )
115 {
116 CV_Assert( i < 0 );
117
118 const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj;
119
120 return cuda_mem->createMatHeader();
121 }
122
123 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
124 }
125
getUMat(int i) const126 UMat _InputArray::getUMat(int i) const
127 {
128 _InputArray::KindFlag k = kind();
129 AccessFlag accessFlags = flags & ACCESS_MASK;
130
131 if( k == UMAT )
132 {
133 const UMat* m = (const UMat*)obj;
134 if( i < 0 )
135 return *m;
136 return m->row(i);
137 }
138
139 if( k == STD_VECTOR_UMAT )
140 {
141 const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
142 CV_Assert( 0 <= i && i < (int)v.size() );
143
144 return v[i];
145 }
146
147 if( k == MAT )
148 {
149 const Mat* m = (const Mat*)obj;
150 if( i < 0 )
151 return m->getUMat(accessFlags);
152 return m->row(i).getUMat(accessFlags);
153 }
154
155 return getMat(i).getUMat(accessFlags);
156 }
157
getMatVector(std::vector<Mat> & mv) const158 void _InputArray::getMatVector(std::vector<Mat>& mv) const
159 {
160 _InputArray::KindFlag k = kind();
161 AccessFlag accessFlags = flags & ACCESS_MASK;
162
163 if( k == MAT )
164 {
165 const Mat& m = *(const Mat*)obj;
166 int n = (int)m.size[0];
167 mv.resize(n);
168
169 for( int i = 0; i < n; i++ )
170 mv[i] = m.dims == 2 ? Mat(1, m.cols, m.type(), (void*)m.ptr(i)) :
171 Mat(m.dims-1, &m.size[1], m.type(), (void*)m.ptr(i), &m.step[1]);
172 return;
173 }
174
175 if (k == MATX)
176 {
177 size_t n = sz.height, esz = CV_ELEM_SIZE(flags);
178 mv.resize(n);
179
180 for( size_t i = 0; i < n; i++ )
181 mv[i] = Mat(1, sz.width, CV_MAT_TYPE(flags), (uchar*)obj + esz*sz.width*i);
182 return;
183 }
184
185 if( k == STD_VECTOR )
186 {
187 const std::vector<uchar>& v = *(const std::vector<uchar>*)obj;
188
189 size_t n = size().width, esz = CV_ELEM_SIZE(flags);
190 int t = CV_MAT_DEPTH(flags), cn = CV_MAT_CN(flags);
191 mv.resize(n);
192
193 for( size_t i = 0; i < n; i++ )
194 mv[i] = Mat(1, cn, t, (void*)(&v[0] + esz*i));
195 return;
196 }
197
198 if( k == NONE )
199 {
200 mv.clear();
201 return;
202 }
203
204 if( k == STD_VECTOR_VECTOR )
205 {
206 const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
207 int n = (int)vv.size();
208 int t = CV_MAT_TYPE(flags);
209 mv.resize(n);
210
211 for( int i = 0; i < n; i++ )
212 {
213 const std::vector<uchar>& v = vv[i];
214 mv[i] = Mat(size(i), t, (void*)&v[0]);
215 }
216 return;
217 }
218
219 if( k == STD_VECTOR_MAT )
220 {
221 const std::vector<Mat>& v = *(const std::vector<Mat>*)obj;
222 size_t n = v.size();
223 mv.resize(n);
224
225 for( size_t i = 0; i < n; i++ )
226 mv[i] = v[i];
227 return;
228 }
229
230 if( k == STD_ARRAY_MAT )
231 {
232 const Mat* v = (const Mat*)obj;
233 size_t n = sz.height;
234 mv.resize(n);
235
236 for( size_t i = 0; i < n; i++ )
237 mv[i] = v[i];
238 return;
239 }
240
241 if( k == STD_VECTOR_UMAT )
242 {
243 const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
244 size_t n = v.size();
245 mv.resize(n);
246
247 for( size_t i = 0; i < n; i++ )
248 mv[i] = v[i].getMat(accessFlags);
249 return;
250 }
251
252 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
253 }
254
getUMatVector(std::vector<UMat> & umv) const255 void _InputArray::getUMatVector(std::vector<UMat>& umv) const
256 {
257 _InputArray::KindFlag k = kind();
258 AccessFlag accessFlags = flags & ACCESS_MASK;
259
260 if( k == NONE )
261 {
262 umv.clear();
263 return;
264 }
265
266 if( k == STD_VECTOR_MAT )
267 {
268 const std::vector<Mat>& v = *(const std::vector<Mat>*)obj;
269 size_t n = v.size();
270 umv.resize(n);
271
272 for( size_t i = 0; i < n; i++ )
273 umv[i] = v[i].getUMat(accessFlags);
274 return;
275 }
276
277 if( k == STD_ARRAY_MAT )
278 {
279 const Mat* v = (const Mat*)obj;
280 size_t n = sz.height;
281 umv.resize(n);
282
283 for( size_t i = 0; i < n; i++ )
284 umv[i] = v[i].getUMat(accessFlags);
285 return;
286 }
287
288 if( k == STD_VECTOR_UMAT )
289 {
290 const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
291 size_t n = v.size();
292 umv.resize(n);
293
294 for( size_t i = 0; i < n; i++ )
295 umv[i] = v[i];
296 return;
297 }
298
299 if( k == UMAT )
300 {
301 UMat& v = *(UMat*)obj;
302 umv.resize(1);
303 umv[0] = v;
304 return;
305 }
306 if( k == MAT )
307 {
308 Mat& v = *(Mat*)obj;
309 umv.resize(1);
310 umv[0] = v.getUMat(accessFlags);
311 return;
312 }
313
314 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
315 }
316
getGpuMat() const317 cuda::GpuMat _InputArray::getGpuMat() const
318 {
319 #ifdef HAVE_CUDA
320 _InputArray::KindFlag k = kind();
321
322 if (k == CUDA_GPU_MAT)
323 {
324 const cuda::GpuMat* d_mat = (const cuda::GpuMat*)obj;
325 return *d_mat;
326 }
327
328 if (k == CUDA_HOST_MEM)
329 {
330 const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj;
331 return cuda_mem->createGpuMatHeader();
332 }
333
334 if (k == OPENGL_BUFFER)
335 {
336 CV_Error(cv::Error::StsNotImplemented, "You should explicitly call mapDevice/unmapDevice methods for ogl::Buffer object");
337 }
338
339 if (k == NONE)
340 return cuda::GpuMat();
341
342 CV_Error(cv::Error::StsNotImplemented, "getGpuMat is available only for cuda::GpuMat and cuda::HostMem");
343 #else
344 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
345 #endif
346 }
getGpuMatVector(std::vector<cuda::GpuMat> & gpumv) const347 void _InputArray::getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const
348 {
349 #ifdef HAVE_CUDA
350 _InputArray::KindFlag k = kind();
351 if (k == STD_VECTOR_CUDA_GPU_MAT)
352 {
353 gpumv = *(std::vector<cuda::GpuMat>*)obj;
354 }
355 #else
356 CV_UNUSED(gpumv);
357 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
358 #endif
359 }
getOGlBuffer() const360 ogl::Buffer _InputArray::getOGlBuffer() const
361 {
362 _InputArray::KindFlag k = kind();
363
364 CV_Assert(k == OPENGL_BUFFER);
365
366 const ogl::Buffer* gl_buf = (const ogl::Buffer*)obj;
367 return *gl_buf;
368 }
369
kind() const370 _InputArray::KindFlag _InputArray::kind() const
371 {
372 KindFlag k = flags & KIND_MASK;
373 #if CV_VERSION_MAJOR < 5
374 CV_DbgAssert(k != EXPR);
375 CV_DbgAssert(k != STD_ARRAY);
376 #endif
377 return k;
378 }
379
rows(int i) const380 int _InputArray::rows(int i) const
381 {
382 return size(i).height;
383 }
384
cols(int i) const385 int _InputArray::cols(int i) const
386 {
387 return size(i).width;
388 }
389
size(int i) const390 Size _InputArray::size(int i) const
391 {
392 _InputArray::KindFlag k = kind();
393
394 if( k == MAT )
395 {
396 CV_Assert( i < 0 );
397 return ((const Mat*)obj)->size();
398 }
399
400 if( k == UMAT )
401 {
402 CV_Assert( i < 0 );
403 return ((const UMat*)obj)->size();
404 }
405
406 if (k == MATX)
407 {
408 CV_Assert( i < 0 );
409 return sz;
410 }
411
412 if( k == STD_VECTOR )
413 {
414 CV_Assert( i < 0 );
415 const std::vector<uchar>& v = *(const std::vector<uchar>*)obj;
416 const std::vector<int>& iv = *(const std::vector<int>*)obj;
417 size_t szb = v.size(), szi = iv.size();
418 return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1);
419 }
420
421 if( k == STD_BOOL_VECTOR )
422 {
423 CV_Assert( i < 0 );
424 const std::vector<bool>& v = *(const std::vector<bool>*)obj;
425 return Size((int)v.size(), 1);
426 }
427
428 if( k == NONE )
429 return Size();
430
431 if( k == STD_VECTOR_VECTOR )
432 {
433 const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
434 if( i < 0 )
435 return vv.empty() ? Size() : Size((int)vv.size(), 1);
436 CV_Assert( i < (int)vv.size() );
437 const std::vector<std::vector<int> >& ivv = *(const std::vector<std::vector<int> >*)obj;
438
439 size_t szb = vv[i].size(), szi = ivv[i].size();
440 return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1);
441 }
442
443 if( k == STD_VECTOR_MAT )
444 {
445 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
446 if( i < 0 )
447 return vv.empty() ? Size() : Size((int)vv.size(), 1);
448 CV_Assert( i < (int)vv.size() );
449
450 return vv[i].size();
451 }
452
453 if( k == STD_ARRAY_MAT )
454 {
455 const Mat* vv = (const Mat*)obj;
456 if( i < 0 )
457 return sz.height==0 ? Size() : Size(sz.height, 1);
458 CV_Assert( i < sz.height );
459
460 return vv[i].size();
461 }
462
463 if (k == STD_VECTOR_CUDA_GPU_MAT)
464 {
465 #ifdef HAVE_CUDA
466 const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
467 if (i < 0)
468 return vv.empty() ? Size() : Size((int)vv.size(), 1);
469 CV_Assert(i < (int)vv.size());
470 return vv[i].size();
471 #else
472 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
473 #endif
474 }
475
476 if( k == STD_VECTOR_UMAT )
477 {
478 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
479 if( i < 0 )
480 return vv.empty() ? Size() : Size((int)vv.size(), 1);
481 CV_Assert( i < (int)vv.size() );
482
483 return vv[i].size();
484 }
485
486 if( k == OPENGL_BUFFER )
487 {
488 CV_Assert( i < 0 );
489 const ogl::Buffer* buf = (const ogl::Buffer*)obj;
490 return buf->size();
491 }
492
493 if( k == CUDA_GPU_MAT )
494 {
495 CV_Assert( i < 0 );
496 const cuda::GpuMat* d_mat = (const cuda::GpuMat*)obj;
497 return d_mat->size();
498 }
499
500 if( k == CUDA_HOST_MEM )
501 {
502 CV_Assert( i < 0 );
503 const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj;
504 return cuda_mem->size();
505 }
506
507 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
508 }
509
sizend(int * arrsz,int i) const510 int _InputArray::sizend(int* arrsz, int i) const
511 {
512 int j, d = 0;
513 _InputArray::KindFlag k = kind();
514
515 if( k == NONE )
516 ;
517 else if( k == MAT )
518 {
519 CV_Assert( i < 0 );
520 const Mat& m = *(const Mat*)obj;
521 d = m.dims;
522 if(arrsz)
523 for(j = 0; j < d; j++)
524 arrsz[j] = m.size.p[j];
525 }
526 else if( k == UMAT )
527 {
528 CV_Assert( i < 0 );
529 const UMat& m = *(const UMat*)obj;
530 d = m.dims;
531 if(arrsz)
532 for(j = 0; j < d; j++)
533 arrsz[j] = m.size.p[j];
534 }
535 else if( k == STD_VECTOR_MAT && i >= 0 )
536 {
537 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
538 CV_Assert( i < (int)vv.size() );
539 const Mat& m = vv[i];
540 d = m.dims;
541 if(arrsz)
542 for(j = 0; j < d; j++)
543 arrsz[j] = m.size.p[j];
544 }
545 else if( k == STD_ARRAY_MAT && i >= 0 )
546 {
547 const Mat* vv = (const Mat*)obj;
548 CV_Assert( i < sz.height );
549 const Mat& m = vv[i];
550 d = m.dims;
551 if(arrsz)
552 for(j = 0; j < d; j++)
553 arrsz[j] = m.size.p[j];
554 }
555 else if( k == STD_VECTOR_UMAT && i >= 0 )
556 {
557 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
558 CV_Assert( i < (int)vv.size() );
559 const UMat& m = vv[i];
560 d = m.dims;
561 if(arrsz)
562 for(j = 0; j < d; j++)
563 arrsz[j] = m.size.p[j];
564 }
565 else
566 {
567 CV_CheckLE(dims(i), 2, "Not supported");
568 Size sz2d = size(i);
569 d = 2;
570 if(arrsz)
571 {
572 arrsz[0] = sz2d.height;
573 arrsz[1] = sz2d.width;
574 }
575 }
576
577 return d;
578 }
579
sameSize(const _InputArray & arr) const580 bool _InputArray::sameSize(const _InputArray& arr) const
581 {
582 _InputArray::KindFlag k1 = kind(), k2 = arr.kind();
583 Size sz1;
584
585 if( k1 == MAT )
586 {
587 const Mat* m = ((const Mat*)obj);
588 if( k2 == MAT )
589 return m->size == ((const Mat*)arr.obj)->size;
590 if( k2 == UMAT )
591 return m->size == ((const UMat*)arr.obj)->size;
592 if( m->dims > 2 )
593 return false;
594 sz1 = m->size();
595 }
596 else if( k1 == UMAT )
597 {
598 const UMat* m = ((const UMat*)obj);
599 if( k2 == MAT )
600 return m->size == ((const Mat*)arr.obj)->size;
601 if( k2 == UMAT )
602 return m->size == ((const UMat*)arr.obj)->size;
603 if( m->dims > 2 )
604 return false;
605 sz1 = m->size();
606 }
607 else
608 sz1 = size();
609 if( arr.dims() > 2 )
610 return false;
611 return sz1 == arr.size();
612 }
613
dims(int i) const614 int _InputArray::dims(int i) const
615 {
616 _InputArray::KindFlag k = kind();
617
618 if( k == MAT )
619 {
620 CV_Assert( i < 0 );
621 return ((const Mat*)obj)->dims;
622 }
623
624 if( k == UMAT )
625 {
626 CV_Assert( i < 0 );
627 return ((const UMat*)obj)->dims;
628 }
629
630 if (k == MATX)
631 {
632 CV_Assert( i < 0 );
633 return 2;
634 }
635
636 if( k == STD_VECTOR || k == STD_BOOL_VECTOR )
637 {
638 CV_Assert( i < 0 );
639 return 2;
640 }
641
642 if( k == NONE )
643 return 0;
644
645 if( k == STD_VECTOR_VECTOR )
646 {
647 const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
648 if( i < 0 )
649 return 1;
650 CV_Assert( i < (int)vv.size() );
651 return 2;
652 }
653
654 if( k == STD_VECTOR_MAT )
655 {
656 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
657 if( i < 0 )
658 return 1;
659 CV_Assert( i < (int)vv.size() );
660
661 return vv[i].dims;
662 }
663
664 if( k == STD_ARRAY_MAT )
665 {
666 const Mat* vv = (const Mat*)obj;
667 if( i < 0 )
668 return 1;
669 CV_Assert( i < sz.height );
670
671 return vv[i].dims;
672 }
673
674 if( k == STD_VECTOR_UMAT )
675 {
676 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
677 if( i < 0 )
678 return 1;
679 CV_Assert( i < (int)vv.size() );
680
681 return vv[i].dims;
682 }
683
684 if( k == OPENGL_BUFFER )
685 {
686 CV_Assert( i < 0 );
687 return 2;
688 }
689
690 if( k == CUDA_GPU_MAT )
691 {
692 CV_Assert( i < 0 );
693 return 2;
694 }
695
696 if( k == CUDA_HOST_MEM )
697 {
698 CV_Assert( i < 0 );
699 return 2;
700 }
701
702 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
703 }
704
total(int i) const705 size_t _InputArray::total(int i) const
706 {
707 _InputArray::KindFlag k = kind();
708
709 if( k == MAT )
710 {
711 CV_Assert( i < 0 );
712 return ((const Mat*)obj)->total();
713 }
714
715 if( k == UMAT )
716 {
717 CV_Assert( i < 0 );
718 return ((const UMat*)obj)->total();
719 }
720
721 if( k == STD_VECTOR_MAT )
722 {
723 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
724 if( i < 0 )
725 return vv.size();
726
727 CV_Assert( i < (int)vv.size() );
728 return vv[i].total();
729 }
730
731 if( k == STD_ARRAY_MAT )
732 {
733 const Mat* vv = (const Mat*)obj;
734 if( i < 0 )
735 return sz.height;
736
737 CV_Assert( i < sz.height );
738 return vv[i].total();
739 }
740
741 if( k == STD_VECTOR_UMAT )
742 {
743 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
744 if( i < 0 )
745 return vv.size();
746
747 CV_Assert( i < (int)vv.size() );
748 return vv[i].total();
749 }
750
751 return size(i).area();
752 }
753
type(int i) const754 int _InputArray::type(int i) const
755 {
756 _InputArray::KindFlag k = kind();
757
758 if( k == MAT )
759 return ((const Mat*)obj)->type();
760
761 if( k == UMAT )
762 return ((const UMat*)obj)->type();
763
764 if( k == MATX || k == STD_VECTOR || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
765 return CV_MAT_TYPE(flags);
766
767 if( k == NONE )
768 return -1;
769
770 if( k == STD_VECTOR_UMAT )
771 {
772 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
773 if( vv.empty() )
774 {
775 CV_Assert((flags & FIXED_TYPE) != 0);
776 return CV_MAT_TYPE(flags);
777 }
778 CV_Assert( i < (int)vv.size() );
779 return vv[i >= 0 ? i : 0].type();
780 }
781
782 if( k == STD_VECTOR_MAT )
783 {
784 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
785 if( vv.empty() )
786 {
787 CV_Assert((flags & FIXED_TYPE) != 0);
788 return CV_MAT_TYPE(flags);
789 }
790 CV_Assert( i < (int)vv.size() );
791 return vv[i >= 0 ? i : 0].type();
792 }
793
794 if( k == STD_ARRAY_MAT )
795 {
796 const Mat* vv = (const Mat*)obj;
797 if( sz.height == 0 )
798 {
799 CV_Assert((flags & FIXED_TYPE) != 0);
800 return CV_MAT_TYPE(flags);
801 }
802 CV_Assert( i < sz.height );
803 return vv[i >= 0 ? i : 0].type();
804 }
805
806 if (k == STD_VECTOR_CUDA_GPU_MAT)
807 {
808 #ifdef HAVE_CUDA
809 const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
810 if (vv.empty())
811 {
812 CV_Assert((flags & FIXED_TYPE) != 0);
813 return CV_MAT_TYPE(flags);
814 }
815 CV_Assert(i < (int)vv.size());
816 return vv[i >= 0 ? i : 0].type();
817 #else
818 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
819 #endif
820 }
821
822 if( k == OPENGL_BUFFER )
823 return ((const ogl::Buffer*)obj)->type();
824
825 if( k == CUDA_GPU_MAT )
826 return ((const cuda::GpuMat*)obj)->type();
827
828 if( k == CUDA_HOST_MEM )
829 return ((const cuda::HostMem*)obj)->type();
830
831 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
832 }
833
depth(int i) const834 int _InputArray::depth(int i) const
835 {
836 return CV_MAT_DEPTH(type(i));
837 }
838
channels(int i) const839 int _InputArray::channels(int i) const
840 {
841 return CV_MAT_CN(type(i));
842 }
843
empty() const844 bool _InputArray::empty() const
845 {
846 _InputArray::KindFlag k = kind();
847
848 if( k == MAT )
849 return ((const Mat*)obj)->empty();
850
851 if( k == UMAT )
852 return ((const UMat*)obj)->empty();
853
854 if (k == MATX)
855 return false;
856
857 if( k == STD_VECTOR )
858 {
859 const std::vector<uchar>& v = *(const std::vector<uchar>*)obj;
860 return v.empty();
861 }
862
863 if( k == STD_BOOL_VECTOR )
864 {
865 const std::vector<bool>& v = *(const std::vector<bool>*)obj;
866 return v.empty();
867 }
868
869 if( k == NONE )
870 return true;
871
872 if( k == STD_VECTOR_VECTOR )
873 {
874 const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
875 return vv.empty();
876 }
877
878 if( k == STD_VECTOR_MAT )
879 {
880 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
881 return vv.empty();
882 }
883
884 if( k == STD_ARRAY_MAT )
885 {
886 return sz.height == 0;
887 }
888
889 if( k == STD_VECTOR_UMAT )
890 {
891 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
892 return vv.empty();
893 }
894
895 if( k == OPENGL_BUFFER )
896 return ((const ogl::Buffer*)obj)->empty();
897
898 if( k == CUDA_GPU_MAT )
899 return ((const cuda::GpuMat*)obj)->empty();
900
901 if (k == STD_VECTOR_CUDA_GPU_MAT)
902 {
903 const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
904 return vv.empty();
905 }
906
907 if( k == CUDA_HOST_MEM )
908 return ((const cuda::HostMem*)obj)->empty();
909
910 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
911 }
912
isContinuous(int i) const913 bool _InputArray::isContinuous(int i) const
914 {
915 _InputArray::KindFlag k = kind();
916
917 if( k == MAT )
918 return i < 0 ? ((const Mat*)obj)->isContinuous() : true;
919
920 if( k == UMAT )
921 return i < 0 ? ((const UMat*)obj)->isContinuous() : true;
922
923 if( k == MATX || k == STD_VECTOR ||
924 k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
925 return true;
926
927 if( k == STD_VECTOR_MAT )
928 {
929 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
930 CV_Assert(i >= 0 && (size_t)i < vv.size());
931 return vv[i].isContinuous();
932 }
933
934 if( k == STD_ARRAY_MAT )
935 {
936 const Mat* vv = (const Mat*)obj;
937 CV_Assert(i >= 0 && i < sz.height);
938 return vv[i].isContinuous();
939 }
940
941 if( k == STD_VECTOR_UMAT )
942 {
943 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
944 CV_Assert(i >= 0 && (size_t)i < vv.size());
945 return vv[i].isContinuous();
946 }
947
948 if( k == CUDA_GPU_MAT )
949 return i < 0 ? ((const cuda::GpuMat*)obj)->isContinuous() : true;
950
951 CV_Error(CV_StsNotImplemented, "Unknown/unsupported array type");
952 }
953
isSubmatrix(int i) const954 bool _InputArray::isSubmatrix(int i) const
955 {
956 _InputArray::KindFlag k = kind();
957
958 if( k == MAT )
959 return i < 0 ? ((const Mat*)obj)->isSubmatrix() : false;
960
961 if( k == UMAT )
962 return i < 0 ? ((const UMat*)obj)->isSubmatrix() : false;
963
964 if( k == MATX || k == STD_VECTOR ||
965 k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
966 return false;
967
968 if( k == STD_VECTOR_MAT )
969 {
970 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
971 CV_Assert(i >= 0 && (size_t)i < vv.size());
972 return vv[i].isSubmatrix();
973 }
974
975 if( k == STD_ARRAY_MAT )
976 {
977 const Mat* vv = (const Mat*)obj;
978 CV_Assert(i >= 0 && i < sz.height);
979 return vv[i].isSubmatrix();
980 }
981
982 if( k == STD_VECTOR_UMAT )
983 {
984 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
985 CV_Assert(i >= 0 && (size_t)i < vv.size());
986 return vv[i].isSubmatrix();
987 }
988
989 CV_Error(CV_StsNotImplemented, "");
990 }
991
offset(int i) const992 size_t _InputArray::offset(int i) const
993 {
994 _InputArray::KindFlag k = kind();
995
996 if( k == MAT )
997 {
998 CV_Assert( i < 0 );
999 const Mat * const m = ((const Mat*)obj);
1000 return (size_t)(m->ptr() - m->datastart);
1001 }
1002
1003 if( k == UMAT )
1004 {
1005 CV_Assert( i < 0 );
1006 return ((const UMat*)obj)->offset;
1007 }
1008
1009 if( k == MATX || k == STD_VECTOR ||
1010 k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
1011 return 0;
1012
1013 if( k == STD_VECTOR_MAT )
1014 {
1015 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
1016 CV_Assert( i >= 0 && i < (int)vv.size() );
1017
1018 return (size_t)(vv[i].ptr() - vv[i].datastart);
1019 }
1020
1021 if( k == STD_ARRAY_MAT )
1022 {
1023 const Mat* vv = (const Mat*)obj;
1024 CV_Assert( i >= 0 && i < sz.height );
1025 return (size_t)(vv[i].ptr() - vv[i].datastart);
1026 }
1027
1028 if( k == STD_VECTOR_UMAT )
1029 {
1030 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
1031 CV_Assert(i >= 0 && (size_t)i < vv.size());
1032 return vv[i].offset;
1033 }
1034
1035 if( k == CUDA_GPU_MAT )
1036 {
1037 CV_Assert( i < 0 );
1038 const cuda::GpuMat * const m = ((const cuda::GpuMat*)obj);
1039 return (size_t)(m->data - m->datastart);
1040 }
1041
1042 if (k == STD_VECTOR_CUDA_GPU_MAT)
1043 {
1044 const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
1045 CV_Assert(i >= 0 && (size_t)i < vv.size());
1046 return (size_t)(vv[i].data - vv[i].datastart);
1047 }
1048
1049 CV_Error(Error::StsNotImplemented, "");
1050 }
1051
step(int i) const1052 size_t _InputArray::step(int i) const
1053 {
1054 _InputArray::KindFlag k = kind();
1055
1056 if( k == MAT )
1057 {
1058 CV_Assert( i < 0 );
1059 return ((const Mat*)obj)->step;
1060 }
1061
1062 if( k == UMAT )
1063 {
1064 CV_Assert( i < 0 );
1065 return ((const UMat*)obj)->step;
1066 }
1067
1068 if( k == MATX || k == STD_VECTOR ||
1069 k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
1070 return 0;
1071
1072 if( k == STD_VECTOR_MAT )
1073 {
1074 const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
1075 CV_Assert( i >= 0 && i < (int)vv.size() );
1076 return vv[i].step;
1077 }
1078
1079 if( k == STD_ARRAY_MAT )
1080 {
1081 const Mat* vv = (const Mat*)obj;
1082 CV_Assert( i >= 0 && i < sz.height );
1083 return vv[i].step;
1084 }
1085
1086 if( k == STD_VECTOR_UMAT )
1087 {
1088 const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
1089 CV_Assert(i >= 0 && (size_t)i < vv.size());
1090 return vv[i].step;
1091 }
1092
1093 if( k == CUDA_GPU_MAT )
1094 {
1095 CV_Assert( i < 0 );
1096 return ((const cuda::GpuMat*)obj)->step;
1097 }
1098 if (k == STD_VECTOR_CUDA_GPU_MAT)
1099 {
1100 const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
1101 CV_Assert(i >= 0 && (size_t)i < vv.size());
1102 return vv[i].step;
1103 }
1104
1105 CV_Error(Error::StsNotImplemented, "");
1106 }
1107
copyTo(const _OutputArray & arr) const1108 void _InputArray::copyTo(const _OutputArray& arr) const
1109 {
1110 _InputArray::KindFlag k = kind();
1111
1112 if( k == NONE )
1113 arr.release();
1114 else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_BOOL_VECTOR )
1115 {
1116 Mat m = getMat();
1117 m.copyTo(arr);
1118 }
1119 else if( k == UMAT )
1120 ((UMat*)obj)->copyTo(arr);
1121 #ifdef HAVE_CUDA
1122 else if (k == CUDA_GPU_MAT)
1123 ((cuda::GpuMat*)obj)->copyTo(arr);
1124 #endif
1125 else
1126 CV_Error(Error::StsNotImplemented, "");
1127 }
1128
copyTo(const _OutputArray & arr,const _InputArray & mask) const1129 void _InputArray::copyTo(const _OutputArray& arr, const _InputArray & mask) const
1130 {
1131 _InputArray::KindFlag k = kind();
1132
1133 if( k == NONE )
1134 arr.release();
1135 else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_BOOL_VECTOR )
1136 {
1137 Mat m = getMat();
1138 m.copyTo(arr, mask);
1139 }
1140 else if( k == UMAT )
1141 ((UMat*)obj)->copyTo(arr, mask);
1142 #ifdef HAVE_CUDA
1143 else if (k == CUDA_GPU_MAT)
1144 ((cuda::GpuMat*)obj)->copyTo(arr, mask);
1145 #endif
1146 else
1147 CV_Error(Error::StsNotImplemented, "");
1148 }
1149
fixedSize() const1150 bool _OutputArray::fixedSize() const
1151 {
1152 return (flags & FIXED_SIZE) == FIXED_SIZE;
1153 }
1154
fixedType() const1155 bool _OutputArray::fixedType() const
1156 {
1157 return (flags & FIXED_TYPE) == FIXED_TYPE;
1158 }
1159
create(Size _sz,int mtype,int i,bool allowTransposed,_OutputArray::DepthMask fixedDepthMask) const1160 void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
1161 {
1162 _InputArray::KindFlag k = kind();
1163 if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1164 {
1165 CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == _sz);
1166 CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype);
1167 ((Mat*)obj)->create(_sz, mtype);
1168 return;
1169 }
1170 if( k == UMAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1171 {
1172 CV_Assert(!fixedSize() || ((UMat*)obj)->size.operator()() == _sz);
1173 CV_Assert(!fixedType() || ((UMat*)obj)->type() == mtype);
1174 ((UMat*)obj)->create(_sz, mtype);
1175 return;
1176 }
1177 if( k == CUDA_GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1178 {
1179 CV_Assert(!fixedSize() || ((cuda::GpuMat*)obj)->size() == _sz);
1180 CV_Assert(!fixedType() || ((cuda::GpuMat*)obj)->type() == mtype);
1181 #ifdef HAVE_CUDA
1182 ((cuda::GpuMat*)obj)->create(_sz, mtype);
1183 return;
1184 #else
1185 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1186 #endif
1187 }
1188 if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1189 {
1190 CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == _sz);
1191 CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype);
1192 #ifdef HAVE_OPENGL
1193 ((ogl::Buffer*)obj)->create(_sz, mtype);
1194 return;
1195 #else
1196 CV_Error(Error::StsNotImplemented, "OpenGL support is not enabled in this OpenCV build (missing HAVE_OPENGL)");
1197 #endif
1198 }
1199 if( k == CUDA_HOST_MEM && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1200 {
1201 CV_Assert(!fixedSize() || ((cuda::HostMem*)obj)->size() == _sz);
1202 CV_Assert(!fixedType() || ((cuda::HostMem*)obj)->type() == mtype);
1203 #ifdef HAVE_CUDA
1204 ((cuda::HostMem*)obj)->create(_sz, mtype);
1205 return;
1206 #else
1207 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1208 #endif
1209 }
1210 int sizes[] = {_sz.height, _sz.width};
1211 create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
1212 }
1213
create(int _rows,int _cols,int mtype,int i,bool allowTransposed,_OutputArray::DepthMask fixedDepthMask) const1214 void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
1215 {
1216 _InputArray::KindFlag k = kind();
1217 if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1218 {
1219 CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows));
1220 CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype);
1221 ((Mat*)obj)->create(_rows, _cols, mtype);
1222 return;
1223 }
1224 if( k == UMAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1225 {
1226 CV_Assert(!fixedSize() || ((UMat*)obj)->size.operator()() == Size(_cols, _rows));
1227 CV_Assert(!fixedType() || ((UMat*)obj)->type() == mtype);
1228 ((UMat*)obj)->create(_rows, _cols, mtype);
1229 return;
1230 }
1231 if( k == CUDA_GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1232 {
1233 CV_Assert(!fixedSize() || ((cuda::GpuMat*)obj)->size() == Size(_cols, _rows));
1234 CV_Assert(!fixedType() || ((cuda::GpuMat*)obj)->type() == mtype);
1235 #ifdef HAVE_CUDA
1236 ((cuda::GpuMat*)obj)->create(_rows, _cols, mtype);
1237 return;
1238 #else
1239 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1240 #endif
1241 }
1242 if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1243 {
1244 CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == Size(_cols, _rows));
1245 CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype);
1246 #ifdef HAVE_OPENGL
1247 ((ogl::Buffer*)obj)->create(_rows, _cols, mtype);
1248 return;
1249 #else
1250 CV_Error(Error::StsNotImplemented, "OpenGL support is not enabled in this OpenCV build (missing HAVE_OPENGL)");
1251 #endif
1252 }
1253 if( k == CUDA_HOST_MEM && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1254 {
1255 CV_Assert(!fixedSize() || ((cuda::HostMem*)obj)->size() == Size(_cols, _rows));
1256 CV_Assert(!fixedType() || ((cuda::HostMem*)obj)->type() == mtype);
1257 #ifdef HAVE_CUDA
1258 ((cuda::HostMem*)obj)->create(_rows, _cols, mtype);
1259 return;
1260 #else
1261 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1262 #endif
1263 }
1264 int sizes[] = {_rows, _cols};
1265 create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
1266 }
1267
create(int d,const int * sizes,int mtype,int i,bool allowTransposed,_OutputArray::DepthMask fixedDepthMask) const1268 void _OutputArray::create(int d, const int* sizes, int mtype, int i,
1269 bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
1270 {
1271 int sizebuf[2];
1272 if(d == 1)
1273 {
1274 d = 2;
1275 sizebuf[0] = sizes[0];
1276 sizebuf[1] = 1;
1277 sizes = sizebuf;
1278 }
1279 _InputArray::KindFlag k = kind();
1280 mtype = CV_MAT_TYPE(mtype);
1281
1282 if( k == MAT )
1283 {
1284 CV_Assert( i < 0 );
1285 Mat& m = *(Mat*)obj;
1286 CV_Assert(!(m.empty() && fixedType() && fixedSize()) && "Can't reallocate empty Mat with locked layout (probably due to misused 'const' modifier)");
1287 if (allowTransposed && !m.empty() &&
1288 d == 2 && m.dims == 2 &&
1289 m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] &&
1290 m.isContinuous())
1291 {
1292 return;
1293 }
1294
1295 if(fixedType())
1296 {
1297 if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1298 mtype = m.type();
1299 else
1300 CV_CheckTypeEQ(m.type(), CV_MAT_TYPE(mtype), "Can't reallocate Mat with locked type (probably due to misused 'const' modifier)");
1301 }
1302 if(fixedSize())
1303 {
1304 CV_CheckEQ(m.dims, d, "Can't reallocate Mat with locked size (probably due to misused 'const' modifier)");
1305 for(int j = 0; j < d; ++j)
1306 CV_CheckEQ(m.size[j], sizes[j], "Can't reallocate Mat with locked size (probably due to misused 'const' modifier)");
1307 }
1308 m.create(d, sizes, mtype);
1309 return;
1310 }
1311
1312 if( k == UMAT )
1313 {
1314 CV_Assert( i < 0 );
1315 UMat& m = *(UMat*)obj;
1316 CV_Assert(!(m.empty() && fixedType() && fixedSize()) && "Can't reallocate empty UMat with locked layout (probably due to misused 'const' modifier)");
1317 if (allowTransposed && !m.empty() &&
1318 d == 2 && m.dims == 2 &&
1319 m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] &&
1320 m.isContinuous())
1321 {
1322 return;
1323 }
1324
1325 if(fixedType())
1326 {
1327 if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1328 mtype = m.type();
1329 else
1330 CV_CheckTypeEQ(m.type(), CV_MAT_TYPE(mtype), "Can't reallocate UMat with locked type (probably due to misused 'const' modifier)");
1331 }
1332 if(fixedSize())
1333 {
1334 CV_CheckEQ(m.dims, d, "Can't reallocate UMat with locked size (probably due to misused 'const' modifier)");
1335 for(int j = 0; j < d; ++j)
1336 CV_CheckEQ(m.size[j], sizes[j], "Can't reallocate UMat with locked size (probably due to misused 'const' modifier)");
1337 }
1338 m.create(d, sizes, mtype);
1339 return;
1340 }
1341
1342 if( k == MATX )
1343 {
1344 CV_Assert( i < 0 );
1345 int type0 = CV_MAT_TYPE(flags);
1346 CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == 1 && ((1 << type0) & fixedDepthMask) != 0) );
1347 CV_CheckLE(d, 2, "");
1348 Size requested_size(d == 2 ? sizes[1] : 1, d >= 1 ? sizes[0] : 1);
1349 if (sz.width == 1 || sz.height == 1)
1350 {
1351 // NB: 1D arrays assume allowTransposed=true (see #4159)
1352 int total_1d = std::max(sz.width, sz.height);
1353 CV_Check(requested_size, std::max(requested_size.width, requested_size.height) == total_1d, "");
1354 }
1355 else
1356 {
1357 if (!allowTransposed)
1358 {
1359 CV_CheckEQ(requested_size, sz, "");
1360 }
1361 else
1362 {
1363 CV_Check(requested_size,
1364 (requested_size == sz || (requested_size.height == sz.width && requested_size.width == sz.height)),
1365 "");
1366 }
1367 }
1368 return;
1369 }
1370
1371 if( k == STD_VECTOR || k == STD_VECTOR_VECTOR )
1372 {
1373 CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
1374 size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0;
1375 std::vector<uchar>* v = (std::vector<uchar>*)obj;
1376
1377 if( k == STD_VECTOR_VECTOR )
1378 {
1379 std::vector<std::vector<uchar> >& vv = *(std::vector<std::vector<uchar> >*)obj;
1380 if( i < 0 )
1381 {
1382 CV_Assert(!fixedSize() || len == vv.size());
1383 vv.resize(len);
1384 return;
1385 }
1386 CV_Assert( i < (int)vv.size() );
1387 v = &vv[i];
1388 }
1389 else
1390 CV_Assert( i < 0 );
1391
1392 int type0 = CV_MAT_TYPE(flags);
1393 CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) );
1394
1395 int esz = CV_ELEM_SIZE(type0);
1396 CV_Assert(!fixedSize() || len == ((std::vector<uchar>*)v)->size() / esz);
1397 switch( esz )
1398 {
1399 case 1:
1400 ((std::vector<uchar>*)v)->resize(len);
1401 break;
1402 case 2:
1403 ((std::vector<Vec2b>*)v)->resize(len);
1404 break;
1405 case 3:
1406 ((std::vector<Vec3b>*)v)->resize(len);
1407 break;
1408 case 4:
1409 ((std::vector<int>*)v)->resize(len);
1410 break;
1411 case 6:
1412 ((std::vector<Vec3s>*)v)->resize(len);
1413 break;
1414 case 8:
1415 ((std::vector<Vec2i>*)v)->resize(len);
1416 break;
1417 case 12:
1418 ((std::vector<Vec3i>*)v)->resize(len);
1419 break;
1420 case 16:
1421 ((std::vector<Vec4i>*)v)->resize(len);
1422 break;
1423 case 20:
1424 ((std::vector<Vec<int, 5> >*)v)->resize(len);
1425 break;
1426 case 24:
1427 ((std::vector<Vec6i>*)v)->resize(len);
1428 break;
1429 case 28:
1430 ((std::vector<Vec<int, 7> >*)v)->resize(len);
1431 break;
1432 case 32:
1433 ((std::vector<Vec8i>*)v)->resize(len);
1434 break;
1435 case 36:
1436 ((std::vector<Vec<int, 9> >*)v)->resize(len);
1437 break;
1438 case 40:
1439 ((std::vector<Vec<int, 10> >*)v)->resize(len);
1440 break;
1441 case 44:
1442 ((std::vector<Vec<int, 11> >*)v)->resize(len);
1443 break;
1444 case 48:
1445 ((std::vector<Vec<int, 12> >*)v)->resize(len);
1446 break;
1447 case 52:
1448 ((std::vector<Vec<int, 13> >*)v)->resize(len);
1449 break;
1450 case 56:
1451 ((std::vector<Vec<int, 14> >*)v)->resize(len);
1452 break;
1453 case 60:
1454 ((std::vector<Vec<int, 15> >*)v)->resize(len);
1455 break;
1456 case 64:
1457 ((std::vector<Vec<int, 16> >*)v)->resize(len);
1458 break;
1459 case 128:
1460 ((std::vector<Vec<int, 32> >*)v)->resize(len);
1461 break;
1462 case 256:
1463 ((std::vector<Vec<int, 64> >*)v)->resize(len);
1464 break;
1465 case 512:
1466 ((std::vector<Vec<int, 128> >*)v)->resize(len);
1467 break;
1468 default:
1469 CV_Error_(CV_StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz));
1470 }
1471 return;
1472 }
1473
1474 if( k == NONE )
1475 {
1476 CV_Error(CV_StsNullPtr, "create() called for the missing output array" );
1477 }
1478
1479 if( k == STD_VECTOR_MAT )
1480 {
1481 std::vector<Mat>& v = *(std::vector<Mat>*)obj;
1482
1483 if( i < 0 )
1484 {
1485 CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
1486 size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = v.size();
1487
1488 CV_Assert(!fixedSize() || len == len0);
1489 v.resize(len);
1490 if( fixedType() )
1491 {
1492 int _type = CV_MAT_TYPE(flags);
1493 for( size_t j = len0; j < len; j++ )
1494 {
1495 if( v[j].type() == _type )
1496 continue;
1497 CV_Assert( v[j].empty() );
1498 v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type;
1499 }
1500 }
1501 return;
1502 }
1503
1504 CV_Assert( i < (int)v.size() );
1505 Mat& m = v[i];
1506
1507 if( allowTransposed )
1508 {
1509 if( !m.isContinuous() )
1510 {
1511 CV_Assert(!fixedType() && !fixedSize());
1512 m.release();
1513 }
1514
1515 if( d == 2 && m.dims == 2 && m.data &&
1516 m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
1517 return;
1518 }
1519
1520 if(fixedType())
1521 {
1522 if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1523 mtype = m.type();
1524 else
1525 CV_Assert(CV_MAT_TYPE(mtype) == m.type());
1526 }
1527 if(fixedSize())
1528 {
1529 CV_Assert(m.dims == d);
1530 for(int j = 0; j < d; ++j)
1531 CV_Assert(m.size[j] == sizes[j]);
1532 }
1533
1534 m.create(d, sizes, mtype);
1535 return;
1536 }
1537
1538 if( k == STD_ARRAY_MAT )
1539 {
1540 Mat* v = (Mat*)obj;
1541
1542 if( i < 0 )
1543 {
1544 CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
1545 size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = sz.height;
1546
1547 CV_Assert(len == len0);
1548 if( fixedType() )
1549 {
1550 int _type = CV_MAT_TYPE(flags);
1551 for( size_t j = len0; j < len; j++ )
1552 {
1553 if( v[j].type() == _type )
1554 continue;
1555 CV_Assert( v[j].empty() );
1556 v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type;
1557 }
1558 }
1559 return;
1560 }
1561
1562 CV_Assert( i < sz.height );
1563 Mat& m = v[i];
1564
1565 if( allowTransposed )
1566 {
1567 if( !m.isContinuous() )
1568 {
1569 CV_Assert(!fixedType() && !fixedSize());
1570 m.release();
1571 }
1572
1573 if( d == 2 && m.dims == 2 && m.data &&
1574 m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
1575 return;
1576 }
1577
1578 if(fixedType())
1579 {
1580 if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1581 mtype = m.type();
1582 else
1583 CV_Assert(CV_MAT_TYPE(mtype) == m.type());
1584 }
1585
1586 if(fixedSize())
1587 {
1588 CV_Assert(m.dims == d);
1589 for(int j = 0; j < d; ++j)
1590 CV_Assert(m.size[j] == sizes[j]);
1591 }
1592
1593 m.create(d, sizes, mtype);
1594 return;
1595 }
1596
1597 if( k == STD_VECTOR_UMAT )
1598 {
1599 std::vector<UMat>& v = *(std::vector<UMat>*)obj;
1600
1601 if( i < 0 )
1602 {
1603 CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
1604 size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = v.size();
1605
1606 CV_Assert(!fixedSize() || len == len0);
1607 v.resize(len);
1608 if( fixedType() )
1609 {
1610 int _type = CV_MAT_TYPE(flags);
1611 for( size_t j = len0; j < len; j++ )
1612 {
1613 if( v[j].type() == _type )
1614 continue;
1615 CV_Assert( v[j].empty() );
1616 v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type;
1617 }
1618 }
1619 return;
1620 }
1621
1622 CV_Assert( i < (int)v.size() );
1623 UMat& m = v[i];
1624
1625 if( allowTransposed )
1626 {
1627 if( !m.isContinuous() )
1628 {
1629 CV_Assert(!fixedType() && !fixedSize());
1630 m.release();
1631 }
1632
1633 if( d == 2 && m.dims == 2 && m.u &&
1634 m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
1635 return;
1636 }
1637
1638 if(fixedType())
1639 {
1640 if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1641 mtype = m.type();
1642 else
1643 CV_Assert(CV_MAT_TYPE(mtype) == m.type());
1644 }
1645 if(fixedSize())
1646 {
1647 CV_Assert(m.dims == d);
1648 for(int j = 0; j < d; ++j)
1649 CV_Assert(m.size[j] == sizes[j]);
1650 }
1651
1652 m.create(d, sizes, mtype);
1653 return;
1654 }
1655
1656 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
1657 }
1658
createSameSize(const _InputArray & arr,int mtype) const1659 void _OutputArray::createSameSize(const _InputArray& arr, int mtype) const
1660 {
1661 int arrsz[CV_MAX_DIM], d = arr.sizend(arrsz);
1662 create(d, arrsz, mtype);
1663 }
1664
release() const1665 void _OutputArray::release() const
1666 {
1667 CV_Assert(!fixedSize());
1668
1669 _InputArray::KindFlag k = kind();
1670
1671 if( k == MAT )
1672 {
1673 ((Mat*)obj)->release();
1674 return;
1675 }
1676
1677 if( k == UMAT )
1678 {
1679 ((UMat*)obj)->release();
1680 return;
1681 }
1682
1683 if( k == CUDA_GPU_MAT )
1684 {
1685 #ifdef HAVE_CUDA
1686 ((cuda::GpuMat*)obj)->release();
1687 return;
1688 #else
1689 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1690 #endif
1691 }
1692
1693 if( k == CUDA_HOST_MEM )
1694 {
1695 #ifdef HAVE_CUDA
1696 ((cuda::HostMem*)obj)->release();
1697 return;
1698 #else
1699 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1700 #endif
1701 }
1702
1703 if( k == OPENGL_BUFFER )
1704 {
1705 #ifdef HAVE_OPENGL
1706 ((ogl::Buffer*)obj)->release();
1707 return;
1708 #else
1709 CV_Error(Error::StsNotImplemented, "OpenGL support is not enabled in this OpenCV build (missing HAVE_OPENGL)");
1710 #endif
1711 }
1712
1713 if( k == NONE )
1714 return;
1715
1716 if( k == STD_VECTOR )
1717 {
1718 create(Size(), CV_MAT_TYPE(flags));
1719 return;
1720 }
1721
1722 if( k == STD_VECTOR_VECTOR )
1723 {
1724 ((std::vector<std::vector<uchar> >*)obj)->clear();
1725 return;
1726 }
1727
1728 if( k == STD_VECTOR_MAT )
1729 {
1730 ((std::vector<Mat>*)obj)->clear();
1731 return;
1732 }
1733
1734 if( k == STD_VECTOR_UMAT )
1735 {
1736 ((std::vector<UMat>*)obj)->clear();
1737 return;
1738 }
1739 if (k == STD_VECTOR_CUDA_GPU_MAT)
1740 {
1741 #ifdef HAVE_CUDA
1742 ((std::vector<cuda::GpuMat>*)obj)->clear();
1743 return;
1744 #else
1745 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1746 #endif
1747 }
1748 CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
1749 }
1750
clear() const1751 void _OutputArray::clear() const
1752 {
1753 _InputArray::KindFlag k = kind();
1754
1755 if( k == MAT )
1756 {
1757 CV_Assert(!fixedSize());
1758 ((Mat*)obj)->resize(0);
1759 return;
1760 }
1761
1762 release();
1763 }
1764
needed() const1765 bool _OutputArray::needed() const
1766 {
1767 return kind() != NONE;
1768 }
1769
getMatRef(int i) const1770 Mat& _OutputArray::getMatRef(int i) const
1771 {
1772 _InputArray::KindFlag k = kind();
1773 if( i < 0 )
1774 {
1775 CV_Assert( k == MAT );
1776 return *(Mat*)obj;
1777 }
1778
1779 CV_Assert( k == STD_VECTOR_MAT || k == STD_ARRAY_MAT );
1780
1781 if( k == STD_VECTOR_MAT )
1782 {
1783 std::vector<Mat>& v = *(std::vector<Mat>*)obj;
1784 CV_Assert( i < (int)v.size() );
1785 return v[i];
1786 }
1787 else
1788 {
1789 Mat* v = (Mat*)obj;
1790 CV_Assert( 0 <= i && i < sz.height );
1791 return v[i];
1792 }
1793 }
1794
getUMatRef(int i) const1795 UMat& _OutputArray::getUMatRef(int i) const
1796 {
1797 _InputArray::KindFlag k = kind();
1798 if( i < 0 )
1799 {
1800 CV_Assert( k == UMAT );
1801 return *(UMat*)obj;
1802 }
1803 else
1804 {
1805 CV_Assert( k == STD_VECTOR_UMAT );
1806 std::vector<UMat>& v = *(std::vector<UMat>*)obj;
1807 CV_Assert( i < (int)v.size() );
1808 return v[i];
1809 }
1810 }
1811
getGpuMatRef() const1812 cuda::GpuMat& _OutputArray::getGpuMatRef() const
1813 {
1814 _InputArray::KindFlag k = kind();
1815 CV_Assert( k == CUDA_GPU_MAT );
1816 return *(cuda::GpuMat*)obj;
1817 }
getGpuMatVecRef() const1818 std::vector<cuda::GpuMat>& _OutputArray::getGpuMatVecRef() const
1819 {
1820 _InputArray::KindFlag k = kind();
1821 CV_Assert(k == STD_VECTOR_CUDA_GPU_MAT);
1822 return *(std::vector<cuda::GpuMat>*)obj;
1823 }
1824
getOGlBufferRef() const1825 ogl::Buffer& _OutputArray::getOGlBufferRef() const
1826 {
1827 _InputArray::KindFlag k = kind();
1828 CV_Assert( k == OPENGL_BUFFER );
1829 return *(ogl::Buffer*)obj;
1830 }
1831
getHostMemRef() const1832 cuda::HostMem& _OutputArray::getHostMemRef() const
1833 {
1834 _InputArray::KindFlag k = kind();
1835 CV_Assert( k == CUDA_HOST_MEM );
1836 return *(cuda::HostMem*)obj;
1837 }
1838
setTo(const _InputArray & arr,const _InputArray & mask) const1839 void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
1840 {
1841 _InputArray::KindFlag k = kind();
1842
1843 if( k == NONE )
1844 ;
1845 else if (k == MAT || k == MATX || k == STD_VECTOR)
1846 {
1847 Mat m = getMat();
1848 m.setTo(arr, mask);
1849 }
1850 else if( k == UMAT )
1851 ((UMat*)obj)->setTo(arr, mask);
1852 else if( k == CUDA_GPU_MAT )
1853 {
1854 #ifdef HAVE_CUDA
1855 Mat value = arr.getMat();
1856 CV_Assert( checkScalar(value, type(), arr.kind(), _InputArray::CUDA_GPU_MAT) );
1857 ((cuda::GpuMat*)obj)->setTo(Scalar(Vec<double, 4>(value.ptr<double>())), mask);
1858 #else
1859 CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1860 #endif
1861 }
1862 else
1863 CV_Error(Error::StsNotImplemented, "");
1864 }
1865
1866
assign(const UMat & u) const1867 void _OutputArray::assign(const UMat& u) const
1868 {
1869 _InputArray::KindFlag k = kind();
1870 if (k == UMAT)
1871 {
1872 *(UMat*)obj = u;
1873 }
1874 else if (k == MAT)
1875 {
1876 u.copyTo(*(Mat*)obj); // TODO check u.getMat()
1877 }
1878 else if (k == MATX)
1879 {
1880 u.copyTo(getMat()); // TODO check u.getMat()
1881 }
1882 else
1883 {
1884 CV_Error(Error::StsNotImplemented, "");
1885 }
1886 }
1887
1888
assign(const Mat & m) const1889 void _OutputArray::assign(const Mat& m) const
1890 {
1891 _InputArray::KindFlag k = kind();
1892 if (k == UMAT)
1893 {
1894 m.copyTo(*(UMat*)obj); // TODO check m.getUMat()
1895 }
1896 else if (k == MAT)
1897 {
1898 *(Mat*)obj = m;
1899 }
1900 else if (k == MATX)
1901 {
1902 m.copyTo(getMat());
1903 }
1904 else
1905 {
1906 CV_Error(Error::StsNotImplemented, "");
1907 }
1908 }
1909
1910
move(UMat & u) const1911 void _OutputArray::move(UMat& u) const
1912 {
1913 if (fixedSize())
1914 {
1915 // TODO Performance warning
1916 assign(u);
1917 return;
1918 }
1919 int k = kind();
1920 if (k == UMAT)
1921 {
1922 #ifdef CV_CXX11
1923 *(UMat*)obj = std::move(u);
1924 #else
1925 *(UMat*)obj = u;
1926 u.release();
1927 #endif
1928 }
1929 else if (k == MAT)
1930 {
1931 u.copyTo(*(Mat*)obj); // TODO check u.getMat()
1932 u.release();
1933 }
1934 else if (k == MATX)
1935 {
1936 u.copyTo(getMat()); // TODO check u.getMat()
1937 u.release();
1938 }
1939 else
1940 {
1941 CV_Error(Error::StsNotImplemented, "");
1942 }
1943 }
1944
1945
move(Mat & m) const1946 void _OutputArray::move(Mat& m) const
1947 {
1948 if (fixedSize())
1949 {
1950 // TODO Performance warning
1951 assign(m);
1952 return;
1953 }
1954 int k = kind();
1955 if (k == UMAT)
1956 {
1957 m.copyTo(*(UMat*)obj); // TODO check m.getUMat()
1958 m.release();
1959 }
1960 else if (k == MAT)
1961 {
1962 #ifdef CV_CXX11
1963 *(Mat*)obj = std::move(m);
1964 #else
1965 *(Mat*)obj = m;
1966 m.release();
1967 #endif
1968 }
1969 else if (k == MATX)
1970 {
1971 m.copyTo(getMat());
1972 m.release();
1973 }
1974 else
1975 {
1976 CV_Error(Error::StsNotImplemented, "");
1977 }
1978 }
1979
1980
assign(const std::vector<UMat> & v) const1981 void _OutputArray::assign(const std::vector<UMat>& v) const
1982 {
1983 _InputArray::KindFlag k = kind();
1984 if (k == STD_VECTOR_UMAT)
1985 {
1986 std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
1987 CV_Assert(this_v.size() == v.size());
1988
1989 for (size_t i = 0; i < v.size(); i++)
1990 {
1991 const UMat& m = v[i];
1992 UMat& this_m = this_v[i];
1993 if (this_m.u != NULL && this_m.u == m.u)
1994 continue; // same object (see dnn::Layer::forward_fallback)
1995 m.copyTo(this_m);
1996 }
1997 }
1998 else if (k == STD_VECTOR_MAT)
1999 {
2000 std::vector<Mat>& this_v = *(std::vector<Mat>*)obj;
2001 CV_Assert(this_v.size() == v.size());
2002
2003 for (size_t i = 0; i < v.size(); i++)
2004 {
2005 const UMat& m = v[i];
2006 Mat& this_m = this_v[i];
2007 if (this_m.u != NULL && this_m.u == m.u)
2008 continue; // same object (see dnn::Layer::forward_fallback)
2009 m.copyTo(this_m);
2010 }
2011 }
2012 else
2013 {
2014 CV_Error(Error::StsNotImplemented, "");
2015 }
2016 }
2017
2018
assign(const std::vector<Mat> & v) const2019 void _OutputArray::assign(const std::vector<Mat>& v) const
2020 {
2021 _InputArray::KindFlag k = kind();
2022 if (k == STD_VECTOR_UMAT)
2023 {
2024 std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
2025 CV_Assert(this_v.size() == v.size());
2026
2027 for (size_t i = 0; i < v.size(); i++)
2028 {
2029 const Mat& m = v[i];
2030 UMat& this_m = this_v[i];
2031 if (this_m.u != NULL && this_m.u == m.u)
2032 continue; // same object (see dnn::Layer::forward_fallback)
2033 m.copyTo(this_m);
2034 }
2035 }
2036 else if (k == STD_VECTOR_MAT)
2037 {
2038 std::vector<Mat>& this_v = *(std::vector<Mat>*)obj;
2039 CV_Assert(this_v.size() == v.size());
2040
2041 for (size_t i = 0; i < v.size(); i++)
2042 {
2043 const Mat& m = v[i];
2044 Mat& this_m = this_v[i];
2045 if (this_m.u != NULL && this_m.u == m.u)
2046 continue; // same object (see dnn::Layer::forward_fallback)
2047 m.copyTo(this_m);
2048 }
2049 }
2050 else
2051 {
2052 CV_Error(Error::StsNotImplemented, "");
2053 }
2054 }
2055
2056
2057 static _InputOutputArray _none;
noArray()2058 InputOutputArray noArray() { return _none; }
2059
2060 } // cv::
2061