1/*M///////////////////////////////////////////////////////////////////////////////////////
2//
3// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4//
5// By downloading, copying, installing or using the software you agree to this license.
6// If you do not agree to this license, do not download, install,
7// copy or use the software.
8//
9//
10// License Agreement
11// For Open Source Computer Vision Library
12//
13// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
16// Third party copyrights are property of their respective owners.
17//
18// Redistribution and use in source and binary forms, with or without modification,
19// are permitted provided that the following conditions are met:
20//
21// * Redistribution's of source code must retain the above copyright notice,
22// this list of conditions and the following disclaimer.
23//
24// * Redistribution's in binary form must reproduce the above copyright notice,
25// this list of conditions and the following disclaimer in the documentation
26// and/or other materials provided with the distribution.
27//
28// * The name of the copyright holders may not be used to endorse or promote products
29// derived from this software without specific prior written permission.
30//
31// This software is provided by the copyright holders and contributors "as is" and
32// any express or implied warranties, including, but not limited to, the implied
33// warranties of merchantability and fitness for a particular purpose are disclaimed.
34// In no event shall the Intel Corporation or contributors be liable for any direct,
35// indirect, incidental, special, exemplary, or consequential damages
36// (including, but not limited to, procurement of substitute goods or services;
37// loss of use, data, or profits; or business interruption) however caused
38// and on any theory of liability, whether in contract, strict liability,
39// or tort (including negligence or otherwise) arising in any way out of
40// the use of this software, even if advised of the possibility of such damage.
41//
42//M*/
43
44#ifndef OPENCV_CORE_TYPES_HPP
45#define OPENCV_CORE_TYPES_HPP
46
47#ifndef __cplusplus
48# error types.hpp header must be compiled as C++
49#endif
50
51#include <climits>
52#include <cfloat>
53#include <vector>
54#include <limits>
55
56#include "opencv2/core/cvdef.h"
57#include "opencv2/core/cvstd.hpp"
58#include "opencv2/core/matx.hpp"
59
60#ifdef _MSC_VER
61#pragma warning(push)
62#pragma warning(disable: 4459) // declaration of '...' hides global declaration
63#endif
64
65namespace cv
66{
67
68//! @addtogroup core_basic
69//! @{
70
71//////////////////////////////// Complex //////////////////////////////
72
73/** @brief A complex number class.
74
75 The template class is similar and compatible with std::complex, however it provides slightly
76 more convenient access to the real and imaginary parts using through the simple field access, as opposite
77 to std::complex::real() and std::complex::imag().
78*/
79template<typename _Tp> class Complex
80{
81public:
82
83 //! default constructor
84 Complex();
85 Complex( _Tp _re, _Tp _im = 0 );
86
87 //! conversion to another data type
88 template<typename T2> operator Complex<T2>() const;
89 //! conjugation
90 Complex conj() const;
91
92 _Tp re, im; ///< the real and the imaginary parts
93};
94
95typedef Complex<float> Complexf;
96typedef Complex<double> Complexd;
97
98template<typename _Tp> class DataType< Complex<_Tp> >
99{
100public:
101 typedef Complex<_Tp> value_type;
102 typedef value_type work_type;
103 typedef _Tp channel_type;
104
105 enum { generic_type = 0,
106 channels = 2,
107 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8)
108#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
109 ,depth = DataType<channel_type>::depth
110 ,type = CV_MAKETYPE(depth, channels)
111#endif
112 };
113
114 typedef Vec<channel_type, channels> vec_type;
115};
116
117namespace traits {
118template<typename _Tp>
119struct Depth< Complex<_Tp> > { enum { value = Depth<_Tp>::value }; };
120template<typename _Tp>
121struct Type< Complex<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; };
122} // namespace
123
124
125//////////////////////////////// Point_ ////////////////////////////////
126
127/** @brief Template class for 2D points specified by its coordinates `x` and `y`.
128
129An instance of the class is interchangeable with C structures, CvPoint and CvPoint2D32f . There is
130also a cast operator to convert point coordinates to the specified type. The conversion from
131floating-point coordinates to integer coordinates is done by rounding. Commonly, the conversion
132uses this operation for each of the coordinates. Besides the class members listed in the
133declaration above, the following operations on points are implemented:
134@code
135 pt1 = pt2 + pt3;
136 pt1 = pt2 - pt3;
137 pt1 = pt2 * a;
138 pt1 = a * pt2;
139 pt1 = pt2 / a;
140 pt1 += pt2;
141 pt1 -= pt2;
142 pt1 *= a;
143 pt1 /= a;
144 double value = norm(pt); // L2 norm
145 pt1 == pt2;
146 pt1 != pt2;
147@endcode
148For your convenience, the following type aliases are defined:
149@code
150 typedef Point_<int> Point2i;
151 typedef Point2i Point;
152 typedef Point_<float> Point2f;
153 typedef Point_<double> Point2d;
154@endcode
155Example:
156@code
157 Point2f a(0.3f, 0.f), b(0.f, 0.4f);
158 Point pt = (a + b)*10.f;
159 cout << pt.x << ", " << pt.y << endl;
160@endcode
161*/
162template<typename _Tp> class Point_
163{
164public:
165 typedef _Tp value_type;
166
167 //! default constructor
168 Point_();
169 Point_(_Tp _x, _Tp _y);
170#if (defined(__GNUC__) && __GNUC__ < 5) && !defined(__clang__) // GCC 4.x bug. Details: https://github.com/opencv/opencv/pull/20837
171 Point_(const Point_& pt);
172 Point_(Point_&& pt) CV_NOEXCEPT = default;
173#elif OPENCV_ABI_COMPATIBILITY < 500
174 Point_(const Point_& pt) = default;
175 Point_(Point_&& pt) CV_NOEXCEPT = default;
176#endif
177 Point_(const Size_<_Tp>& sz);
178 Point_(const Vec<_Tp, 2>& v);
179
180#if (defined(__GNUC__) && __GNUC__ < 5) && !defined(__clang__) // GCC 4.x bug. Details: https://github.com/opencv/opencv/pull/20837
181 Point_& operator = (const Point_& pt);
182 Point_& operator = (Point_&& pt) CV_NOEXCEPT = default;
183#elif OPENCV_ABI_COMPATIBILITY < 500
184 Point_& operator = (const Point_& pt) = default;
185 Point_& operator = (Point_&& pt) CV_NOEXCEPT = default;
186#endif
187 //! conversion to another data type
188 template<typename _Tp2> operator Point_<_Tp2>() const;
189
190 //! conversion to the old-style C structures
191 operator Vec<_Tp, 2>() const;
192
193 //! dot product
194 _Tp dot(const Point_& pt) const;
195 //! dot product computed in double-precision arithmetics
196 double ddot(const Point_& pt) const;
197 //! cross-product
198 double cross(const Point_& pt) const;
199 //! checks whether the point is inside the specified rectangle
200 bool inside(const Rect_<_Tp>& r) const;
201 _Tp x; //!< x coordinate of the point
202 _Tp y; //!< y coordinate of the point
203};
204
205typedef Point_<int> Point2i;
206typedef Point_<int64> Point2l;
207typedef Point_<float> Point2f;
208typedef Point_<double> Point2d;
209typedef Point2i Point;
210
211template<typename _Tp> class DataType< Point_<_Tp> >
212{
213public:
214 typedef Point_<_Tp> value_type;
215 typedef Point_<typename DataType<_Tp>::work_type> work_type;
216 typedef _Tp channel_type;
217
218 enum { generic_type = 0,
219 channels = 2,
220 fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
221#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
222 ,depth = DataType<channel_type>::depth
223 ,type = CV_MAKETYPE(depth, channels)
224#endif
225 };
226
227 typedef Vec<channel_type, channels> vec_type;
228};
229
230namespace traits {
231template<typename _Tp>
232struct Depth< Point_<_Tp> > { enum { value = Depth<_Tp>::value }; };
233template<typename _Tp>
234struct Type< Point_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; };
235} // namespace
236
237
238//////////////////////////////// Point3_ ////////////////////////////////
239
240/** @brief Template class for 3D points specified by its coordinates `x`, `y` and `z`.
241
242An instance of the class is interchangeable with the C structure CvPoint2D32f . Similarly to
243Point_ , the coordinates of 3D points can be converted to another type. The vector arithmetic and
244comparison operations are also supported.
245
246The following Point3_\<\> aliases are available:
247@code
248 typedef Point3_<int> Point3i;
249 typedef Point3_<float> Point3f;
250 typedef Point3_<double> Point3d;
251@endcode
252@see cv::Point3i, cv::Point3f and cv::Point3d
253*/
254template<typename _Tp> class Point3_
255{
256public:
257 typedef _Tp value_type;
258
259 //! default constructor
260 Point3_();
261 Point3_(_Tp _x, _Tp _y, _Tp _z);
262#if OPENCV_ABI_COMPATIBILITY < 500
263 Point3_(const Point3_& pt) = default;
264 Point3_(Point3_&& pt) CV_NOEXCEPT = default;
265#endif
266 explicit Point3_(const Point_<_Tp>& pt);
267 Point3_(const Vec<_Tp, 3>& v);
268
269#if OPENCV_ABI_COMPATIBILITY < 500
270 Point3_& operator = (const Point3_& pt) = default;
271 Point3_& operator = (Point3_&& pt) CV_NOEXCEPT = default;
272#endif
273 //! conversion to another data type
274 template<typename _Tp2> operator Point3_<_Tp2>() const;
275 //! conversion to cv::Vec<>
276 operator Vec<_Tp, 3>() const;
277
278 //! dot product
279 _Tp dot(const Point3_& pt) const;
280 //! dot product computed in double-precision arithmetics
281 double ddot(const Point3_& pt) const;
282 //! cross product of the 2 3D points
283 Point3_ cross(const Point3_& pt) const;
284 _Tp x; //!< x coordinate of the 3D point
285 _Tp y; //!< y coordinate of the 3D point
286 _Tp z; //!< z coordinate of the 3D point
287};
288
289typedef Point3_<int> Point3i;
290typedef Point3_<float> Point3f;
291typedef Point3_<double> Point3d;
292
293template<typename _Tp> class DataType< Point3_<_Tp> >
294{
295public:
296 typedef Point3_<_Tp> value_type;
297 typedef Point3_<typename DataType<_Tp>::work_type> work_type;
298 typedef _Tp channel_type;
299
300 enum { generic_type = 0,
301 channels = 3,
302 fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
303#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
304 ,depth = DataType<channel_type>::depth
305 ,type = CV_MAKETYPE(depth, channels)
306#endif
307 };
308
309 typedef Vec<channel_type, channels> vec_type;
310};
311
312namespace traits {
313template<typename _Tp>
314struct Depth< Point3_<_Tp> > { enum { value = Depth<_Tp>::value }; };
315template<typename _Tp>
316struct Type< Point3_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 3) }; };
317} // namespace
318
319//////////////////////////////// Size_ ////////////////////////////////
320
321/** @brief Template class for specifying the size of an image or rectangle.
322
323The class includes two members called width and height. The structure can be converted to and from
324the old OpenCV structures CvSize and CvSize2D32f . The same set of arithmetic and comparison
325operations as for Point_ is available.
326
327OpenCV defines the following Size_\<\> aliases:
328@code
329 typedef Size_<int> Size2i;
330 typedef Size2i Size;
331 typedef Size_<float> Size2f;
332@endcode
333*/
334template<typename _Tp> class Size_
335{
336public:
337 typedef _Tp value_type;
338
339 //! default constructor
340 Size_();
341 Size_(_Tp _width, _Tp _height);
342#if OPENCV_ABI_COMPATIBILITY < 500
343 Size_(const Size_& sz) = default;
344 Size_(Size_&& sz) CV_NOEXCEPT = default;
345#endif
346 Size_(const Point_<_Tp>& pt);
347
348#if OPENCV_ABI_COMPATIBILITY < 500
349 Size_& operator = (const Size_& sz) = default;
350 Size_& operator = (Size_&& sz) CV_NOEXCEPT = default;
351#endif
352 //! the area (width*height)
353 _Tp area() const;
354 //! aspect ratio (width/height)
355 double aspectRatio() const;
356 //! true if empty
357 bool empty() const;
358
359 //! conversion of another data type.
360 template<typename _Tp2> operator Size_<_Tp2>() const;
361
362 _Tp width; //!< the width
363 _Tp height; //!< the height
364};
365
366typedef Size_<int> Size2i;
367typedef Size_<int64> Size2l;
368typedef Size_<float> Size2f;
369typedef Size_<double> Size2d;
370typedef Size2i Size;
371
372template<typename _Tp> class DataType< Size_<_Tp> >
373{
374public:
375 typedef Size_<_Tp> value_type;
376 typedef Size_<typename DataType<_Tp>::work_type> work_type;
377 typedef _Tp channel_type;
378
379 enum { generic_type = 0,
380 channels = 2,
381 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8)
382#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
383 ,depth = DataType<channel_type>::depth
384 ,type = CV_MAKETYPE(depth, channels)
385#endif
386 };
387
388 typedef Vec<channel_type, channels> vec_type;
389};
390
391namespace traits {
392template<typename _Tp>
393struct Depth< Size_<_Tp> > { enum { value = Depth<_Tp>::value }; };
394template<typename _Tp>
395struct Type< Size_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; };
396} // namespace
397
398//////////////////////////////// Rect_ ////////////////////////////////
399
400/** @brief Template class for 2D rectangles
401
402described by the following parameters:
403- Coordinates of the top-left corner. This is a default interpretation of Rect_::x and Rect_::y
404 in OpenCV. Though, in your algorithms you may count x and y from the bottom-left corner.
405- Rectangle width and height.
406
407OpenCV typically assumes that the top and left boundary of the rectangle are inclusive, while the
408right and bottom boundaries are not. For example, the method Rect_::contains returns true if
409
410\f[x \leq pt.x < x+width,
411 y \leq pt.y < y+height\f]
412
413Virtually every loop over an image ROI in OpenCV (where ROI is specified by Rect_\<int\> ) is
414implemented as:
415@code
416 for(int y = roi.y; y < roi.y + roi.height; y++)
417 for(int x = roi.x; x < roi.x + roi.width; x++)
418 {
419 // ...
420 }
421@endcode
422In addition to the class members, the following operations on rectangles are implemented:
423- \f$\texttt{rect} = \texttt{rect} \pm \texttt{point}\f$ (shifting a rectangle by a certain offset)
424- \f$\texttt{rect} = \texttt{rect} \pm \texttt{size}\f$ (expanding or shrinking a rectangle by a
425 certain amount)
426- rect += point, rect -= point, rect += size, rect -= size (augmenting operations)
427- rect = rect1 & rect2 (rectangle intersection)
428- rect = rect1 | rect2 (minimum area rectangle containing rect1 and rect2 )
429- rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
430- rect == rect1, rect != rect1 (rectangle comparison)
431
432This is an example how the partial ordering on rectangles can be established (rect1 \f$\subseteq\f$
433rect2):
434@code
435 template<typename _Tp> inline bool
436 operator <= (const Rect_<_Tp>& r1, const Rect_<_Tp>& r2)
437 {
438 return (r1 & r2) == r1;
439 }
440@endcode
441For your convenience, the Rect_\<\> alias is available: cv::Rect
442*/
443template<typename _Tp> class Rect_
444{
445public:
446 typedef _Tp value_type;
447
448 //! default constructor
449 Rect_();
450 Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
451#if OPENCV_ABI_COMPATIBILITY < 500
452 Rect_(const Rect_& r) = default;
453 Rect_(Rect_&& r) CV_NOEXCEPT = default;
454#endif
455 Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
456 Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
457
458#if OPENCV_ABI_COMPATIBILITY < 500
459 Rect_& operator = (const Rect_& r) = default;
460 Rect_& operator = (Rect_&& r) CV_NOEXCEPT = default;
461#endif
462 //! the top-left corner
463 Point_<_Tp> tl() const;
464 //! the bottom-right corner
465 Point_<_Tp> br() const;
466
467 //! size (width, height) of the rectangle
468 Size_<_Tp> size() const;
469 //! area (width*height) of the rectangle
470 _Tp area() const;
471 //! true if empty
472 bool empty() const;
473
474 //! conversion to another data type
475 template<typename _Tp2> operator Rect_<_Tp2>() const;
476
477 //! checks whether the rectangle contains the point
478 /*! @warning After OpenCV 4.11.0, when calling Rect.contains() with cv::Point2f / cv::Point2d point, point should not convert/round to int.
479 * ```
480 * Rect_<int> r(0,0,500,500); Point_<float> pt(250.0f, 499.9f);
481 * r.contains(pt) returns false.(OpenCV 4.10.0 or before)
482 * r.contains(pt) returns true. (OpenCV 4.11.0 or later)
483 * ```
484 */
485 template<typename _Tp2> inline bool contains(const Point_<_Tp2>& pt) const;
486
487 _Tp x; //!< x coordinate of the top-left corner
488 _Tp y; //!< y coordinate of the top-left corner
489 _Tp width; //!< width of the rectangle
490 _Tp height; //!< height of the rectangle
491};
492
493typedef Rect_<int> Rect2i;
494typedef Rect_<float> Rect2f;
495typedef Rect_<double> Rect2d;
496typedef Rect2i Rect;
497
498template<typename _Tp> class DataType< Rect_<_Tp> >
499{
500public:
501 typedef Rect_<_Tp> value_type;
502 typedef Rect_<typename DataType<_Tp>::work_type> work_type;
503 typedef _Tp channel_type;
504
505 enum { generic_type = 0,
506 channels = 4,
507 fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
508#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
509 ,depth = DataType<channel_type>::depth
510 ,type = CV_MAKETYPE(depth, channels)
511#endif
512 };
513
514 typedef Vec<channel_type, channels> vec_type;
515};
516
517namespace traits {
518template<typename _Tp>
519struct Depth< Rect_<_Tp> > { enum { value = Depth<_Tp>::value }; };
520template<typename _Tp>
521struct Type< Rect_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 4) }; };
522} // namespace
523
524///////////////////////////// RotatedRect /////////////////////////////
525
526/** @brief The class represents rotated (i.e. not up-right) rectangles on a plane.
527
528Each rectangle is specified by the center point (mass center), length of each side (represented by
529#Size2f structure) and the rotation angle in degrees.
530
531The sample below demonstrates how to use RotatedRect:
532@snippet snippets/core_various.cpp RotatedRect_demo
533![image](pics/rotatedrect.png)
534
535@sa CamShift, fitEllipse, minAreaRect, CvBox2D
536*/
537class CV_EXPORTS_W_SIMPLE RotatedRect
538{
539public:
540 //! default constructor
541 CV_WRAP RotatedRect();
542 /** full constructor
543 @param center The rectangle mass center.
544 @param size Width and height of the rectangle.
545 @param angle The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc.,
546 the rectangle becomes an up-right rectangle.
547 */
548 CV_WRAP RotatedRect(const Point2f& center, const Size2f& size, float angle);
549 /**
550 Any 3 end points of the RotatedRect. They must be given in order (either clockwise or
551 anticlockwise).
552 */
553 CV_WRAP RotatedRect(const Point2f& point1, const Point2f& point2, const Point2f& point3);
554
555 /** returns 4 vertices of the rotated rectangle
556 @param pts The points array for storing rectangle vertices. The order is _bottomLeft_, _topLeft_, topRight, bottomRight.
557 @note _Bottom_, _Top_, _Left_ and _Right_ sides refer to the original rectangle (angle is 0),
558 so after 180 degree rotation _bottomLeft_ point will be located at the top right corner of the
559 rectangle.
560 */
561 void points(Point2f pts[]) const;
562
563 CV_WRAP void points(CV_OUT std::vector<Point2f>& pts) const;
564
565 //! returns the minimal up-right integer rectangle containing the rotated rectangle
566 CV_WRAP Rect boundingRect() const;
567 //! returns the minimal (exact) floating point rectangle containing the rotated rectangle, not intended for use with images
568 CV_WRAP Rect2f boundingRect2f() const;
569 //! returns the rectangle mass center
570 CV_PROP_RW Point2f center;
571 //! returns width and height of the rectangle
572 CV_PROP_RW Size2f size;
573 //! returns the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
574 CV_PROP_RW float angle;
575};
576
577template<> class DataType< RotatedRect >
578{
579public:
580 typedef RotatedRect value_type;
581 typedef value_type work_type;
582 typedef float channel_type;
583
584 enum { generic_type = 0,
585 channels = (int)sizeof(value_type)/sizeof(channel_type), // 5
586 fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
587#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
588 ,depth = DataType<channel_type>::depth
589 ,type = CV_MAKETYPE(depth, channels)
590#endif
591 };
592
593 typedef Vec<channel_type, channels> vec_type;
594};
595
596namespace traits {
597template<>
598struct Depth< RotatedRect > { enum { value = Depth<float>::value }; };
599template<>
600struct Type< RotatedRect > { enum { value = CV_MAKETYPE(Depth<float>::value, (int)sizeof(RotatedRect)/sizeof(float)) }; };
601} // namespace
602
603
604//////////////////////////////// Range /////////////////////////////////
605
606/** @brief Template class specifying a continuous subsequence (slice) of a sequence.
607
608The class is used to specify a row or a column span in a matrix ( Mat ) and for many other purposes.
609Range(a,b) is basically the same as a:b in Matlab or a..b in Python. As in Python, start is an
610inclusive left boundary of the range and end is an exclusive right boundary of the range. Such a
611half-opened interval is usually denoted as \f$[start,end)\f$ .
612
613The static method Range::all() returns a special variable that means "the whole sequence" or "the
614whole range", just like " : " in Matlab or " ... " in Python. All the methods and functions in
615OpenCV that take Range support this special Range::all() value. But, of course, in case of your own
616custom processing, you will probably have to check and handle it explicitly:
617@code
618 void my_function(..., const Range& r, ....)
619 {
620 if(r == Range::all()) {
621 // process all the data
622 }
623 else {
624 // process [r.start, r.end)
625 }
626 }
627@endcode
628*/
629class CV_EXPORTS Range
630{
631public:
632 Range();
633 Range(int _start, int _end);
634 int size() const;
635 bool empty() const;
636 static Range all();
637
638 int start, end;
639};
640
641template<> class DataType<Range>
642{
643public:
644 typedef Range value_type;
645 typedef value_type work_type;
646 typedef int channel_type;
647
648 enum { generic_type = 0,
649 channels = 2,
650 fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
651#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
652 ,depth = DataType<channel_type>::depth
653 ,type = CV_MAKETYPE(depth, channels)
654#endif
655 };
656
657 typedef Vec<channel_type, channels> vec_type;
658};
659
660namespace traits {
661template<>
662struct Depth< Range > { enum { value = Depth<int>::value }; };
663template<>
664struct Type< Range > { enum { value = CV_MAKETYPE(Depth<int>::value, 2) }; };
665} // namespace
666
667
668//////////////////////////////// Scalar_ ///////////////////////////////
669
670/** @brief Template class for a 4-element vector derived from Vec.
671
672Being derived from Vec\<_Tp, 4\> , Scalar\_ and Scalar can be used just as typical 4-element
673vectors. In addition, they can be converted to/from CvScalar . The type Scalar is widely used in
674OpenCV to pass pixel values.
675*/
676template<typename _Tp> class Scalar_ : public Vec<_Tp, 4>
677{
678public:
679 //! default constructor
680 Scalar_();
681 Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
682 Scalar_(_Tp v0);
683
684 Scalar_(const Scalar_& s);
685 Scalar_(Scalar_&& s) CV_NOEXCEPT;
686
687 Scalar_& operator=(const Scalar_& s);
688 Scalar_& operator=(Scalar_&& s) CV_NOEXCEPT;
689
690 template<typename _Tp2, int cn>
691 Scalar_(const Vec<_Tp2, cn>& v);
692
693 //! returns a scalar with all elements set to v0
694 static Scalar_<_Tp> all(_Tp v0);
695
696 //! conversion to another data type
697 template<typename T2> operator Scalar_<T2>() const;
698
699 //! per-element product
700 Scalar_<_Tp> mul(const Scalar_<_Tp>& a, double scale=1 ) const;
701
702 //! returns (v0, -v1, -v2, -v3)
703 Scalar_<_Tp> conj() const;
704
705 //! returns true iff v1 == v2 == v3 == 0
706 bool isReal() const;
707};
708
709typedef Scalar_<double> Scalar;
710
711template<typename _Tp> class DataType< Scalar_<_Tp> >
712{
713public:
714 typedef Scalar_<_Tp> value_type;
715 typedef Scalar_<typename DataType<_Tp>::work_type> work_type;
716 typedef _Tp channel_type;
717
718 enum { generic_type = 0,
719 channels = 4,
720 fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
721#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
722 ,depth = DataType<channel_type>::depth
723 ,type = CV_MAKETYPE(depth, channels)
724#endif
725 };
726
727 typedef Vec<channel_type, channels> vec_type;
728};
729
730namespace traits {
731template<typename _Tp>
732struct Depth< Scalar_<_Tp> > { enum { value = Depth<_Tp>::value }; };
733template<typename _Tp>
734struct Type< Scalar_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 4) }; };
735} // namespace
736
737
738/////////////////////////////// KeyPoint ////////////////////////////////
739
740/** @brief Data structure for salient point detectors.
741
742The class instance stores a keypoint, i.e. a point feature found by one of many available keypoint
743detectors, such as Harris corner detector, #FAST, %StarDetector, %SURF, %SIFT etc.
744
745The keypoint is characterized by the 2D position, scale (proportional to the diameter of the
746neighborhood that needs to be taken into account), orientation and some other parameters. The
747keypoint neighborhood is then analyzed by another algorithm that builds a descriptor (usually
748represented as a feature vector). The keypoints representing the same object in different images
749can then be matched using %KDTree or another method.
750*/
751class CV_EXPORTS_W_SIMPLE KeyPoint
752{
753public:
754 //! the default constructor
755 CV_WRAP KeyPoint();
756 /**
757 @param pt x & y coordinates of the keypoint
758 @param size keypoint diameter
759 @param angle keypoint orientation
760 @param response keypoint detector response on the keypoint (that is, strength of the keypoint)
761 @param octave pyramid octave in which the keypoint has been detected
762 @param class_id object id
763 */
764 KeyPoint(Point2f pt, float size, float angle=-1, float response=0, int octave=0, int class_id=-1);
765 /**
766 @param x x-coordinate of the keypoint
767 @param y y-coordinate of the keypoint
768 @param size keypoint diameter
769 @param angle keypoint orientation
770 @param response keypoint detector response on the keypoint (that is, strength of the keypoint)
771 @param octave pyramid octave in which the keypoint has been detected
772 @param class_id object id
773 */
774 CV_WRAP KeyPoint(float x, float y, float size, float angle=-1, float response=0, int octave=0, int class_id=-1);
775
776 size_t hash() const;
777
778 /**
779 This method converts vector of keypoints to vector of points or the reverse, where each keypoint is
780 assigned the same size and the same orientation.
781
782 @param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
783 @param points2f Array of (x,y) coordinates of each keypoint
784 @param keypointIndexes Array of indexes of keypoints to be converted to points. (Acts like a mask to
785 convert only specified keypoints)
786 */
787 CV_WRAP static void convert(const std::vector<KeyPoint>& keypoints,
788 CV_OUT std::vector<Point2f>& points2f,
789 const std::vector<int>& keypointIndexes=std::vector<int>());
790 /** @overload
791 @param points2f Array of (x,y) coordinates of each keypoint
792 @param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
793 @param size keypoint diameter
794 @param response keypoint detector response on the keypoint (that is, strength of the keypoint)
795 @param octave pyramid octave in which the keypoint has been detected
796 @param class_id object id
797 */
798 CV_WRAP static void convert(const std::vector<Point2f>& points2f,
799 CV_OUT std::vector<KeyPoint>& keypoints,
800 float size=1, float response=1, int octave=0, int class_id=-1);
801
802 /**
803 This method computes overlap for pair of keypoints. Overlap is the ratio between area of keypoint
804 regions' intersection and area of keypoint regions' union (considering keypoint region as circle).
805 If they don't overlap, we get zero. If they coincide at same location with same size, we get 1.
806 @param kp1 First keypoint
807 @param kp2 Second keypoint
808 */
809 CV_WRAP static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
810
811 CV_PROP_RW Point2f pt; //!< coordinates of the keypoints
812 CV_PROP_RW float size; //!< diameter of the meaningful keypoint neighborhood
813 CV_PROP_RW float angle; //!< computed orientation of the keypoint (-1 if not applicable);
814 //!< it's in [0,360) degrees and measured relative to
815 //!< image coordinate system, ie in clockwise.
816 CV_PROP_RW float response; //!< the response by which the most strong keypoints have been selected. Can be used for the further sorting or subsampling
817 CV_PROP_RW int octave; //!< octave (pyramid layer) from which the keypoint has been extracted
818 CV_PROP_RW int class_id; //!< object class (if the keypoints need to be clustered by an object they belong to)
819};
820
821#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
822template<> class DataType<KeyPoint>
823{
824public:
825 typedef KeyPoint value_type;
826 typedef float work_type;
827 typedef float channel_type;
828
829 enum { generic_type = 0,
830 depth = DataType<channel_type>::depth,
831 channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 7
832 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
833 type = CV_MAKETYPE(depth, channels)
834 };
835
836 typedef Vec<channel_type, channels> vec_type;
837};
838#endif
839
840
841//////////////////////////////// DMatch /////////////////////////////////
842
843/** @brief Class for matching keypoint descriptors
844
845query descriptor index, train descriptor index, train image index, and distance between
846descriptors.
847*/
848class CV_EXPORTS_W_SIMPLE DMatch
849{
850public:
851 CV_WRAP DMatch();
852 CV_WRAP DMatch(int _queryIdx, int _trainIdx, float _distance);
853 CV_WRAP DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance);
854
855 CV_PROP_RW int queryIdx; //!< query descriptor index
856 CV_PROP_RW int trainIdx; //!< train descriptor index
857 CV_PROP_RW int imgIdx; //!< train image index
858
859 CV_PROP_RW float distance;
860
861 // less is better
862 bool operator<(const DMatch &m) const;
863};
864
865#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
866template<> class DataType<DMatch>
867{
868public:
869 typedef DMatch value_type;
870 typedef int work_type;
871 typedef int channel_type;
872
873 enum { generic_type = 0,
874 depth = DataType<channel_type>::depth,
875 channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 4
876 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
877 type = CV_MAKETYPE(depth, channels)
878 };
879
880 typedef Vec<channel_type, channels> vec_type;
881};
882#endif
883
884
885///////////////////////////// TermCriteria //////////////////////////////
886
887/** @brief The class defining termination criteria for iterative algorithms.
888
889You can initialize it by default constructor and then override any parameters, or the structure may
890be fully initialized using the advanced variant of the constructor.
891*/
892class CV_EXPORTS TermCriteria
893{
894public:
895 /**
896 Criteria type, can be one of: COUNT, EPS or COUNT + EPS
897 */
898 enum Type
899 {
900 COUNT=1, //!< the maximum number of iterations or elements to compute
901 MAX_ITER=COUNT, //!< ditto
902 EPS=2 //!< the desired accuracy or change in parameters at which the iterative algorithm stops
903 };
904
905 //! default constructor
906 TermCriteria();
907 /**
908 @param type The type of termination criteria, one of TermCriteria::Type
909 @param maxCount The maximum number of iterations or elements to compute.
910 @param epsilon The desired accuracy or change in parameters at which the iterative algorithm stops.
911 */
912 TermCriteria(int type, int maxCount, double epsilon);
913
914 inline bool isValid() const
915 {
916 const bool isCount = (type & COUNT) && maxCount > 0;
917 const bool isEps = (type & EPS) && !cvIsNaN(value: epsilon);
918 return isCount || isEps;
919 }
920
921 int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS
922 int maxCount; //!< the maximum number of iterations/elements
923 double epsilon; //!< the desired accuracy
924};
925
926
927//! @} core_basic
928
929///////////////////////// raster image moments //////////////////////////
930
931//! @addtogroup imgproc_shape
932//! @{
933
934/** @brief struct returned by cv::moments
935
936The spatial moments \f$\texttt{Moments::m}_{ji}\f$ are computed as:
937
938\f[\texttt{m} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot x^j \cdot y^i \right )\f]
939
940The central moments \f$\texttt{Moments::mu}_{ji}\f$ are computed as:
941
942\f[\texttt{mu} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot (x - \bar{x} )^j \cdot (y - \bar{y} )^i \right )\f]
943
944where \f$(\bar{x}, \bar{y})\f$ is the mass center:
945
946\f[\bar{x} = \frac{\texttt{m}_{10}}{\texttt{m}_{00}} , \; \bar{y} = \frac{\texttt{m}_{01}}{\texttt{m}_{00}}\f]
947
948The normalized central moments \f$\texttt{Moments::nu}_{ij}\f$ are computed as:
949
950\f[\texttt{nu} _{ji}= \frac{\texttt{mu}_{ji}}{\texttt{m}_{00}^{(i+j)/2+1}} .\f]
951
952@note
953\f$\texttt{mu}_{00}=\texttt{m}_{00}\f$, \f$\texttt{nu}_{00}=1\f$
954\f$\texttt{nu}_{10}=\texttt{mu}_{10}=\texttt{mu}_{01}=\texttt{mu}_{10}=0\f$ , hence the values are not
955stored.
956
957The moments of a contour are defined in the same way but computed using the Green's formula (see
958<http://en.wikipedia.org/wiki/Green_theorem>). So, due to a limited raster resolution, the moments
959computed for a contour are slightly different from the moments computed for the same rasterized
960contour.
961
962@note
963Since the contour moments are computed using Green formula, you may get seemingly odd results for
964contours with self-intersections, e.g. a zero area (m00) for butterfly-shaped contours.
965 */
966class CV_EXPORTS_W_MAP Moments
967{
968public:
969 //! the default constructor
970 Moments();
971 //! the full constructor
972 Moments(double m00, double m10, double m01, double m20, double m11,
973 double m02, double m30, double m21, double m12, double m03 );
974 ////! the conversion from CvMoments
975 //Moments( const CvMoments& moments );
976 ////! the conversion to CvMoments
977 //operator CvMoments() const;
978
979 //! @name spatial moments
980 //! @{
981 CV_PROP_RW double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
982 //! @}
983
984 //! @name central moments
985 //! @{
986 CV_PROP_RW double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
987 //! @}
988
989 //! @name central normalized moments
990 //! @{
991 CV_PROP_RW double nu20, nu11, nu02, nu30, nu21, nu12, nu03;
992 //! @}
993};
994
995template<> class DataType<Moments>
996{
997public:
998 typedef Moments value_type;
999 typedef double work_type;
1000 typedef double channel_type;
1001
1002 enum { generic_type = 0,
1003 channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 24
1004 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8)
1005#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
1006 ,depth = DataType<channel_type>::depth
1007 ,type = CV_MAKETYPE(depth, channels)
1008#endif
1009 };
1010
1011 typedef Vec<channel_type, channels> vec_type;
1012};
1013
1014namespace traits {
1015template<>
1016struct Depth< Moments > { enum { value = Depth<double>::value }; };
1017template<>
1018struct Type< Moments > { enum { value = CV_MAKETYPE(Depth<double>::value, (int)(sizeof(Moments)/sizeof(double))) }; };
1019} // namespace
1020
1021//! @} imgproc_shape
1022
1023//! @cond IGNORED
1024
1025/////////////////////////////////////////////////////////////////////////
1026///////////////////////////// Implementation ////////////////////////////
1027/////////////////////////////////////////////////////////////////////////
1028
1029//////////////////////////////// Complex ////////////////////////////////
1030
1031template<typename _Tp> inline
1032Complex<_Tp>::Complex()
1033 : re(0), im(0) {}
1034
1035template<typename _Tp> inline
1036Complex<_Tp>::Complex( _Tp _re, _Tp _im )
1037 : re(_re), im(_im) {}
1038
1039template<typename _Tp> template<typename T2> inline
1040Complex<_Tp>::operator Complex<T2>() const
1041{
1042 return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im));
1043}
1044
1045template<typename _Tp> inline
1046Complex<_Tp> Complex<_Tp>::conj() const
1047{
1048 return Complex<_Tp>(re, -im);
1049}
1050
1051
1052template<typename _Tp> static inline
1053bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b)
1054{
1055 return a.re == b.re && a.im == b.im;
1056}
1057
1058template<typename _Tp> static inline
1059bool operator != (const Complex<_Tp>& a, const Complex<_Tp>& b)
1060{
1061 return a.re != b.re || a.im != b.im;
1062}
1063
1064template<typename _Tp> static inline
1065Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b)
1066{
1067 return Complex<_Tp>( a.re + b.re, a.im + b.im );
1068}
1069
1070template<typename _Tp> static inline
1071Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b)
1072{
1073 a.re += b.re; a.im += b.im;
1074 return a;
1075}
1076
1077template<typename _Tp> static inline
1078Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b)
1079{
1080 return Complex<_Tp>( a.re - b.re, a.im - b.im );
1081}
1082
1083template<typename _Tp> static inline
1084Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b)
1085{
1086 a.re -= b.re; a.im -= b.im;
1087 return a;
1088}
1089
1090template<typename _Tp> static inline
1091Complex<_Tp> operator - (const Complex<_Tp>& a)
1092{
1093 return Complex<_Tp>(-a.re, -a.im);
1094}
1095
1096template<typename _Tp> static inline
1097Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b)
1098{
1099 return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re );
1100}
1101
1102template<typename _Tp> static inline
1103Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b)
1104{
1105 return Complex<_Tp>( a.re*b, a.im*b );
1106}
1107
1108template<typename _Tp> static inline
1109Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a)
1110{
1111 return Complex<_Tp>( a.re*b, a.im*b );
1112}
1113
1114template<typename _Tp> static inline
1115Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b)
1116{
1117 return Complex<_Tp>( a.re + b, a.im );
1118}
1119
1120template<typename _Tp> static inline
1121Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b)
1122{ return Complex<_Tp>( a.re - b, a.im ); }
1123
1124template<typename _Tp> static inline
1125Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a)
1126{
1127 return Complex<_Tp>( a.re + b, a.im );
1128}
1129
1130template<typename _Tp> static inline
1131Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a)
1132{
1133 return Complex<_Tp>( b - a.re, -a.im );
1134}
1135
1136template<typename _Tp> static inline
1137Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b)
1138{
1139 a.re += b; return a;
1140}
1141
1142template<typename _Tp> static inline
1143Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b)
1144{
1145 a.re -= b; return a;
1146}
1147
1148template<typename _Tp> static inline
1149Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b)
1150{
1151 a.re *= b; a.im *= b; return a;
1152}
1153
1154template<typename _Tp> static inline
1155double abs(const Complex<_Tp>& a)
1156{
1157 return std::sqrt( (double)a.re*a.re + (double)a.im*a.im);
1158}
1159
1160template<typename _Tp> static inline
1161Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b)
1162{
1163 double t = 1./((double)b.re*b.re + (double)b.im*b.im);
1164 return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t),
1165 (_Tp)((-a.re*b.im + a.im*b.re)*t) );
1166}
1167
1168template<typename _Tp> static inline
1169Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b)
1170{
1171 a = a / b;
1172 return a;
1173}
1174
1175template<typename _Tp> static inline
1176Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b)
1177{
1178 _Tp t = (_Tp)1/b;
1179 return Complex<_Tp>( a.re*t, a.im*t );
1180}
1181
1182template<typename _Tp> static inline
1183Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a)
1184{
1185 return Complex<_Tp>(b)/a;
1186}
1187
1188template<typename _Tp> static inline
1189Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b)
1190{
1191 _Tp t = (_Tp)1/b;
1192 a.re *= t; a.im *= t; return a;
1193}
1194
1195
1196
1197//////////////////////////////// 2D Point ///////////////////////////////
1198
1199template<typename _Tp> inline
1200Point_<_Tp>::Point_()
1201 : x(0), y(0) {}
1202
1203template<typename _Tp> inline
1204Point_<_Tp>::Point_(_Tp _x, _Tp _y)
1205 : x(_x), y(_y) {}
1206
1207#if (defined(__GNUC__) && __GNUC__ < 5) && !defined(__clang__) // GCC 4.x bug. Details: https://github.com/opencv/opencv/pull/20837
1208template<typename _Tp> inline
1209Point_<_Tp>::Point_(const Point_& pt)
1210 : x(pt.x), y(pt.y) {}
1211#endif
1212
1213template<typename _Tp> inline
1214Point_<_Tp>::Point_(const Size_<_Tp>& sz)
1215 : x(sz.width), y(sz.height) {}
1216
1217template<typename _Tp> inline
1218Point_<_Tp>::Point_(const Vec<_Tp,2>& v)
1219 : x(v[0]), y(v[1]) {}
1220
1221#if (defined(__GNUC__) && __GNUC__ < 5) && !defined(__clang__) // GCC 4.x bug. Details: https://github.com/opencv/opencv/pull/20837
1222template<typename _Tp> inline
1223Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt)
1224{
1225 x = pt.x; y = pt.y;
1226 return *this;
1227}
1228#endif
1229
1230template<typename _Tp> template<typename _Tp2> inline
1231Point_<_Tp>::operator Point_<_Tp2>() const
1232{
1233 return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y));
1234}
1235
1236template<typename _Tp> inline
1237Point_<_Tp>::operator Vec<_Tp, 2>() const
1238{
1239 return Vec<_Tp, 2>(x, y);
1240}
1241
1242template<typename _Tp> inline
1243_Tp Point_<_Tp>::dot(const Point_& pt) const
1244{
1245 return saturate_cast<_Tp>(x*pt.x + y*pt.y);
1246}
1247
1248template<typename _Tp> inline
1249double Point_<_Tp>::ddot(const Point_& pt) const
1250{
1251 return (double)x*(double)(pt.x) + (double)y*(double)(pt.y);
1252}
1253
1254template<typename _Tp> inline
1255double Point_<_Tp>::cross(const Point_& pt) const
1256{
1257 return (double)x*pt.y - (double)y*pt.x;
1258}
1259
1260template<typename _Tp> inline bool
1261Point_<_Tp>::inside( const Rect_<_Tp>& r ) const
1262{
1263 return r.contains(*this);
1264}
1265
1266
1267template<typename _Tp> static inline
1268Point_<_Tp>& operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
1269{
1270 a.x += b.x;
1271 a.y += b.y;
1272 return a;
1273}
1274
1275template<typename _Tp> static inline
1276Point_<_Tp>& operator -= (Point_<_Tp>& a, const Point_<_Tp>& b)
1277{
1278 a.x -= b.x;
1279 a.y -= b.y;
1280 return a;
1281}
1282
1283template<typename _Tp> static inline
1284Point_<_Tp>& operator *= (Point_<_Tp>& a, int b)
1285{
1286 a.x = saturate_cast<_Tp>(a.x * b);
1287 a.y = saturate_cast<_Tp>(a.y * b);
1288 return a;
1289}
1290
1291template<typename _Tp> static inline
1292Point_<_Tp>& operator *= (Point_<_Tp>& a, float b)
1293{
1294 a.x = saturate_cast<_Tp>(a.x * b);
1295 a.y = saturate_cast<_Tp>(a.y * b);
1296 return a;
1297}
1298
1299template<typename _Tp> static inline
1300Point_<_Tp>& operator *= (Point_<_Tp>& a, double b)
1301{
1302 a.x = saturate_cast<_Tp>(a.x * b);
1303 a.y = saturate_cast<_Tp>(a.y * b);
1304 return a;
1305}
1306
1307template<typename _Tp> static inline
1308Point_<_Tp>& operator /= (Point_<_Tp>& a, int b)
1309{
1310 a.x = saturate_cast<_Tp>(a.x / b);
1311 a.y = saturate_cast<_Tp>(a.y / b);
1312 return a;
1313}
1314
1315template<typename _Tp> static inline
1316Point_<_Tp>& operator /= (Point_<_Tp>& a, float b)
1317{
1318 a.x = saturate_cast<_Tp>(a.x / b);
1319 a.y = saturate_cast<_Tp>(a.y / b);
1320 return a;
1321}
1322
1323template<typename _Tp> static inline
1324Point_<_Tp>& operator /= (Point_<_Tp>& a, double b)
1325{
1326 a.x = saturate_cast<_Tp>(a.x / b);
1327 a.y = saturate_cast<_Tp>(a.y / b);
1328 return a;
1329}
1330
1331template<typename _Tp> static inline
1332double norm(const Point_<_Tp>& pt)
1333{
1334 return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y);
1335}
1336
1337template<typename _Tp> static inline
1338bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b)
1339{
1340 return a.x == b.x && a.y == b.y;
1341}
1342
1343template<typename _Tp> static inline
1344bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b)
1345{
1346 return a.x != b.x || a.y != b.y;
1347}
1348
1349template<typename _Tp> static inline
1350Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b)
1351{
1352 return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) );
1353}
1354
1355template<typename _Tp> static inline
1356Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b)
1357{
1358 return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) );
1359}
1360
1361template<typename _Tp> static inline
1362Point_<_Tp> operator - (const Point_<_Tp>& a)
1363{
1364 return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) );
1365}
1366
1367template<typename _Tp> static inline
1368Point_<_Tp> operator * (const Point_<_Tp>& a, int b)
1369{
1370 return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
1371}
1372
1373template<typename _Tp> static inline
1374Point_<_Tp> operator * (int a, const Point_<_Tp>& b)
1375{
1376 return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
1377}
1378
1379template<typename _Tp> static inline
1380Point_<_Tp> operator * (const Point_<_Tp>& a, float b)
1381{
1382 return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
1383}
1384
1385template<typename _Tp> static inline
1386Point_<_Tp> operator * (float a, const Point_<_Tp>& b)
1387{
1388 return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
1389}
1390
1391template<typename _Tp> static inline
1392Point_<_Tp> operator * (const Point_<_Tp>& a, double b)
1393{
1394 return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
1395}
1396
1397template<typename _Tp> static inline
1398Point_<_Tp> operator * (double a, const Point_<_Tp>& b)
1399{
1400 return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
1401}
1402
1403template<typename _Tp> static inline
1404Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
1405{
1406 Matx<_Tp, 2, 1> tmp = a * Vec<_Tp,2>(b.x, b.y);
1407 return Point_<_Tp>(tmp.val[0], tmp.val[1]);
1408}
1409
1410template<typename _Tp> static inline
1411Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b)
1412{
1413 Matx<_Tp, 3, 1> tmp = a * Vec<_Tp,3>(b.x, b.y, 1);
1414 return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]);
1415}
1416
1417template<typename _Tp> static inline
1418Point_<_Tp> operator / (const Point_<_Tp>& a, int b)
1419{
1420 Point_<_Tp> tmp(a);
1421 tmp /= b;
1422 return tmp;
1423}
1424
1425template<typename _Tp> static inline
1426Point_<_Tp> operator / (const Point_<_Tp>& a, float b)
1427{
1428 Point_<_Tp> tmp(a);
1429 tmp /= b;
1430 return tmp;
1431}
1432
1433template<typename _Tp> static inline
1434Point_<_Tp> operator / (const Point_<_Tp>& a, double b)
1435{
1436 Point_<_Tp> tmp(a);
1437 tmp /= b;
1438 return tmp;
1439}
1440
1441
1442template<typename _AccTp> static inline _AccTp normL2Sqr(const Point_<int>& pt);
1443template<typename _AccTp> static inline _AccTp normL2Sqr(const Point_<int64>& pt);
1444template<typename _AccTp> static inline _AccTp normL2Sqr(const Point_<float>& pt);
1445template<typename _AccTp> static inline _AccTp normL2Sqr(const Point_<double>& pt);
1446
1447template<> inline int normL2Sqr<int>(const Point_<int>& pt) { return pt.dot(pt); }
1448template<> inline int64 normL2Sqr<int64>(const Point_<int64>& pt) { return pt.dot(pt); }
1449template<> inline float normL2Sqr<float>(const Point_<float>& pt) { return pt.dot(pt); }
1450template<> inline double normL2Sqr<double>(const Point_<int>& pt) { return pt.dot(pt); }
1451
1452template<> inline double normL2Sqr<double>(const Point_<float>& pt) { return pt.ddot(pt); }
1453template<> inline double normL2Sqr<double>(const Point_<double>& pt) { return pt.ddot(pt); }
1454
1455
1456
1457//////////////////////////////// 3D Point ///////////////////////////////
1458
1459template<typename _Tp> inline
1460Point3_<_Tp>::Point3_()
1461 : x(0), y(0), z(0) {}
1462
1463template<typename _Tp> inline
1464Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z)
1465 : x(_x), y(_y), z(_z) {}
1466
1467template<typename _Tp> inline
1468Point3_<_Tp>::Point3_(const Point_<_Tp>& pt)
1469 : x(pt.x), y(pt.y), z(_Tp()) {}
1470
1471template<typename _Tp> inline
1472Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v)
1473 : x(v[0]), y(v[1]), z(v[2]) {}
1474
1475template<typename _Tp> template<typename _Tp2> inline
1476Point3_<_Tp>::operator Point3_<_Tp2>() const
1477{
1478 return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z));
1479}
1480
1481template<typename _Tp> inline
1482Point3_<_Tp>::operator Vec<_Tp, 3>() const
1483{
1484 return Vec<_Tp, 3>(x, y, z);
1485}
1486
1487template<typename _Tp> inline
1488_Tp Point3_<_Tp>::dot(const Point3_& pt) const
1489{
1490 return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z);
1491}
1492
1493template<typename _Tp> inline
1494double Point3_<_Tp>::ddot(const Point3_& pt) const
1495{
1496 return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z;
1497}
1498
1499template<typename _Tp> inline
1500Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const
1501{
1502 return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x);
1503}
1504
1505
1506template<typename _Tp> static inline
1507Point3_<_Tp>& operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b)
1508{
1509 a.x += b.x;
1510 a.y += b.y;
1511 a.z += b.z;
1512 return a;
1513}
1514
1515template<typename _Tp> static inline
1516Point3_<_Tp>& operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b)
1517{
1518 a.x -= b.x;
1519 a.y -= b.y;
1520 a.z -= b.z;
1521 return a;
1522}
1523
1524template<typename _Tp> static inline
1525Point3_<_Tp>& operator *= (Point3_<_Tp>& a, int b)
1526{
1527 a.x = saturate_cast<_Tp>(a.x * b);
1528 a.y = saturate_cast<_Tp>(a.y * b);
1529 a.z = saturate_cast<_Tp>(a.z * b);
1530 return a;
1531}
1532
1533template<typename _Tp> static inline
1534Point3_<_Tp>& operator *= (Point3_<_Tp>& a, float b)
1535{
1536 a.x = saturate_cast<_Tp>(a.x * b);
1537 a.y = saturate_cast<_Tp>(a.y * b);
1538 a.z = saturate_cast<_Tp>(a.z * b);
1539 return a;
1540}
1541
1542template<typename _Tp> static inline
1543Point3_<_Tp>& operator *= (Point3_<_Tp>& a, double b)
1544{
1545 a.x = saturate_cast<_Tp>(a.x * b);
1546 a.y = saturate_cast<_Tp>(a.y * b);
1547 a.z = saturate_cast<_Tp>(a.z * b);
1548 return a;
1549}
1550
1551template<typename _Tp> static inline
1552Point3_<_Tp>& operator /= (Point3_<_Tp>& a, int b)
1553{
1554 a.x = saturate_cast<_Tp>(a.x / b);
1555 a.y = saturate_cast<_Tp>(a.y / b);
1556 a.z = saturate_cast<_Tp>(a.z / b);
1557 return a;
1558}
1559
1560template<typename _Tp> static inline
1561Point3_<_Tp>& operator /= (Point3_<_Tp>& a, float b)
1562{
1563 a.x = saturate_cast<_Tp>(a.x / b);
1564 a.y = saturate_cast<_Tp>(a.y / b);
1565 a.z = saturate_cast<_Tp>(a.z / b);
1566 return a;
1567}
1568
1569template<typename _Tp> static inline
1570Point3_<_Tp>& operator /= (Point3_<_Tp>& a, double b)
1571{
1572 a.x = saturate_cast<_Tp>(a.x / b);
1573 a.y = saturate_cast<_Tp>(a.y / b);
1574 a.z = saturate_cast<_Tp>(a.z / b);
1575 return a;
1576}
1577
1578template<typename _Tp> static inline
1579double norm(const Point3_<_Tp>& pt)
1580{
1581 return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z);
1582}
1583
1584template<typename _Tp> static inline
1585bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1586{
1587 return a.x == b.x && a.y == b.y && a.z == b.z;
1588}
1589
1590template<typename _Tp> static inline
1591bool operator != (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1592{
1593 return a.x != b.x || a.y != b.y || a.z != b.z;
1594}
1595
1596template<typename _Tp> static inline
1597Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1598{
1599 return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y), saturate_cast<_Tp>(a.z + b.z));
1600}
1601
1602template<typename _Tp> static inline
1603Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1604{
1605 return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y), saturate_cast<_Tp>(a.z - b.z));
1606}
1607
1608template<typename _Tp> static inline
1609Point3_<_Tp> operator - (const Point3_<_Tp>& a)
1610{
1611 return Point3_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y), saturate_cast<_Tp>(-a.z) );
1612}
1613
1614template<typename _Tp> static inline
1615Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b)
1616{
1617 return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b), saturate_cast<_Tp>(a.z*b) );
1618}
1619
1620template<typename _Tp> static inline
1621Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b)
1622{
1623 return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
1624}
1625
1626template<typename _Tp> static inline
1627Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b)
1628{
1629 return Point3_<_Tp>( saturate_cast<_Tp>(a.x * b), saturate_cast<_Tp>(a.y * b), saturate_cast<_Tp>(a.z * b) );
1630}
1631
1632template<typename _Tp> static inline
1633Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b)
1634{
1635 return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
1636}
1637
1638template<typename _Tp> static inline
1639Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b)
1640{
1641 return Point3_<_Tp>( saturate_cast<_Tp>(a.x * b), saturate_cast<_Tp>(a.y * b), saturate_cast<_Tp>(a.z * b) );
1642}
1643
1644template<typename _Tp> static inline
1645Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b)
1646{
1647 return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
1648}
1649
1650template<typename _Tp> static inline
1651Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b)
1652{
1653 Matx<_Tp, 3, 1> tmp = a * Vec<_Tp,3>(b.x, b.y, b.z);
1654 return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]);
1655}
1656
1657template<typename _Tp> static inline
1658Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
1659{
1660 return a * Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1);
1661}
1662
1663template<typename _Tp> static inline
1664Point3_<_Tp> operator / (const Point3_<_Tp>& a, int b)
1665{
1666 Point3_<_Tp> tmp(a);
1667 tmp /= b;
1668 return tmp;
1669}
1670
1671template<typename _Tp> static inline
1672Point3_<_Tp> operator / (const Point3_<_Tp>& a, float b)
1673{
1674 Point3_<_Tp> tmp(a);
1675 tmp /= b;
1676 return tmp;
1677}
1678
1679template<typename _Tp> static inline
1680Point3_<_Tp> operator / (const Point3_<_Tp>& a, double b)
1681{
1682 Point3_<_Tp> tmp(a);
1683 tmp /= b;
1684 return tmp;
1685}
1686
1687
1688
1689////////////////////////////////// Size /////////////////////////////////
1690
1691template<typename _Tp> inline
1692Size_<_Tp>::Size_()
1693 : width(0), height(0) {}
1694
1695template<typename _Tp> inline
1696Size_<_Tp>::Size_(_Tp _width, _Tp _height)
1697 : width(_width), height(_height) {}
1698
1699template<typename _Tp> inline
1700Size_<_Tp>::Size_(const Point_<_Tp>& pt)
1701 : width(pt.x), height(pt.y) {}
1702
1703template<typename _Tp> template<typename _Tp2> inline
1704Size_<_Tp>::operator Size_<_Tp2>() const
1705{
1706 return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height));
1707}
1708
1709template<typename _Tp> inline
1710_Tp Size_<_Tp>::area() const
1711{
1712 const _Tp result = width * height;
1713 CV_DbgAssert(!std::numeric_limits<_Tp>::is_integer
1714 || width == 0 || result / width == height); // make sure the result fits in the return value
1715 return result;
1716}
1717
1718template<typename _Tp> inline
1719double Size_<_Tp>::aspectRatio() const
1720{
1721 return width / static_cast<double>(height);
1722}
1723
1724template<typename _Tp> inline
1725bool Size_<_Tp>::empty() const
1726{
1727 return width <= 0 || height <= 0;
1728}
1729
1730
1731template<typename _Tp> static inline
1732Size_<_Tp>& operator *= (Size_<_Tp>& a, _Tp b)
1733{
1734 a.width *= b;
1735 a.height *= b;
1736 return a;
1737}
1738
1739template<typename _Tp> static inline
1740Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b)
1741{
1742 Size_<_Tp> tmp(a);
1743 tmp *= b;
1744 return tmp;
1745}
1746
1747template<typename _Tp> static inline
1748Size_<_Tp>& operator /= (Size_<_Tp>& a, _Tp b)
1749{
1750 a.width /= b;
1751 a.height /= b;
1752 return a;
1753}
1754
1755template<typename _Tp> static inline
1756Size_<_Tp> operator / (const Size_<_Tp>& a, _Tp b)
1757{
1758 Size_<_Tp> tmp(a);
1759 tmp /= b;
1760 return tmp;
1761}
1762
1763template<typename _Tp> static inline
1764Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b)
1765{
1766 a.width += b.width;
1767 a.height += b.height;
1768 return a;
1769}
1770
1771template<typename _Tp> static inline
1772Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b)
1773{
1774 Size_<_Tp> tmp(a);
1775 tmp += b;
1776 return tmp;
1777}
1778
1779template<typename _Tp> static inline
1780Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b)
1781{
1782 a.width -= b.width;
1783 a.height -= b.height;
1784 return a;
1785}
1786
1787template<typename _Tp> static inline
1788Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b)
1789{
1790 Size_<_Tp> tmp(a);
1791 tmp -= b;
1792 return tmp;
1793}
1794
1795template<typename _Tp> static inline
1796bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b)
1797{
1798 return a.width == b.width && a.height == b.height;
1799}
1800
1801template<typename _Tp> static inline
1802bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b)
1803{
1804 return !(a == b);
1805}
1806
1807
1808
1809////////////////////////////////// Rect /////////////////////////////////
1810
1811template<typename _Tp> inline
1812Rect_<_Tp>::Rect_()
1813 : x(0), y(0), width(0), height(0) {}
1814
1815template<typename _Tp> inline
1816Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height)
1817 : x(_x), y(_y), width(_width), height(_height) {}
1818
1819template<typename _Tp> inline
1820Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz)
1821 : x(org.x), y(org.y), width(sz.width), height(sz.height) {}
1822
1823template<typename _Tp> inline
1824Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)
1825{
1826 x = std::min(pt1.x, pt2.x);
1827 y = std::min(pt1.y, pt2.y);
1828 width = std::max(pt1.x, pt2.x) - x;
1829 height = std::max(pt1.y, pt2.y) - y;
1830}
1831
1832template<typename _Tp> inline
1833Point_<_Tp> Rect_<_Tp>::tl() const
1834{
1835 return Point_<_Tp>(x,y);
1836}
1837
1838template<typename _Tp> inline
1839Point_<_Tp> Rect_<_Tp>::br() const
1840{
1841 return Point_<_Tp>(x + width, y + height);
1842}
1843
1844template<typename _Tp> inline
1845Size_<_Tp> Rect_<_Tp>::size() const
1846{
1847 return Size_<_Tp>(width, height);
1848}
1849
1850template<typename _Tp> inline
1851_Tp Rect_<_Tp>::area() const
1852{
1853 const _Tp result = width * height;
1854 CV_DbgAssert(!std::numeric_limits<_Tp>::is_integer
1855 || width == 0 || result / width == height); // make sure the result fits in the return value
1856 return result;
1857}
1858
1859template<typename _Tp> inline
1860bool Rect_<_Tp>::empty() const
1861{
1862 return width <= 0 || height <= 0;
1863}
1864
1865template<typename _Tp> template<typename _Tp2> inline
1866Rect_<_Tp>::operator Rect_<_Tp2>() const
1867{
1868 return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height));
1869}
1870
1871template<typename _Tp> template<typename _Tp2> inline
1872bool Rect_<_Tp>::contains(const Point_<_Tp2>& pt) const
1873{
1874 return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height;
1875}
1876// See https://github.com/opencv/opencv/issues/26016
1877template<> template<> inline
1878bool Rect_<int>::contains(const Point_<double>& pt) const
1879{
1880 // std::numeric_limits<int>::digits is 31.
1881 // std::numeric_limits<double>::digits is 53.
1882 // So conversion int->double does not lead to accuracy errors.
1883 const Rect_<double> _rect(static_cast<double>(x), static_cast<double>(y), static_cast<double>(width), static_cast<double>(height));
1884 return _rect.contains(pt);
1885}
1886template<> template<> inline
1887bool Rect_<int>::contains(const Point_<float>& _pt) const
1888{
1889 // std::numeric_limits<float>::digits is 24.
1890 // std::numeric_limits<double>::digits is 53.
1891 // So conversion float->double does not lead to accuracy errors.
1892 return contains(pt: Point_<double>(static_cast<double>(_pt.x), static_cast<double>(_pt.y)));
1893}
1894
1895template<typename _Tp> static inline
1896Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b )
1897{
1898 a.x += b.x;
1899 a.y += b.y;
1900 return a;
1901}
1902
1903template<typename _Tp> static inline
1904Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b )
1905{
1906 a.x -= b.x;
1907 a.y -= b.y;
1908 return a;
1909}
1910
1911template<typename _Tp> static inline
1912Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b )
1913{
1914 a.width += b.width;
1915 a.height += b.height;
1916 return a;
1917}
1918
1919template<typename _Tp> static inline
1920Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b )
1921{
1922 const _Tp width = a.width - b.width;
1923 const _Tp height = a.height - b.height;
1924 CV_DbgAssert(width >= 0 && height >= 0);
1925 a.width = width;
1926 a.height = height;
1927 return a;
1928}
1929
1930template<typename _Tp> static inline
1931Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
1932{
1933 if (a.empty() || b.empty()) {
1934 a = Rect();
1935 return a;
1936 }
1937 const Rect_<_Tp>& Rx_min = (a.x < b.x) ? a : b;
1938 const Rect_<_Tp>& Rx_max = (a.x < b.x) ? b : a;
1939 const Rect_<_Tp>& Ry_min = (a.y < b.y) ? a : b;
1940 const Rect_<_Tp>& Ry_max = (a.y < b.y) ? b : a;
1941 // Looking at the formula below, we will compute Rx_min.width - (Rx_max.x - Rx_min.x)
1942 // but we want to avoid overflows. Rx_min.width >= 0 and (Rx_max.x - Rx_min.x) >= 0
1943 // by definition so the difference does not overflow. The only thing that can overflow
1944 // is (Rx_max.x - Rx_min.x). And it can only overflow if Rx_min.x < 0.
1945 // Let us first deal with the following case.
1946 if ((Rx_min.x < 0 && Rx_min.x + Rx_min.width < Rx_max.x) ||
1947 (Ry_min.y < 0 && Ry_min.y + Ry_min.height < Ry_max.y)) {
1948 a = Rect();
1949 return a;
1950 }
1951 // We now know that either Rx_min.x >= 0, or
1952 // Rx_min.x < 0 && Rx_min.x + Rx_min.width >= Rx_max.x and therefore
1953 // Rx_min.width >= (Rx_max.x - Rx_min.x) which means (Rx_max.x - Rx_min.x)
1954 // is inferior to a valid int and therefore does not overflow.
1955 a.width = std::min(Rx_min.width - (Rx_max.x - Rx_min.x), Rx_max.width);
1956 a.height = std::min(Ry_min.height - (Ry_max.y - Ry_min.y), Ry_max.height);
1957 a.x = Rx_max.x;
1958 a.y = Ry_max.y;
1959 if (a.empty())
1960 a = Rect();
1961 return a;
1962}
1963
1964template<typename _Tp> static inline
1965Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
1966{
1967 if (a.empty()) {
1968 a = b;
1969 }
1970 else if (!b.empty()) {
1971 _Tp x1 = std::min(a.x, b.x);
1972 _Tp y1 = std::min(a.y, b.y);
1973 a.width = std::max(a.x + a.width, b.x + b.width) - x1;
1974 a.height = std::max(a.y + a.height, b.y + b.height) - y1;
1975 a.x = x1;
1976 a.y = y1;
1977 }
1978 return a;
1979}
1980
1981template<typename _Tp> static inline
1982bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1983{
1984 return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
1985}
1986
1987template<typename _Tp> static inline
1988bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1989{
1990 return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height;
1991}
1992
1993template<typename _Tp> static inline
1994Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b)
1995{
1996 return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height );
1997}
1998
1999template<typename _Tp> static inline
2000Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b)
2001{
2002 return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height );
2003}
2004
2005template<typename _Tp> static inline
2006Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b)
2007{
2008 return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height );
2009}
2010
2011template<typename _Tp> static inline
2012Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Size_<_Tp>& b)
2013{
2014 const _Tp width = a.width - b.width;
2015 const _Tp height = a.height - b.height;
2016 CV_DbgAssert(width >= 0 && height >= 0);
2017 return Rect_<_Tp>( a.x, a.y, width, height );
2018}
2019
2020template<typename _Tp> static inline
2021Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
2022{
2023 Rect_<_Tp> c = a;
2024 return c &= b;
2025}
2026
2027template<typename _Tp> static inline
2028Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
2029{
2030 Rect_<_Tp> c = a;
2031 return c |= b;
2032}
2033
2034/**
2035 * @brief measure dissimilarity between two sample sets
2036 *
2037 * computes the complement of the Jaccard Index as described in <https://en.wikipedia.org/wiki/Jaccard_index>.
2038 * For rectangles this reduces to computing the intersection over the union.
2039 */
2040template<typename _Tp> static inline
2041double jaccardDistance(const Rect_<_Tp>& a, const Rect_<_Tp>& b) {
2042 _Tp Aa = a.area();
2043 _Tp Ab = b.area();
2044
2045 if ((Aa + Ab) <= std::numeric_limits<_Tp>::epsilon()) {
2046 // jaccard_index = 1 -> distance = 0
2047 return 0.0;
2048 }
2049
2050 double Aab = (a & b).area();
2051 // distance = 1 - jaccard_index
2052 return 1.0 - Aab / (Aa + Ab - Aab);
2053}
2054
2055/** @brief Finds out if there is any intersection between two rectangles
2056 *
2057 * mainly useful for language bindings
2058 * @param a First rectangle
2059 * @param b Second rectangle
2060 * @return the area of the intersection
2061 */
2062CV_EXPORTS_W inline double rectangleIntersectionArea(const Rect2d& a, const Rect2d& b) { return (a & b).area(); }
2063
2064////////////////////////////// RotatedRect //////////////////////////////
2065
2066inline
2067RotatedRect::RotatedRect()
2068 : center(), size(), angle(0) {}
2069
2070inline
2071RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
2072 : center(_center), size(_size), angle(_angle) {}
2073
2074///////////////////////////////// Range /////////////////////////////////
2075
2076inline
2077Range::Range()
2078 : start(0), end(0) {}
2079
2080inline
2081Range::Range(int _start, int _end)
2082 : start(_start), end(_end) {}
2083
2084inline
2085int Range::size() const
2086{
2087 return end - start;
2088}
2089
2090inline
2091bool Range::empty() const
2092{
2093 return start == end;
2094}
2095
2096inline
2097Range Range::all()
2098{
2099 return Range(INT_MIN, INT_MAX);
2100}
2101
2102
2103static inline
2104bool operator == (const Range& r1, const Range& r2)
2105{
2106 return r1.start == r2.start && r1.end == r2.end;
2107}
2108
2109static inline
2110bool operator != (const Range& r1, const Range& r2)
2111{
2112 return !(r1 == r2);
2113}
2114
2115static inline
2116bool operator !(const Range& r)
2117{
2118 return r.start == r.end;
2119}
2120
2121static inline
2122Range operator & (const Range& r1, const Range& r2)
2123{
2124 Range r(std::max(a: r1.start, b: r2.start), std::min(a: r1.end, b: r2.end));
2125 r.end = std::max(a: r.end, b: r.start);
2126 return r;
2127}
2128
2129static inline
2130Range& operator &= (Range& r1, const Range& r2)
2131{
2132 r1 = r1 & r2;
2133 return r1;
2134}
2135
2136static inline
2137Range operator + (const Range& r1, int delta)
2138{
2139 return Range(r1.start + delta, r1.end + delta);
2140}
2141
2142static inline
2143Range operator + (int delta, const Range& r1)
2144{
2145 return Range(r1.start + delta, r1.end + delta);
2146}
2147
2148static inline
2149Range operator - (const Range& r1, int delta)
2150{
2151 return r1 + (-delta);
2152}
2153
2154
2155
2156///////////////////////////////// Scalar ////////////////////////////////
2157
2158template<typename _Tp> inline
2159Scalar_<_Tp>::Scalar_()
2160{
2161 this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0;
2162}
2163
2164template<typename _Tp> inline
2165Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
2166{
2167 this->val[0] = v0;
2168 this->val[1] = v1;
2169 this->val[2] = v2;
2170 this->val[3] = v3;
2171}
2172
2173template<typename _Tp> inline
2174Scalar_<_Tp>::Scalar_(const Scalar_<_Tp>& s) : Vec<_Tp, 4>(s) {
2175}
2176
2177template<typename _Tp> inline
2178Scalar_<_Tp>::Scalar_(Scalar_<_Tp>&& s) CV_NOEXCEPT {
2179 this->val[0] = std::move(s.val[0]);
2180 this->val[1] = std::move(s.val[1]);
2181 this->val[2] = std::move(s.val[2]);
2182 this->val[3] = std::move(s.val[3]);
2183}
2184
2185template<typename _Tp> inline
2186Scalar_<_Tp>& Scalar_<_Tp>::operator=(const Scalar_<_Tp>& s) {
2187 this->val[0] = s.val[0];
2188 this->val[1] = s.val[1];
2189 this->val[2] = s.val[2];
2190 this->val[3] = s.val[3];
2191 return *this;
2192}
2193
2194template<typename _Tp> inline
2195Scalar_<_Tp>& Scalar_<_Tp>::operator=(Scalar_<_Tp>&& s) CV_NOEXCEPT {
2196 this->val[0] = std::move(s.val[0]);
2197 this->val[1] = std::move(s.val[1]);
2198 this->val[2] = std::move(s.val[2]);
2199 this->val[3] = std::move(s.val[3]);
2200 return *this;
2201}
2202
2203template<typename _Tp> template<typename _Tp2, int cn> inline
2204Scalar_<_Tp>::Scalar_(const Vec<_Tp2, cn>& v)
2205{
2206 int i;
2207 for( i = 0; i < (cn < 4 ? cn : 4); i++ )
2208 this->val[i] = cv::saturate_cast<_Tp>(v.val[i]);
2209 for( ; i < 4; i++ )
2210 this->val[i] = 0;
2211}
2212
2213template<typename _Tp> inline
2214Scalar_<_Tp>::Scalar_(_Tp v0)
2215{
2216 this->val[0] = v0;
2217 this->val[1] = this->val[2] = this->val[3] = 0;
2218}
2219
2220template<typename _Tp> inline
2221Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0)
2222{
2223 return Scalar_<_Tp>(v0, v0, v0, v0);
2224}
2225
2226
2227template<typename _Tp> inline
2228Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& a, double scale ) const
2229{
2230 return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0] * a.val[0] * scale),
2231 saturate_cast<_Tp>(this->val[1] * a.val[1] * scale),
2232 saturate_cast<_Tp>(this->val[2] * a.val[2] * scale),
2233 saturate_cast<_Tp>(this->val[3] * a.val[3] * scale));
2234}
2235
2236template<typename _Tp> inline
2237Scalar_<_Tp> Scalar_<_Tp>::conj() const
2238{
2239 return Scalar_<_Tp>(saturate_cast<_Tp>( this->val[0]),
2240 saturate_cast<_Tp>(-this->val[1]),
2241 saturate_cast<_Tp>(-this->val[2]),
2242 saturate_cast<_Tp>(-this->val[3]));
2243}
2244
2245template<typename _Tp> inline
2246bool Scalar_<_Tp>::isReal() const
2247{
2248 return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0;
2249}
2250
2251
2252template<typename _Tp> template<typename T2> inline
2253Scalar_<_Tp>::operator Scalar_<T2>() const
2254{
2255 return Scalar_<T2>(saturate_cast<T2>(this->val[0]),
2256 saturate_cast<T2>(this->val[1]),
2257 saturate_cast<T2>(this->val[2]),
2258 saturate_cast<T2>(this->val[3]));
2259}
2260
2261
2262template<typename _Tp> static inline
2263Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
2264{
2265 a.val[0] += b.val[0];
2266 a.val[1] += b.val[1];
2267 a.val[2] += b.val[2];
2268 a.val[3] += b.val[3];
2269 return a;
2270}
2271
2272template<typename _Tp> static inline
2273Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
2274{
2275 a.val[0] -= b.val[0];
2276 a.val[1] -= b.val[1];
2277 a.val[2] -= b.val[2];
2278 a.val[3] -= b.val[3];
2279 return a;
2280}
2281
2282template<typename _Tp> static inline
2283Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v )
2284{
2285 a.val[0] *= v;
2286 a.val[1] *= v;
2287 a.val[2] *= v;
2288 a.val[3] *= v;
2289 return a;
2290}
2291
2292template<typename _Tp> static inline
2293bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
2294{
2295 return a.val[0] == b.val[0] && a.val[1] == b.val[1] &&
2296 a.val[2] == b.val[2] && a.val[3] == b.val[3];
2297}
2298
2299template<typename _Tp> static inline
2300bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
2301{
2302 return a.val[0] != b.val[0] || a.val[1] != b.val[1] ||
2303 a.val[2] != b.val[2] || a.val[3] != b.val[3];
2304}
2305
2306template<typename _Tp> static inline
2307Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
2308{
2309 return Scalar_<_Tp>(a.val[0] + b.val[0],
2310 a.val[1] + b.val[1],
2311 a.val[2] + b.val[2],
2312 a.val[3] + b.val[3]);
2313}
2314
2315template<typename _Tp> static inline
2316Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
2317{
2318 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]),
2319 saturate_cast<_Tp>(a.val[1] - b.val[1]),
2320 saturate_cast<_Tp>(a.val[2] - b.val[2]),
2321 saturate_cast<_Tp>(a.val[3] - b.val[3]));
2322}
2323
2324template<typename _Tp> static inline
2325Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha)
2326{
2327 return Scalar_<_Tp>(a.val[0] * alpha,
2328 a.val[1] * alpha,
2329 a.val[2] * alpha,
2330 a.val[3] * alpha);
2331}
2332
2333template<typename _Tp> static inline
2334Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a)
2335{
2336 return a*alpha;
2337}
2338
2339template<typename _Tp> static inline
2340Scalar_<_Tp> operator - (const Scalar_<_Tp>& a)
2341{
2342 return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]),
2343 saturate_cast<_Tp>(-a.val[1]),
2344 saturate_cast<_Tp>(-a.val[2]),
2345 saturate_cast<_Tp>(-a.val[3]));
2346}
2347
2348
2349template<typename _Tp> static inline
2350Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
2351{
2352 return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]),
2353 saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]),
2354 saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1]),
2355 saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0]));
2356}
2357
2358template<typename _Tp> static inline
2359Scalar_<_Tp>& operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
2360{
2361 a = a * b;
2362 return a;
2363}
2364
2365template<typename _Tp> static inline
2366Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha)
2367{
2368 return Scalar_<_Tp>(a.val[0] / alpha,
2369 a.val[1] / alpha,
2370 a.val[2] / alpha,
2371 a.val[3] / alpha);
2372}
2373
2374template<typename _Tp> static inline
2375Scalar_<float> operator / (const Scalar_<float>& a, float alpha)
2376{
2377 float s = 1 / alpha;
2378 return Scalar_<float>(a.val[0] * s, a.val[1] * s, a.val[2] * s, a.val[3] * s);
2379}
2380
2381template<typename _Tp> static inline
2382Scalar_<double> operator / (const Scalar_<double>& a, double alpha)
2383{
2384 double s = 1 / alpha;
2385 return Scalar_<double>(a.val[0] * s, a.val[1] * s, a.val[2] * s, a.val[3] * s);
2386}
2387
2388template<typename _Tp> static inline
2389Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha)
2390{
2391 a = a / alpha;
2392 return a;
2393}
2394
2395template<typename _Tp> static inline
2396Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b)
2397{
2398 _Tp s = a / (b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]);
2399 return b.conj() * s;
2400}
2401
2402template<typename _Tp> static inline
2403Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
2404{
2405 return a * ((_Tp)1 / b);
2406}
2407
2408template<typename _Tp> static inline
2409Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
2410{
2411 a = a / b;
2412 return a;
2413}
2414
2415template<typename _Tp> static inline
2416Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
2417{
2418 Matx<double, 4, 1> c((Matx<double, 4, 4>)a, b, Matx_MatMulOp());
2419 return reinterpret_cast<const Scalar&>(c);
2420}
2421
2422template<> inline
2423Scalar operator * (const Matx<double, 4, 4>& a, const Scalar& b)
2424{
2425 Matx<double, 4, 1> c(a, b, Matx_MatMulOp());
2426 return reinterpret_cast<const Scalar&>(c);
2427}
2428
2429
2430
2431//////////////////////////////// KeyPoint ///////////////////////////////
2432
2433inline
2434KeyPoint::KeyPoint()
2435 : pt(0,0), size(0), angle(-1), response(0), octave(0), class_id(-1) {}
2436
2437inline
2438KeyPoint::KeyPoint(Point2f _pt, float _size, float _angle, float _response, int _octave, int _class_id)
2439 : pt(_pt), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {}
2440
2441inline
2442KeyPoint::KeyPoint(float x, float y, float _size, float _angle, float _response, int _octave, int _class_id)
2443 : pt(x, y), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {}
2444
2445
2446
2447///////////////////////////////// DMatch ////////////////////////////////
2448
2449inline
2450DMatch::DMatch()
2451 : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(FLT_MAX) {}
2452
2453inline
2454DMatch::DMatch(int _queryIdx, int _trainIdx, float _distance)
2455 : queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {}
2456
2457inline
2458DMatch::DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance)
2459 : queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {}
2460
2461inline
2462bool DMatch::operator < (const DMatch &m) const
2463{
2464 return distance < m.distance;
2465}
2466
2467
2468
2469////////////////////////////// TermCriteria /////////////////////////////
2470
2471inline
2472TermCriteria::TermCriteria()
2473 : type(0), maxCount(0), epsilon(0) {}
2474
2475inline
2476TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
2477 : type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
2478
2479//! @endcond
2480
2481} // cv
2482
2483#ifdef _MSC_VER
2484#pragma warning(pop)
2485#endif
2486
2487#endif //OPENCV_CORE_TYPES_HPP
2488

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of opencv/modules/core/include/opencv2/core/types.hpp