2392 lines
68 KiB
C++
2392 lines
68 KiB
C++
/*M///////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
|
//
|
|
// By downloading, copying, installing or using the software you agree to this license.
|
|
// If you do not agree to this license, do not download, install,
|
|
// copy or use the software.
|
|
//
|
|
//
|
|
// License Agreement
|
|
// For Open Source Computer Vision Library
|
|
//
|
|
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
|
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
|
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
|
// Third party copyrights are property of their respective owners.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
// are permitted provided that the following conditions are met:
|
|
//
|
|
// * Redistribution's of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
//
|
|
// * Redistribution's in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
//
|
|
// * The name of the copyright holders may not be used to endorse or promote products
|
|
// derived from this software without specific prior written permission.
|
|
//
|
|
// This software is provided by the copyright holders and contributors "as is" and
|
|
// any express or implied warranties, including, but not limited to, the implied
|
|
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
|
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
|
// indirect, incidental, special, exemplary, or consequential damages
|
|
// (including, but not limited to, procurement of substitute goods or services;
|
|
// loss of use, data, or profits; or business interruption) however caused
|
|
// and on any theory of liability, whether in contract, strict liability,
|
|
// or tort (including negligence or otherwise) arising in any way out of
|
|
// the use of this software, even if advised of the possibility of such damage.
|
|
//
|
|
//M*/
|
|
|
|
#ifndef OPENCV_CORE_TYPES_HPP
|
|
#define OPENCV_CORE_TYPES_HPP
|
|
|
|
#ifndef __cplusplus
|
|
# error types.hpp header must be compiled as C++
|
|
#endif
|
|
|
|
#include <climits>
|
|
#include <cfloat>
|
|
#include <vector>
|
|
#include <limits>
|
|
|
|
#include "opencv2/core/cvdef.h"
|
|
#include "opencv2/core/cvstd.hpp"
|
|
#include "opencv2/core/matx.hpp"
|
|
|
|
namespace cv
|
|
{
|
|
|
|
//! @addtogroup core_basic
|
|
//! @{
|
|
|
|
//////////////////////////////// Complex //////////////////////////////
|
|
|
|
/** @brief A complex number class.
|
|
|
|
The template class is similar and compatible with std::complex, however it provides slightly
|
|
more convenient access to the real and imaginary parts using through the simple field access, as opposite
|
|
to std::complex::real() and std::complex::imag().
|
|
*/
|
|
template<typename _Tp> class Complex
|
|
{
|
|
public:
|
|
|
|
//! default constructor
|
|
Complex();
|
|
Complex( _Tp _re, _Tp _im = 0 );
|
|
|
|
//! conversion to another data type
|
|
template<typename T2> operator Complex<T2>() const;
|
|
//! conjugation
|
|
Complex conj() const;
|
|
|
|
_Tp re, im; //< the real and the imaginary parts
|
|
};
|
|
|
|
typedef Complex<float> Complexf;
|
|
typedef Complex<double> Complexd;
|
|
|
|
template<typename _Tp> class DataType< Complex<_Tp> >
|
|
{
|
|
public:
|
|
typedef Complex<_Tp> value_type;
|
|
typedef value_type work_type;
|
|
typedef _Tp channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = 2,
|
|
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<typename _Tp>
|
|
struct Depth< Complex<_Tp> > { enum { value = Depth<_Tp>::value }; };
|
|
template<typename _Tp>
|
|
struct Type< Complex<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; };
|
|
} // namespace
|
|
|
|
|
|
//////////////////////////////// Point_ ////////////////////////////////
|
|
|
|
/** @brief Template class for 2D points specified by its coordinates `x` and `y`.
|
|
|
|
An instance of the class is interchangeable with C structures, CvPoint and CvPoint2D32f . There is
|
|
also a cast operator to convert point coordinates to the specified type. The conversion from
|
|
floating-point coordinates to integer coordinates is done by rounding. Commonly, the conversion
|
|
uses this operation for each of the coordinates. Besides the class members listed in the
|
|
declaration above, the following operations on points are implemented:
|
|
@code
|
|
pt1 = pt2 + pt3;
|
|
pt1 = pt2 - pt3;
|
|
pt1 = pt2 * a;
|
|
pt1 = a * pt2;
|
|
pt1 = pt2 / a;
|
|
pt1 += pt2;
|
|
pt1 -= pt2;
|
|
pt1 *= a;
|
|
pt1 /= a;
|
|
double value = norm(pt); // L2 norm
|
|
pt1 == pt2;
|
|
pt1 != pt2;
|
|
@endcode
|
|
For your convenience, the following type aliases are defined:
|
|
@code
|
|
typedef Point_<int> Point2i;
|
|
typedef Point2i Point;
|
|
typedef Point_<float> Point2f;
|
|
typedef Point_<double> Point2d;
|
|
@endcode
|
|
Example:
|
|
@code
|
|
Point2f a(0.3f, 0.f), b(0.f, 0.4f);
|
|
Point pt = (a + b)*10.f;
|
|
cout << pt.x << ", " << pt.y << endl;
|
|
@endcode
|
|
*/
|
|
template<typename _Tp> class Point_
|
|
{
|
|
public:
|
|
typedef _Tp value_type;
|
|
|
|
//! default constructor
|
|
Point_();
|
|
Point_(_Tp _x, _Tp _y);
|
|
Point_(const Point_& pt);
|
|
Point_(const Size_<_Tp>& sz);
|
|
Point_(const Vec<_Tp, 2>& v);
|
|
|
|
Point_& operator = (const Point_& pt);
|
|
//! conversion to another data type
|
|
template<typename _Tp2> operator Point_<_Tp2>() const;
|
|
|
|
//! conversion to the old-style C structures
|
|
operator Vec<_Tp, 2>() const;
|
|
|
|
//! dot product
|
|
_Tp dot(const Point_& pt) const;
|
|
//! dot product computed in double-precision arithmetics
|
|
double ddot(const Point_& pt) const;
|
|
//! cross-product
|
|
double cross(const Point_& pt) const;
|
|
//! checks whether the point is inside the specified rectangle
|
|
bool inside(const Rect_<_Tp>& r) const;
|
|
_Tp x; //!< x coordinate of the point
|
|
_Tp y; //!< y coordinate of the point
|
|
};
|
|
|
|
typedef Point_<int> Point2i;
|
|
typedef Point_<int64> Point2l;
|
|
typedef Point_<float> Point2f;
|
|
typedef Point_<double> Point2d;
|
|
typedef Point2i Point;
|
|
|
|
template<typename _Tp> class DataType< Point_<_Tp> >
|
|
{
|
|
public:
|
|
typedef Point_<_Tp> value_type;
|
|
typedef Point_<typename DataType<_Tp>::work_type> work_type;
|
|
typedef _Tp channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = 2,
|
|
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<typename _Tp>
|
|
struct Depth< Point_<_Tp> > { enum { value = Depth<_Tp>::value }; };
|
|
template<typename _Tp>
|
|
struct Type< Point_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; };
|
|
} // namespace
|
|
|
|
|
|
//////////////////////////////// Point3_ ////////////////////////////////
|
|
|
|
/** @brief Template class for 3D points specified by its coordinates `x`, `y` and `z`.
|
|
|
|
An instance of the class is interchangeable with the C structure CvPoint2D32f . Similarly to
|
|
Point_ , the coordinates of 3D points can be converted to another type. The vector arithmetic and
|
|
comparison operations are also supported.
|
|
|
|
The following Point3_\<\> aliases are available:
|
|
@code
|
|
typedef Point3_<int> Point3i;
|
|
typedef Point3_<float> Point3f;
|
|
typedef Point3_<double> Point3d;
|
|
@endcode
|
|
@see cv::Point3i, cv::Point3f and cv::Point3d
|
|
*/
|
|
template<typename _Tp> class Point3_
|
|
{
|
|
public:
|
|
typedef _Tp value_type;
|
|
|
|
//! default constructor
|
|
Point3_();
|
|
Point3_(_Tp _x, _Tp _y, _Tp _z);
|
|
Point3_(const Point3_& pt);
|
|
explicit Point3_(const Point_<_Tp>& pt);
|
|
Point3_(const Vec<_Tp, 3>& v);
|
|
|
|
Point3_& operator = (const Point3_& pt);
|
|
//! conversion to another data type
|
|
template<typename _Tp2> operator Point3_<_Tp2>() const;
|
|
//! conversion to cv::Vec<>
|
|
#if OPENCV_ABI_COMPATIBILITY > 300
|
|
template<typename _Tp2> operator Vec<_Tp2, 3>() const;
|
|
#else
|
|
operator Vec<_Tp, 3>() const;
|
|
#endif
|
|
|
|
//! dot product
|
|
_Tp dot(const Point3_& pt) const;
|
|
//! dot product computed in double-precision arithmetics
|
|
double ddot(const Point3_& pt) const;
|
|
//! cross product of the 2 3D points
|
|
Point3_ cross(const Point3_& pt) const;
|
|
_Tp x; //!< x coordinate of the 3D point
|
|
_Tp y; //!< y coordinate of the 3D point
|
|
_Tp z; //!< z coordinate of the 3D point
|
|
};
|
|
|
|
typedef Point3_<int> Point3i;
|
|
typedef Point3_<float> Point3f;
|
|
typedef Point3_<double> Point3d;
|
|
|
|
template<typename _Tp> class DataType< Point3_<_Tp> >
|
|
{
|
|
public:
|
|
typedef Point3_<_Tp> value_type;
|
|
typedef Point3_<typename DataType<_Tp>::work_type> work_type;
|
|
typedef _Tp channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = 3,
|
|
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<typename _Tp>
|
|
struct Depth< Point3_<_Tp> > { enum { value = Depth<_Tp>::value }; };
|
|
template<typename _Tp>
|
|
struct Type< Point3_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 3) }; };
|
|
} // namespace
|
|
|
|
//////////////////////////////// Size_ ////////////////////////////////
|
|
|
|
/** @brief Template class for specifying the size of an image or rectangle.
|
|
|
|
The class includes two members called width and height. The structure can be converted to and from
|
|
the old OpenCV structures CvSize and CvSize2D32f . The same set of arithmetic and comparison
|
|
operations as for Point_ is available.
|
|
|
|
OpenCV defines the following Size_\<\> aliases:
|
|
@code
|
|
typedef Size_<int> Size2i;
|
|
typedef Size2i Size;
|
|
typedef Size_<float> Size2f;
|
|
@endcode
|
|
*/
|
|
template<typename _Tp> class Size_
|
|
{
|
|
public:
|
|
typedef _Tp value_type;
|
|
|
|
//! default constructor
|
|
Size_();
|
|
Size_(_Tp _width, _Tp _height);
|
|
Size_(const Size_& sz);
|
|
Size_(const Point_<_Tp>& pt);
|
|
|
|
Size_& operator = (const Size_& sz);
|
|
//! the area (width*height)
|
|
_Tp area() const;
|
|
//! true if empty
|
|
bool empty() const;
|
|
|
|
//! conversion of another data type.
|
|
template<typename _Tp2> operator Size_<_Tp2>() const;
|
|
|
|
_Tp width; //!< the width
|
|
_Tp height; //!< the height
|
|
};
|
|
|
|
typedef Size_<int> Size2i;
|
|
typedef Size_<int64> Size2l;
|
|
typedef Size_<float> Size2f;
|
|
typedef Size_<double> Size2d;
|
|
typedef Size2i Size;
|
|
|
|
template<typename _Tp> class DataType< Size_<_Tp> >
|
|
{
|
|
public:
|
|
typedef Size_<_Tp> value_type;
|
|
typedef Size_<typename DataType<_Tp>::work_type> work_type;
|
|
typedef _Tp channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = 2,
|
|
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<typename _Tp>
|
|
struct Depth< Size_<_Tp> > { enum { value = Depth<_Tp>::value }; };
|
|
template<typename _Tp>
|
|
struct Type< Size_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; };
|
|
} // namespace
|
|
|
|
//////////////////////////////// Rect_ ////////////////////////////////
|
|
|
|
/** @brief Template class for 2D rectangles
|
|
|
|
described by the following parameters:
|
|
- Coordinates of the top-left corner. This is a default interpretation of Rect_::x and Rect_::y
|
|
in OpenCV. Though, in your algorithms you may count x and y from the bottom-left corner.
|
|
- Rectangle width and height.
|
|
|
|
OpenCV typically assumes that the top and left boundary of the rectangle are inclusive, while the
|
|
right and bottom boundaries are not. For example, the method Rect_::contains returns true if
|
|
|
|
\f[x \leq pt.x < x+width,
|
|
y \leq pt.y < y+height\f]
|
|
|
|
Virtually every loop over an image ROI in OpenCV (where ROI is specified by Rect_\<int\> ) is
|
|
implemented as:
|
|
@code
|
|
for(int y = roi.y; y < roi.y + roi.height; y++)
|
|
for(int x = roi.x; x < roi.x + roi.width; x++)
|
|
{
|
|
// ...
|
|
}
|
|
@endcode
|
|
In addition to the class members, the following operations on rectangles are implemented:
|
|
- \f$\texttt{rect} = \texttt{rect} \pm \texttt{point}\f$ (shifting a rectangle by a certain offset)
|
|
- \f$\texttt{rect} = \texttt{rect} \pm \texttt{size}\f$ (expanding or shrinking a rectangle by a
|
|
certain amount)
|
|
- rect += point, rect -= point, rect += size, rect -= size (augmenting operations)
|
|
- rect = rect1 & rect2 (rectangle intersection)
|
|
- rect = rect1 | rect2 (minimum area rectangle containing rect1 and rect2 )
|
|
- rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
|
|
- rect == rect1, rect != rect1 (rectangle comparison)
|
|
|
|
This is an example how the partial ordering on rectangles can be established (rect1 \f$\subseteq\f$
|
|
rect2):
|
|
@code
|
|
template<typename _Tp> inline bool
|
|
operator <= (const Rect_<_Tp>& r1, const Rect_<_Tp>& r2)
|
|
{
|
|
return (r1 & r2) == r1;
|
|
}
|
|
@endcode
|
|
For your convenience, the Rect_\<\> alias is available: cv::Rect
|
|
*/
|
|
template<typename _Tp> class Rect_
|
|
{
|
|
public:
|
|
typedef _Tp value_type;
|
|
|
|
//! default constructor
|
|
Rect_();
|
|
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
|
|
Rect_(const Rect_& r);
|
|
Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
|
|
Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
|
|
|
|
Rect_& operator = ( const Rect_& r );
|
|
//! the top-left corner
|
|
Point_<_Tp> tl() const;
|
|
//! the bottom-right corner
|
|
Point_<_Tp> br() const;
|
|
|
|
//! size (width, height) of the rectangle
|
|
Size_<_Tp> size() const;
|
|
//! area (width*height) of the rectangle
|
|
_Tp area() const;
|
|
//! true if empty
|
|
bool empty() const;
|
|
|
|
//! conversion to another data type
|
|
template<typename _Tp2> operator Rect_<_Tp2>() const;
|
|
|
|
//! checks whether the rectangle contains the point
|
|
bool contains(const Point_<_Tp>& pt) const;
|
|
|
|
_Tp x; //!< x coordinate of the top-left corner
|
|
_Tp y; //!< y coordinate of the top-left corner
|
|
_Tp width; //!< width of the rectangle
|
|
_Tp height; //!< height of the rectangle
|
|
};
|
|
|
|
typedef Rect_<int> Rect2i;
|
|
typedef Rect_<float> Rect2f;
|
|
typedef Rect_<double> Rect2d;
|
|
typedef Rect2i Rect;
|
|
|
|
template<typename _Tp> class DataType< Rect_<_Tp> >
|
|
{
|
|
public:
|
|
typedef Rect_<_Tp> value_type;
|
|
typedef Rect_<typename DataType<_Tp>::work_type> work_type;
|
|
typedef _Tp channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = 4,
|
|
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<typename _Tp>
|
|
struct Depth< Rect_<_Tp> > { enum { value = Depth<_Tp>::value }; };
|
|
template<typename _Tp>
|
|
struct Type< Rect_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 4) }; };
|
|
} // namespace
|
|
|
|
///////////////////////////// RotatedRect /////////////////////////////
|
|
|
|
/** @brief The class represents rotated (i.e. not up-right) rectangles on a plane.
|
|
|
|
Each rectangle is specified by the center point (mass center), length of each side (represented by
|
|
#Size2f structure) and the rotation angle in degrees.
|
|
|
|
The sample below demonstrates how to use RotatedRect:
|
|
@snippet snippets/core_various.cpp RotatedRect_demo
|
|
![image](pics/rotatedrect.png)
|
|
|
|
@sa CamShift, fitEllipse, minAreaRect, CvBox2D
|
|
*/
|
|
class CV_EXPORTS RotatedRect
|
|
{
|
|
public:
|
|
//! default constructor
|
|
RotatedRect();
|
|
/** full constructor
|
|
@param center The rectangle mass center.
|
|
@param size Width and height of the rectangle.
|
|
@param angle The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc.,
|
|
the rectangle becomes an up-right rectangle.
|
|
*/
|
|
RotatedRect(const Point2f& center, const Size2f& size, float angle);
|
|
/**
|
|
Any 3 end points of the RotatedRect. They must be given in order (either clockwise or
|
|
anticlockwise).
|
|
*/
|
|
RotatedRect(const Point2f& point1, const Point2f& point2, const Point2f& point3);
|
|
|
|
/** returns 4 vertices of the rectangle
|
|
@param pts The points array for storing rectangle vertices. The order is bottomLeft, topLeft, topRight, bottomRight.
|
|
*/
|
|
void points(Point2f pts[]) const;
|
|
//! returns the minimal up-right integer rectangle containing the rotated rectangle
|
|
Rect boundingRect() const;
|
|
//! returns the minimal (exact) floating point rectangle containing the rotated rectangle, not intended for use with images
|
|
Rect_<float> boundingRect2f() const;
|
|
//! returns the rectangle mass center
|
|
Point2f center;
|
|
//! returns width and height of the rectangle
|
|
Size2f size;
|
|
//! returns the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
|
|
float angle;
|
|
};
|
|
|
|
template<> class DataType< RotatedRect >
|
|
{
|
|
public:
|
|
typedef RotatedRect value_type;
|
|
typedef value_type work_type;
|
|
typedef float channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = (int)sizeof(value_type)/sizeof(channel_type), // 5
|
|
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<>
|
|
struct Depth< RotatedRect > { enum { value = Depth<float>::value }; };
|
|
template<>
|
|
struct Type< RotatedRect > { enum { value = CV_MAKETYPE(Depth<float>::value, (int)sizeof(RotatedRect)/sizeof(float)) }; };
|
|
} // namespace
|
|
|
|
|
|
//////////////////////////////// Range /////////////////////////////////
|
|
|
|
/** @brief Template class specifying a continuous subsequence (slice) of a sequence.
|
|
|
|
The class is used to specify a row or a column span in a matrix ( Mat ) and for many other purposes.
|
|
Range(a,b) is basically the same as a:b in Matlab or a..b in Python. As in Python, start is an
|
|
inclusive left boundary of the range and end is an exclusive right boundary of the range. Such a
|
|
half-opened interval is usually denoted as \f$[start,end)\f$ .
|
|
|
|
The static method Range::all() returns a special variable that means "the whole sequence" or "the
|
|
whole range", just like " : " in Matlab or " ... " in Python. All the methods and functions in
|
|
OpenCV that take Range support this special Range::all() value. But, of course, in case of your own
|
|
custom processing, you will probably have to check and handle it explicitly:
|
|
@code
|
|
void my_function(..., const Range& r, ....)
|
|
{
|
|
if(r == Range::all()) {
|
|
// process all the data
|
|
}
|
|
else {
|
|
// process [r.start, r.end)
|
|
}
|
|
}
|
|
@endcode
|
|
*/
|
|
class CV_EXPORTS Range
|
|
{
|
|
public:
|
|
Range();
|
|
Range(int _start, int _end);
|
|
int size() const;
|
|
bool empty() const;
|
|
static Range all();
|
|
|
|
int start, end;
|
|
};
|
|
|
|
template<> class DataType<Range>
|
|
{
|
|
public:
|
|
typedef Range value_type;
|
|
typedef value_type work_type;
|
|
typedef int channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = 2,
|
|
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<>
|
|
struct Depth< Range > { enum { value = Depth<int>::value }; };
|
|
template<>
|
|
struct Type< Range > { enum { value = CV_MAKETYPE(Depth<int>::value, 2) }; };
|
|
} // namespace
|
|
|
|
|
|
//////////////////////////////// Scalar_ ///////////////////////////////
|
|
|
|
/** @brief Template class for a 4-element vector derived from Vec.
|
|
|
|
Being derived from Vec\<_Tp, 4\> , Scalar\_ and Scalar can be used just as typical 4-element
|
|
vectors. In addition, they can be converted to/from CvScalar . The type Scalar is widely used in
|
|
OpenCV to pass pixel values.
|
|
*/
|
|
template<typename _Tp> class Scalar_ : public Vec<_Tp, 4>
|
|
{
|
|
public:
|
|
//! default constructor
|
|
Scalar_();
|
|
Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
|
|
Scalar_(_Tp v0);
|
|
|
|
template<typename _Tp2, int cn>
|
|
Scalar_(const Vec<_Tp2, cn>& v);
|
|
|
|
//! returns a scalar with all elements set to v0
|
|
static Scalar_<_Tp> all(_Tp v0);
|
|
|
|
//! conversion to another data type
|
|
template<typename T2> operator Scalar_<T2>() const;
|
|
|
|
//! per-element product
|
|
Scalar_<_Tp> mul(const Scalar_<_Tp>& a, double scale=1 ) const;
|
|
|
|
//! returns (v0, -v1, -v2, -v3)
|
|
Scalar_<_Tp> conj() const;
|
|
|
|
//! returns true iff v1 == v2 == v3 == 0
|
|
bool isReal() const;
|
|
};
|
|
|
|
typedef Scalar_<double> Scalar;
|
|
|
|
template<typename _Tp> class DataType< Scalar_<_Tp> >
|
|
{
|
|
public:
|
|
typedef Scalar_<_Tp> value_type;
|
|
typedef Scalar_<typename DataType<_Tp>::work_type> work_type;
|
|
typedef _Tp channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = 4,
|
|
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<typename _Tp>
|
|
struct Depth< Scalar_<_Tp> > { enum { value = Depth<_Tp>::value }; };
|
|
template<typename _Tp>
|
|
struct Type< Scalar_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 4) }; };
|
|
} // namespace
|
|
|
|
|
|
/////////////////////////////// KeyPoint ////////////////////////////////
|
|
|
|
/** @brief Data structure for salient point detectors.
|
|
|
|
The class instance stores a keypoint, i.e. a point feature found by one of many available keypoint
|
|
detectors, such as Harris corner detector, #FAST, %StarDetector, %SURF, %SIFT etc.
|
|
|
|
The keypoint is characterized by the 2D position, scale (proportional to the diameter of the
|
|
neighborhood that needs to be taken into account), orientation and some other parameters. The
|
|
keypoint neighborhood is then analyzed by another algorithm that builds a descriptor (usually
|
|
represented as a feature vector). The keypoints representing the same object in different images
|
|
can then be matched using %KDTree or another method.
|
|
*/
|
|
class CV_EXPORTS_W_SIMPLE KeyPoint
|
|
{
|
|
public:
|
|
//! the default constructor
|
|
CV_WRAP KeyPoint();
|
|
/**
|
|
@param _pt x & y coordinates of the keypoint
|
|
@param _size keypoint diameter
|
|
@param _angle keypoint orientation
|
|
@param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
|
@param _octave pyramid octave in which the keypoint has been detected
|
|
@param _class_id object id
|
|
*/
|
|
KeyPoint(Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
|
|
/**
|
|
@param x x-coordinate of the keypoint
|
|
@param y y-coordinate of the keypoint
|
|
@param _size keypoint diameter
|
|
@param _angle keypoint orientation
|
|
@param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
|
@param _octave pyramid octave in which the keypoint has been detected
|
|
@param _class_id object id
|
|
*/
|
|
CV_WRAP KeyPoint(float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
|
|
|
|
size_t hash() const;
|
|
|
|
/**
|
|
This method converts vector of keypoints to vector of points or the reverse, where each keypoint is
|
|
assigned the same size and the same orientation.
|
|
|
|
@param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
|
|
@param points2f Array of (x,y) coordinates of each keypoint
|
|
@param keypointIndexes Array of indexes of keypoints to be converted to points. (Acts like a mask to
|
|
convert only specified keypoints)
|
|
*/
|
|
CV_WRAP static void convert(const std::vector<KeyPoint>& keypoints,
|
|
CV_OUT std::vector<Point2f>& points2f,
|
|
const std::vector<int>& keypointIndexes=std::vector<int>());
|
|
/** @overload
|
|
@param points2f Array of (x,y) coordinates of each keypoint
|
|
@param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
|
|
@param size keypoint diameter
|
|
@param response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
|
@param octave pyramid octave in which the keypoint has been detected
|
|
@param class_id object id
|
|
*/
|
|
CV_WRAP static void convert(const std::vector<Point2f>& points2f,
|
|
CV_OUT std::vector<KeyPoint>& keypoints,
|
|
float size=1, float response=1, int octave=0, int class_id=-1);
|
|
|
|
/**
|
|
This method computes overlap for pair of keypoints. Overlap is the ratio between area of keypoint
|
|
regions' intersection and area of keypoint regions' union (considering keypoint region as circle).
|
|
If they don't overlap, we get zero. If they coincide at same location with same size, we get 1.
|
|
@param kp1 First keypoint
|
|
@param kp2 Second keypoint
|
|
*/
|
|
CV_WRAP static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
|
|
|
|
CV_PROP_RW Point2f pt; //!< coordinates of the keypoints
|
|
CV_PROP_RW float size; //!< diameter of the meaningful keypoint neighborhood
|
|
CV_PROP_RW float angle; //!< computed orientation of the keypoint (-1 if not applicable);
|
|
//!< it's in [0,360) degrees and measured relative to
|
|
//!< image coordinate system, ie in clockwise.
|
|
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
|
|
CV_PROP_RW int octave; //!< octave (pyramid layer) from which the keypoint has been extracted
|
|
CV_PROP_RW int class_id; //!< object class (if the keypoints need to be clustered by an object they belong to)
|
|
};
|
|
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
template<> class DataType<KeyPoint>
|
|
{
|
|
public:
|
|
typedef KeyPoint value_type;
|
|
typedef float work_type;
|
|
typedef float channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
depth = DataType<channel_type>::depth,
|
|
channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 7
|
|
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
|
|
type = CV_MAKETYPE(depth, channels)
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
#endif
|
|
|
|
|
|
//////////////////////////////// DMatch /////////////////////////////////
|
|
|
|
/** @brief Class for matching keypoint descriptors
|
|
|
|
query descriptor index, train descriptor index, train image index, and distance between
|
|
descriptors.
|
|
*/
|
|
class CV_EXPORTS_W_SIMPLE DMatch
|
|
{
|
|
public:
|
|
CV_WRAP DMatch();
|
|
CV_WRAP DMatch(int _queryIdx, int _trainIdx, float _distance);
|
|
CV_WRAP DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance);
|
|
|
|
CV_PROP_RW int queryIdx; //!< query descriptor index
|
|
CV_PROP_RW int trainIdx; //!< train descriptor index
|
|
CV_PROP_RW int imgIdx; //!< train image index
|
|
|
|
CV_PROP_RW float distance;
|
|
|
|
// less is better
|
|
bool operator<(const DMatch &m) const;
|
|
};
|
|
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
template<> class DataType<DMatch>
|
|
{
|
|
public:
|
|
typedef DMatch value_type;
|
|
typedef int work_type;
|
|
typedef int channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
depth = DataType<channel_type>::depth,
|
|
channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 4
|
|
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
|
|
type = CV_MAKETYPE(depth, channels)
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
#endif
|
|
|
|
|
|
///////////////////////////// TermCriteria //////////////////////////////
|
|
|
|
/** @brief The class defining termination criteria for iterative algorithms.
|
|
|
|
You can initialize it by default constructor and then override any parameters, or the structure may
|
|
be fully initialized using the advanced variant of the constructor.
|
|
*/
|
|
class CV_EXPORTS TermCriteria
|
|
{
|
|
public:
|
|
/**
|
|
Criteria type, can be one of: COUNT, EPS or COUNT + EPS
|
|
*/
|
|
enum Type
|
|
{
|
|
COUNT=1, //!< the maximum number of iterations or elements to compute
|
|
MAX_ITER=COUNT, //!< ditto
|
|
EPS=2 //!< the desired accuracy or change in parameters at which the iterative algorithm stops
|
|
};
|
|
|
|
//! default constructor
|
|
TermCriteria();
|
|
/**
|
|
@param type The type of termination criteria, one of TermCriteria::Type
|
|
@param maxCount The maximum number of iterations or elements to compute.
|
|
@param epsilon The desired accuracy or change in parameters at which the iterative algorithm stops.
|
|
*/
|
|
TermCriteria(int type, int maxCount, double epsilon);
|
|
|
|
inline bool isValid() const
|
|
{
|
|
const bool isCount = (type & COUNT) && maxCount > 0;
|
|
const bool isEps = (type & EPS) && !cvIsNaN(epsilon);
|
|
return isCount || isEps;
|
|
}
|
|
|
|
int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS
|
|
int maxCount; //!< the maximum number of iterations/elements
|
|
double epsilon; //!< the desired accuracy
|
|
};
|
|
|
|
|
|
//! @} core_basic
|
|
|
|
///////////////////////// raster image moments //////////////////////////
|
|
|
|
//! @addtogroup imgproc_shape
|
|
//! @{
|
|
|
|
/** @brief struct returned by cv::moments
|
|
|
|
The spatial moments \f$\texttt{Moments::m}_{ji}\f$ are computed as:
|
|
|
|
\f[\texttt{m} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot x^j \cdot y^i \right )\f]
|
|
|
|
The central moments \f$\texttt{Moments::mu}_{ji}\f$ are computed as:
|
|
|
|
\f[\texttt{mu} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot (x - \bar{x} )^j \cdot (y - \bar{y} )^i \right )\f]
|
|
|
|
where \f$(\bar{x}, \bar{y})\f$ is the mass center:
|
|
|
|
\f[\bar{x} = \frac{\texttt{m}_{10}}{\texttt{m}_{00}} , \; \bar{y} = \frac{\texttt{m}_{01}}{\texttt{m}_{00}}\f]
|
|
|
|
The normalized central moments \f$\texttt{Moments::nu}_{ij}\f$ are computed as:
|
|
|
|
\f[\texttt{nu} _{ji}= \frac{\texttt{mu}_{ji}}{\texttt{m}_{00}^{(i+j)/2+1}} .\f]
|
|
|
|
@note
|
|
\f$\texttt{mu}_{00}=\texttt{m}_{00}\f$, \f$\texttt{nu}_{00}=1\f$
|
|
\f$\texttt{nu}_{10}=\texttt{mu}_{10}=\texttt{mu}_{01}=\texttt{mu}_{10}=0\f$ , hence the values are not
|
|
stored.
|
|
|
|
The moments of a contour are defined in the same way but computed using the Green's formula (see
|
|
<http://en.wikipedia.org/wiki/Green_theorem>). So, due to a limited raster resolution, the moments
|
|
computed for a contour are slightly different from the moments computed for the same rasterized
|
|
contour.
|
|
|
|
@note
|
|
Since the contour moments are computed using Green formula, you may get seemingly odd results for
|
|
contours with self-intersections, e.g. a zero area (m00) for butterfly-shaped contours.
|
|
*/
|
|
class CV_EXPORTS_W_MAP Moments
|
|
{
|
|
public:
|
|
//! the default constructor
|
|
Moments();
|
|
//! the full constructor
|
|
Moments(double m00, double m10, double m01, double m20, double m11,
|
|
double m02, double m30, double m21, double m12, double m03 );
|
|
////! the conversion from CvMoments
|
|
//Moments( const CvMoments& moments );
|
|
////! the conversion to CvMoments
|
|
//operator CvMoments() const;
|
|
|
|
//! @name spatial moments
|
|
//! @{
|
|
CV_PROP_RW double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
|
|
//! @}
|
|
|
|
//! @name central moments
|
|
//! @{
|
|
CV_PROP_RW double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
|
|
//! @}
|
|
|
|
//! @name central normalized moments
|
|
//! @{
|
|
CV_PROP_RW double nu20, nu11, nu02, nu30, nu21, nu12, nu03;
|
|
//! @}
|
|
};
|
|
|
|
template<> class DataType<Moments>
|
|
{
|
|
public:
|
|
typedef Moments value_type;
|
|
typedef double work_type;
|
|
typedef double channel_type;
|
|
|
|
enum { generic_type = 0,
|
|
channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 24
|
|
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8)
|
|
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
|
,depth = DataType<channel_type>::depth
|
|
,type = CV_MAKETYPE(depth, channels)
|
|
#endif
|
|
};
|
|
|
|
typedef Vec<channel_type, channels> vec_type;
|
|
};
|
|
|
|
namespace traits {
|
|
template<>
|
|
struct Depth< Moments > { enum { value = Depth<double>::value }; };
|
|
template<>
|
|
struct Type< Moments > { enum { value = CV_MAKETYPE(Depth<double>::value, (int)(sizeof(Moments)/sizeof(double))) }; };
|
|
} // namespace
|
|
|
|
//! @} imgproc_shape
|
|
|
|
//! @cond IGNORED
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////// Implementation ////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////// Complex ////////////////////////////////
|
|
|
|
template<typename _Tp> inline
|
|
Complex<_Tp>::Complex()
|
|
: re(0), im(0) {}
|
|
|
|
template<typename _Tp> inline
|
|
Complex<_Tp>::Complex( _Tp _re, _Tp _im )
|
|
: re(_re), im(_im) {}
|
|
|
|
template<typename _Tp> template<typename T2> inline
|
|
Complex<_Tp>::operator Complex<T2>() const
|
|
{
|
|
return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im));
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Complex<_Tp> Complex<_Tp>::conj() const
|
|
{
|
|
return Complex<_Tp>(re, -im);
|
|
}
|
|
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
return a.re == b.re && a.im == b.im;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator != (const Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
return a.re != b.re || a.im != b.im;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
return Complex<_Tp>( a.re + b.re, a.im + b.im );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
a.re += b.re; a.im += b.im;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
return Complex<_Tp>( a.re - b.re, a.im - b.im );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
a.re -= b.re; a.im -= b.im;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator - (const Complex<_Tp>& a)
|
|
{
|
|
return Complex<_Tp>(-a.re, -a.im);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b)
|
|
{
|
|
return Complex<_Tp>( a.re*b, a.im*b );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a)
|
|
{
|
|
return Complex<_Tp>( a.re*b, a.im*b );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b)
|
|
{
|
|
return Complex<_Tp>( a.re + b, a.im );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b)
|
|
{ return Complex<_Tp>( a.re - b, a.im ); }
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a)
|
|
{
|
|
return Complex<_Tp>( a.re + b, a.im );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a)
|
|
{
|
|
return Complex<_Tp>( b - a.re, -a.im );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b)
|
|
{
|
|
a.re += b; return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b)
|
|
{
|
|
a.re -= b; return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b)
|
|
{
|
|
a.re *= b; a.im *= b; return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
double abs(const Complex<_Tp>& a)
|
|
{
|
|
return std::sqrt( (double)a.re*a.re + (double)a.im*a.im);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
double t = 1./((double)b.re*b.re + (double)b.im*b.im);
|
|
return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t),
|
|
(_Tp)((-a.re*b.im + a.im*b.re)*t) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b)
|
|
{
|
|
a = a / b;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b)
|
|
{
|
|
_Tp t = (_Tp)1/b;
|
|
return Complex<_Tp>( a.re*t, a.im*t );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a)
|
|
{
|
|
return Complex<_Tp>(b)/a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b)
|
|
{
|
|
_Tp t = (_Tp)1/b;
|
|
a.re *= t; a.im *= t; return a;
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////// 2D Point ///////////////////////////////
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp>::Point_()
|
|
: x(0), y(0) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp>::Point_(_Tp _x, _Tp _y)
|
|
: x(_x), y(_y) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp>::Point_(const Point_& pt)
|
|
: x(pt.x), y(pt.y) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp>::Point_(const Size_<_Tp>& sz)
|
|
: x(sz.width), y(sz.height) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp>::Point_(const Vec<_Tp,2>& v)
|
|
: x(v[0]), y(v[1]) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt)
|
|
{
|
|
x = pt.x; y = pt.y;
|
|
return *this;
|
|
}
|
|
|
|
template<typename _Tp> template<typename _Tp2> inline
|
|
Point_<_Tp>::operator Point_<_Tp2>() const
|
|
{
|
|
return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y));
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp>::operator Vec<_Tp, 2>() const
|
|
{
|
|
return Vec<_Tp, 2>(x, y);
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
_Tp Point_<_Tp>::dot(const Point_& pt) const
|
|
{
|
|
return saturate_cast<_Tp>(x*pt.x + y*pt.y);
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
double Point_<_Tp>::ddot(const Point_& pt) const
|
|
{
|
|
return (double)x*(double)(pt.x) + (double)y*(double)(pt.y);
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
double Point_<_Tp>::cross(const Point_& pt) const
|
|
{
|
|
return (double)x*pt.y - (double)y*pt.x;
|
|
}
|
|
|
|
template<typename _Tp> inline bool
|
|
Point_<_Tp>::inside( const Rect_<_Tp>& r ) const
|
|
{
|
|
return r.contains(*this);
|
|
}
|
|
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp>& operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
|
|
{
|
|
a.x += b.x;
|
|
a.y += b.y;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp>& operator -= (Point_<_Tp>& a, const Point_<_Tp>& b)
|
|
{
|
|
a.x -= b.x;
|
|
a.y -= b.y;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp>& operator *= (Point_<_Tp>& a, int b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x * b);
|
|
a.y = saturate_cast<_Tp>(a.y * b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp>& operator *= (Point_<_Tp>& a, float b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x * b);
|
|
a.y = saturate_cast<_Tp>(a.y * b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp>& operator *= (Point_<_Tp>& a, double b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x * b);
|
|
a.y = saturate_cast<_Tp>(a.y * b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp>& operator /= (Point_<_Tp>& a, int b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x / b);
|
|
a.y = saturate_cast<_Tp>(a.y / b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp>& operator /= (Point_<_Tp>& a, float b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x / b);
|
|
a.y = saturate_cast<_Tp>(a.y / b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp>& operator /= (Point_<_Tp>& a, double b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x / b);
|
|
a.y = saturate_cast<_Tp>(a.y / b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
double norm(const Point_<_Tp>& pt)
|
|
{
|
|
return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b)
|
|
{
|
|
return a.x == b.x && a.y == b.y;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b)
|
|
{
|
|
return a.x != b.x || a.y != b.y;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator - (const Point_<_Tp>& a)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator * (const Point_<_Tp>& a, int b)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator * (int a, const Point_<_Tp>& b)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator * (const Point_<_Tp>& a, float b)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator * (float a, const Point_<_Tp>& b)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator * (const Point_<_Tp>& a, double b)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator * (double a, const Point_<_Tp>& b)
|
|
{
|
|
return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
|
|
{
|
|
Matx<_Tp, 2, 1> tmp = a * Vec<_Tp,2>(b.x, b.y);
|
|
return Point_<_Tp>(tmp.val[0], tmp.val[1]);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b)
|
|
{
|
|
Matx<_Tp, 3, 1> tmp = a * Vec<_Tp,3>(b.x, b.y, 1);
|
|
return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator / (const Point_<_Tp>& a, int b)
|
|
{
|
|
Point_<_Tp> tmp(a);
|
|
tmp /= b;
|
|
return tmp;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator / (const Point_<_Tp>& a, float b)
|
|
{
|
|
Point_<_Tp> tmp(a);
|
|
tmp /= b;
|
|
return tmp;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point_<_Tp> operator / (const Point_<_Tp>& a, double b)
|
|
{
|
|
Point_<_Tp> tmp(a);
|
|
tmp /= b;
|
|
return tmp;
|
|
}
|
|
|
|
|
|
template<typename _AccTp> static inline _AccTp normL2Sqr(const Point_<int>& pt);
|
|
template<typename _AccTp> static inline _AccTp normL2Sqr(const Point_<int64>& pt);
|
|
template<typename _AccTp> static inline _AccTp normL2Sqr(const Point_<float>& pt);
|
|
template<typename _AccTp> static inline _AccTp normL2Sqr(const Point_<double>& pt);
|
|
|
|
template<> inline int normL2Sqr<int>(const Point_<int>& pt) { return pt.dot(pt); }
|
|
template<> inline int64 normL2Sqr<int64>(const Point_<int64>& pt) { return pt.dot(pt); }
|
|
template<> inline float normL2Sqr<float>(const Point_<float>& pt) { return pt.dot(pt); }
|
|
template<> inline double normL2Sqr<double>(const Point_<int>& pt) { return pt.dot(pt); }
|
|
|
|
template<> inline double normL2Sqr<double>(const Point_<float>& pt) { return pt.ddot(pt); }
|
|
template<> inline double normL2Sqr<double>(const Point_<double>& pt) { return pt.ddot(pt); }
|
|
|
|
|
|
|
|
//////////////////////////////// 3D Point ///////////////////////////////
|
|
|
|
template<typename _Tp> inline
|
|
Point3_<_Tp>::Point3_()
|
|
: x(0), y(0), z(0) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z)
|
|
: x(_x), y(_y), z(_z) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point3_<_Tp>::Point3_(const Point3_& pt)
|
|
: x(pt.x), y(pt.y), z(pt.z) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point3_<_Tp>::Point3_(const Point_<_Tp>& pt)
|
|
: x(pt.x), y(pt.y), z(_Tp()) {}
|
|
|
|
template<typename _Tp> inline
|
|
Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v)
|
|
: x(v[0]), y(v[1]), z(v[2]) {}
|
|
|
|
template<typename _Tp> template<typename _Tp2> inline
|
|
Point3_<_Tp>::operator Point3_<_Tp2>() const
|
|
{
|
|
return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z));
|
|
}
|
|
|
|
#if OPENCV_ABI_COMPATIBILITY > 300
|
|
template<typename _Tp> template<typename _Tp2> inline
|
|
Point3_<_Tp>::operator Vec<_Tp2, 3>() const
|
|
{
|
|
return Vec<_Tp2, 3>(x, y, z);
|
|
}
|
|
#else
|
|
template<typename _Tp> inline
|
|
Point3_<_Tp>::operator Vec<_Tp, 3>() const
|
|
{
|
|
return Vec<_Tp, 3>(x, y, z);
|
|
}
|
|
#endif
|
|
|
|
template<typename _Tp> inline
|
|
Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt)
|
|
{
|
|
x = pt.x; y = pt.y; z = pt.z;
|
|
return *this;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
_Tp Point3_<_Tp>::dot(const Point3_& pt) const
|
|
{
|
|
return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z);
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
double Point3_<_Tp>::ddot(const Point3_& pt) const
|
|
{
|
|
return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const
|
|
{
|
|
return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x);
|
|
}
|
|
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp>& operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b)
|
|
{
|
|
a.x += b.x;
|
|
a.y += b.y;
|
|
a.z += b.z;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp>& operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b)
|
|
{
|
|
a.x -= b.x;
|
|
a.y -= b.y;
|
|
a.z -= b.z;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp>& operator *= (Point3_<_Tp>& a, int b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x * b);
|
|
a.y = saturate_cast<_Tp>(a.y * b);
|
|
a.z = saturate_cast<_Tp>(a.z * b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp>& operator *= (Point3_<_Tp>& a, float b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x * b);
|
|
a.y = saturate_cast<_Tp>(a.y * b);
|
|
a.z = saturate_cast<_Tp>(a.z * b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp>& operator *= (Point3_<_Tp>& a, double b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x * b);
|
|
a.y = saturate_cast<_Tp>(a.y * b);
|
|
a.z = saturate_cast<_Tp>(a.z * b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp>& operator /= (Point3_<_Tp>& a, int b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x / b);
|
|
a.y = saturate_cast<_Tp>(a.y / b);
|
|
a.z = saturate_cast<_Tp>(a.z / b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp>& operator /= (Point3_<_Tp>& a, float b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x / b);
|
|
a.y = saturate_cast<_Tp>(a.y / b);
|
|
a.z = saturate_cast<_Tp>(a.z / b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp>& operator /= (Point3_<_Tp>& a, double b)
|
|
{
|
|
a.x = saturate_cast<_Tp>(a.x / b);
|
|
a.y = saturate_cast<_Tp>(a.y / b);
|
|
a.z = saturate_cast<_Tp>(a.z / b);
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
double norm(const Point3_<_Tp>& pt)
|
|
{
|
|
return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
|
|
{
|
|
return a.x == b.x && a.y == b.y && a.z == b.z;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator != (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
|
|
{
|
|
return a.x != b.x || a.y != b.y || a.z != b.z;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y), saturate_cast<_Tp>(a.z + b.z));
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y), saturate_cast<_Tp>(a.z - b.z));
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator - (const Point3_<_Tp>& a)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y), saturate_cast<_Tp>(-a.z) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b), saturate_cast<_Tp>(a.z*b) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(a.x * b), saturate_cast<_Tp>(a.y * b), saturate_cast<_Tp>(a.z * b) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(a.x * b), saturate_cast<_Tp>(a.y * b), saturate_cast<_Tp>(a.z * b) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b)
|
|
{
|
|
return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b)
|
|
{
|
|
Matx<_Tp, 3, 1> tmp = a * Vec<_Tp,3>(b.x, b.y, b.z);
|
|
return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
|
|
{
|
|
return a * Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator / (const Point3_<_Tp>& a, int b)
|
|
{
|
|
Point3_<_Tp> tmp(a);
|
|
tmp /= b;
|
|
return tmp;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator / (const Point3_<_Tp>& a, float b)
|
|
{
|
|
Point3_<_Tp> tmp(a);
|
|
tmp /= b;
|
|
return tmp;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Point3_<_Tp> operator / (const Point3_<_Tp>& a, double b)
|
|
{
|
|
Point3_<_Tp> tmp(a);
|
|
tmp /= b;
|
|
return tmp;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////// Size /////////////////////////////////
|
|
|
|
template<typename _Tp> inline
|
|
Size_<_Tp>::Size_()
|
|
: width(0), height(0) {}
|
|
|
|
template<typename _Tp> inline
|
|
Size_<_Tp>::Size_(_Tp _width, _Tp _height)
|
|
: width(_width), height(_height) {}
|
|
|
|
template<typename _Tp> inline
|
|
Size_<_Tp>::Size_(const Size_& sz)
|
|
: width(sz.width), height(sz.height) {}
|
|
|
|
template<typename _Tp> inline
|
|
Size_<_Tp>::Size_(const Point_<_Tp>& pt)
|
|
: width(pt.x), height(pt.y) {}
|
|
|
|
template<typename _Tp> template<typename _Tp2> inline
|
|
Size_<_Tp>::operator Size_<_Tp2>() const
|
|
{
|
|
return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height));
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz)
|
|
{
|
|
width = sz.width; height = sz.height;
|
|
return *this;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
_Tp Size_<_Tp>::area() const
|
|
{
|
|
const _Tp result = width * height;
|
|
CV_DbgAssert(!std::numeric_limits<_Tp>::is_integer
|
|
|| width == 0 || result / width == height); // make sure the result fits in the return value
|
|
return result;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
bool Size_<_Tp>::empty() const
|
|
{
|
|
return width <= 0 || height <= 0;
|
|
}
|
|
|
|
|
|
template<typename _Tp> static inline
|
|
Size_<_Tp>& operator *= (Size_<_Tp>& a, _Tp b)
|
|
{
|
|
a.width *= b;
|
|
a.height *= b;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b)
|
|
{
|
|
Size_<_Tp> tmp(a);
|
|
tmp *= b;
|
|
return tmp;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Size_<_Tp>& operator /= (Size_<_Tp>& a, _Tp b)
|
|
{
|
|
a.width /= b;
|
|
a.height /= b;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Size_<_Tp> operator / (const Size_<_Tp>& a, _Tp b)
|
|
{
|
|
Size_<_Tp> tmp(a);
|
|
tmp /= b;
|
|
return tmp;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b)
|
|
{
|
|
a.width += b.width;
|
|
a.height += b.height;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b)
|
|
{
|
|
Size_<_Tp> tmp(a);
|
|
tmp += b;
|
|
return tmp;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b)
|
|
{
|
|
a.width -= b.width;
|
|
a.height -= b.height;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b)
|
|
{
|
|
Size_<_Tp> tmp(a);
|
|
tmp -= b;
|
|
return tmp;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b)
|
|
{
|
|
return a.width == b.width && a.height == b.height;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b)
|
|
{
|
|
return !(a == b);
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////// Rect /////////////////////////////////
|
|
|
|
template<typename _Tp> inline
|
|
Rect_<_Tp>::Rect_()
|
|
: x(0), y(0), width(0), height(0) {}
|
|
|
|
template<typename _Tp> inline
|
|
Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height)
|
|
: x(_x), y(_y), width(_width), height(_height) {}
|
|
|
|
template<typename _Tp> inline
|
|
Rect_<_Tp>::Rect_(const Rect_<_Tp>& r)
|
|
: x(r.x), y(r.y), width(r.width), height(r.height) {}
|
|
|
|
template<typename _Tp> inline
|
|
Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz)
|
|
: x(org.x), y(org.y), width(sz.width), height(sz.height) {}
|
|
|
|
template<typename _Tp> inline
|
|
Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)
|
|
{
|
|
x = std::min(pt1.x, pt2.x);
|
|
y = std::min(pt1.y, pt2.y);
|
|
width = std::max(pt1.x, pt2.x) - x;
|
|
height = std::max(pt1.y, pt2.y) - y;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r )
|
|
{
|
|
x = r.x;
|
|
y = r.y;
|
|
width = r.width;
|
|
height = r.height;
|
|
return *this;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp> Rect_<_Tp>::tl() const
|
|
{
|
|
return Point_<_Tp>(x,y);
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Point_<_Tp> Rect_<_Tp>::br() const
|
|
{
|
|
return Point_<_Tp>(x + width, y + height);
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Size_<_Tp> Rect_<_Tp>::size() const
|
|
{
|
|
return Size_<_Tp>(width, height);
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
_Tp Rect_<_Tp>::area() const
|
|
{
|
|
const _Tp result = width * height;
|
|
CV_DbgAssert(!std::numeric_limits<_Tp>::is_integer
|
|
|| width == 0 || result / width == height); // make sure the result fits in the return value
|
|
return result;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
bool Rect_<_Tp>::empty() const
|
|
{
|
|
return width <= 0 || height <= 0;
|
|
}
|
|
|
|
template<typename _Tp> template<typename _Tp2> inline
|
|
Rect_<_Tp>::operator Rect_<_Tp2>() const
|
|
{
|
|
return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height));
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const
|
|
{
|
|
return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height;
|
|
}
|
|
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b )
|
|
{
|
|
a.x += b.x;
|
|
a.y += b.y;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b )
|
|
{
|
|
a.x -= b.x;
|
|
a.y -= b.y;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b )
|
|
{
|
|
a.width += b.width;
|
|
a.height += b.height;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b )
|
|
{
|
|
const _Tp width = a.width - b.width;
|
|
const _Tp height = a.height - b.height;
|
|
CV_DbgAssert(width >= 0 && height >= 0);
|
|
a.width = width;
|
|
a.height = height;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
|
|
{
|
|
_Tp x1 = std::max(a.x, b.x);
|
|
_Tp y1 = std::max(a.y, b.y);
|
|
a.width = std::min(a.x + a.width, b.x + b.width) - x1;
|
|
a.height = std::min(a.y + a.height, b.y + b.height) - y1;
|
|
a.x = x1;
|
|
a.y = y1;
|
|
if( a.width <= 0 || a.height <= 0 )
|
|
a = Rect();
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
|
|
{
|
|
if (a.empty()) {
|
|
a = b;
|
|
}
|
|
else if (!b.empty()) {
|
|
_Tp x1 = std::min(a.x, b.x);
|
|
_Tp y1 = std::min(a.y, b.y);
|
|
a.width = std::max(a.x + a.width, b.x + b.width) - x1;
|
|
a.height = std::max(a.y + a.height, b.y + b.height) - y1;
|
|
a.x = x1;
|
|
a.y = y1;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
|
|
{
|
|
return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
|
|
{
|
|
return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b)
|
|
{
|
|
return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b)
|
|
{
|
|
return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b)
|
|
{
|
|
return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Size_<_Tp>& b)
|
|
{
|
|
const _Tp width = a.width - b.width;
|
|
const _Tp height = a.height - b.height;
|
|
CV_DbgAssert(width >= 0 && height >= 0);
|
|
return Rect_<_Tp>( a.x, a.y, width, height );
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
|
|
{
|
|
Rect_<_Tp> c = a;
|
|
return c &= b;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
|
|
{
|
|
Rect_<_Tp> c = a;
|
|
return c |= b;
|
|
}
|
|
|
|
/**
|
|
* @brief measure dissimilarity between two sample sets
|
|
*
|
|
* computes the complement of the Jaccard Index as described in <https://en.wikipedia.org/wiki/Jaccard_index>.
|
|
* For rectangles this reduces to computing the intersection over the union.
|
|
*/
|
|
template<typename _Tp> static inline
|
|
double jaccardDistance(const Rect_<_Tp>& a, const Rect_<_Tp>& b) {
|
|
_Tp Aa = a.area();
|
|
_Tp Ab = b.area();
|
|
|
|
if ((Aa + Ab) <= std::numeric_limits<_Tp>::epsilon()) {
|
|
// jaccard_index = 1 -> distance = 0
|
|
return 0.0;
|
|
}
|
|
|
|
double Aab = (a & b).area();
|
|
// distance = 1 - jaccard_index
|
|
return 1.0 - Aab / (Aa + Ab - Aab);
|
|
}
|
|
|
|
////////////////////////////// RotatedRect //////////////////////////////
|
|
|
|
inline
|
|
RotatedRect::RotatedRect()
|
|
: center(), size(), angle(0) {}
|
|
|
|
inline
|
|
RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
|
|
: center(_center), size(_size), angle(_angle) {}
|
|
|
|
|
|
|
|
///////////////////////////////// Range /////////////////////////////////
|
|
|
|
inline
|
|
Range::Range()
|
|
: start(0), end(0) {}
|
|
|
|
inline
|
|
Range::Range(int _start, int _end)
|
|
: start(_start), end(_end) {}
|
|
|
|
inline
|
|
int Range::size() const
|
|
{
|
|
return end - start;
|
|
}
|
|
|
|
inline
|
|
bool Range::empty() const
|
|
{
|
|
return start == end;
|
|
}
|
|
|
|
inline
|
|
Range Range::all()
|
|
{
|
|
return Range(INT_MIN, INT_MAX);
|
|
}
|
|
|
|
|
|
static inline
|
|
bool operator == (const Range& r1, const Range& r2)
|
|
{
|
|
return r1.start == r2.start && r1.end == r2.end;
|
|
}
|
|
|
|
static inline
|
|
bool operator != (const Range& r1, const Range& r2)
|
|
{
|
|
return !(r1 == r2);
|
|
}
|
|
|
|
static inline
|
|
bool operator !(const Range& r)
|
|
{
|
|
return r.start == r.end;
|
|
}
|
|
|
|
static inline
|
|
Range operator & (const Range& r1, const Range& r2)
|
|
{
|
|
Range r(std::max(r1.start, r2.start), std::min(r1.end, r2.end));
|
|
r.end = std::max(r.end, r.start);
|
|
return r;
|
|
}
|
|
|
|
static inline
|
|
Range& operator &= (Range& r1, const Range& r2)
|
|
{
|
|
r1 = r1 & r2;
|
|
return r1;
|
|
}
|
|
|
|
static inline
|
|
Range operator + (const Range& r1, int delta)
|
|
{
|
|
return Range(r1.start + delta, r1.end + delta);
|
|
}
|
|
|
|
static inline
|
|
Range operator + (int delta, const Range& r1)
|
|
{
|
|
return Range(r1.start + delta, r1.end + delta);
|
|
}
|
|
|
|
static inline
|
|
Range operator - (const Range& r1, int delta)
|
|
{
|
|
return r1 + (-delta);
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////// Scalar ////////////////////////////////
|
|
|
|
template<typename _Tp> inline
|
|
Scalar_<_Tp>::Scalar_()
|
|
{
|
|
this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
|
|
{
|
|
this->val[0] = v0;
|
|
this->val[1] = v1;
|
|
this->val[2] = v2;
|
|
this->val[3] = v3;
|
|
}
|
|
|
|
template<typename _Tp> template<typename _Tp2, int cn> inline
|
|
Scalar_<_Tp>::Scalar_(const Vec<_Tp2, cn>& v)
|
|
{
|
|
int i;
|
|
for( i = 0; i < (cn < 4 ? cn : 4); i++ )
|
|
this->val[i] = cv::saturate_cast<_Tp>(v.val[i]);
|
|
for( ; i < 4; i++ )
|
|
this->val[i] = 0;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Scalar_<_Tp>::Scalar_(_Tp v0)
|
|
{
|
|
this->val[0] = v0;
|
|
this->val[1] = this->val[2] = this->val[3] = 0;
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0)
|
|
{
|
|
return Scalar_<_Tp>(v0, v0, v0, v0);
|
|
}
|
|
|
|
|
|
template<typename _Tp> inline
|
|
Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& a, double scale ) const
|
|
{
|
|
return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0] * a.val[0] * scale),
|
|
saturate_cast<_Tp>(this->val[1] * a.val[1] * scale),
|
|
saturate_cast<_Tp>(this->val[2] * a.val[2] * scale),
|
|
saturate_cast<_Tp>(this->val[3] * a.val[3] * scale));
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
Scalar_<_Tp> Scalar_<_Tp>::conj() const
|
|
{
|
|
return Scalar_<_Tp>(saturate_cast<_Tp>( this->val[0]),
|
|
saturate_cast<_Tp>(-this->val[1]),
|
|
saturate_cast<_Tp>(-this->val[2]),
|
|
saturate_cast<_Tp>(-this->val[3]));
|
|
}
|
|
|
|
template<typename _Tp> inline
|
|
bool Scalar_<_Tp>::isReal() const
|
|
{
|
|
return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0;
|
|
}
|
|
|
|
|
|
template<typename _Tp> template<typename T2> inline
|
|
Scalar_<_Tp>::operator Scalar_<T2>() const
|
|
{
|
|
return Scalar_<T2>(saturate_cast<T2>(this->val[0]),
|
|
saturate_cast<T2>(this->val[1]),
|
|
saturate_cast<T2>(this->val[2]),
|
|
saturate_cast<T2>(this->val[3]));
|
|
}
|
|
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
|
|
{
|
|
a.val[0] += b.val[0];
|
|
a.val[1] += b.val[1];
|
|
a.val[2] += b.val[2];
|
|
a.val[3] += b.val[3];
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
|
|
{
|
|
a.val[0] -= b.val[0];
|
|
a.val[1] -= b.val[1];
|
|
a.val[2] -= b.val[2];
|
|
a.val[3] -= b.val[3];
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v )
|
|
{
|
|
a.val[0] *= v;
|
|
a.val[1] *= v;
|
|
a.val[2] *= v;
|
|
a.val[3] *= v;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
|
|
{
|
|
return a.val[0] == b.val[0] && a.val[1] == b.val[1] &&
|
|
a.val[2] == b.val[2] && a.val[3] == b.val[3];
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
|
|
{
|
|
return a.val[0] != b.val[0] || a.val[1] != b.val[1] ||
|
|
a.val[2] != b.val[2] || a.val[3] != b.val[3];
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
|
|
{
|
|
return Scalar_<_Tp>(a.val[0] + b.val[0],
|
|
a.val[1] + b.val[1],
|
|
a.val[2] + b.val[2],
|
|
a.val[3] + b.val[3]);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
|
|
{
|
|
return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]),
|
|
saturate_cast<_Tp>(a.val[1] - b.val[1]),
|
|
saturate_cast<_Tp>(a.val[2] - b.val[2]),
|
|
saturate_cast<_Tp>(a.val[3] - b.val[3]));
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha)
|
|
{
|
|
return Scalar_<_Tp>(a.val[0] * alpha,
|
|
a.val[1] * alpha,
|
|
a.val[2] * alpha,
|
|
a.val[3] * alpha);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a)
|
|
{
|
|
return a*alpha;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator - (const Scalar_<_Tp>& a)
|
|
{
|
|
return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]),
|
|
saturate_cast<_Tp>(-a.val[1]),
|
|
saturate_cast<_Tp>(-a.val[2]),
|
|
saturate_cast<_Tp>(-a.val[3]));
|
|
}
|
|
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
|
|
{
|
|
return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]),
|
|
saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]),
|
|
saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1]),
|
|
saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0]));
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp>& operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
|
|
{
|
|
a = a * b;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha)
|
|
{
|
|
return Scalar_<_Tp>(a.val[0] / alpha,
|
|
a.val[1] / alpha,
|
|
a.val[2] / alpha,
|
|
a.val[3] / alpha);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<float> operator / (const Scalar_<float>& a, float alpha)
|
|
{
|
|
float s = 1 / alpha;
|
|
return Scalar_<float>(a.val[0] * s, a.val[1] * s, a.val[2] * s, a.val[3] * s);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<double> operator / (const Scalar_<double>& a, double alpha)
|
|
{
|
|
double s = 1 / alpha;
|
|
return Scalar_<double>(a.val[0] * s, a.val[1] * s, a.val[2] * s, a.val[3] * s);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha)
|
|
{
|
|
a = a / alpha;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b)
|
|
{
|
|
_Tp s = a / (b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]);
|
|
return b.conj() * s;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
|
|
{
|
|
return a * ((_Tp)1 / b);
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
|
|
{
|
|
a = a / b;
|
|
return a;
|
|
}
|
|
|
|
template<typename _Tp> static inline
|
|
Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
|
|
{
|
|
Matx<double, 4, 1> c((Matx<double, 4, 4>)a, b, Matx_MatMulOp());
|
|
return reinterpret_cast<const Scalar&>(c);
|
|
}
|
|
|
|
template<> inline
|
|
Scalar operator * (const Matx<double, 4, 4>& a, const Scalar& b)
|
|
{
|
|
Matx<double, 4, 1> c(a, b, Matx_MatMulOp());
|
|
return reinterpret_cast<const Scalar&>(c);
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////// KeyPoint ///////////////////////////////
|
|
|
|
inline
|
|
KeyPoint::KeyPoint()
|
|
: pt(0,0), size(0), angle(-1), response(0), octave(0), class_id(-1) {}
|
|
|
|
inline
|
|
KeyPoint::KeyPoint(Point2f _pt, float _size, float _angle, float _response, int _octave, int _class_id)
|
|
: pt(_pt), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {}
|
|
|
|
inline
|
|
KeyPoint::KeyPoint(float x, float y, float _size, float _angle, float _response, int _octave, int _class_id)
|
|
: pt(x, y), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {}
|
|
|
|
|
|
|
|
///////////////////////////////// DMatch ////////////////////////////////
|
|
|
|
inline
|
|
DMatch::DMatch()
|
|
: queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(FLT_MAX) {}
|
|
|
|
inline
|
|
DMatch::DMatch(int _queryIdx, int _trainIdx, float _distance)
|
|
: queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {}
|
|
|
|
inline
|
|
DMatch::DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance)
|
|
: queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {}
|
|
|
|
inline
|
|
bool DMatch::operator < (const DMatch &m) const
|
|
{
|
|
return distance < m.distance;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////// TermCriteria /////////////////////////////
|
|
|
|
inline
|
|
TermCriteria::TermCriteria()
|
|
: type(0), maxCount(0), epsilon(0) {}
|
|
|
|
inline
|
|
TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
|
|
: type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
|
|
|
|
//! @endcond
|
|
|
|
} // cv
|
|
|
|
#endif //OPENCV_CORE_TYPES_HPP
|