一、基本类型
可以在 opencv-4.0.0\modules\core\include\opencv2\core\base.hpp
或 opencv-4.0.0\modules\core\include\opencv2\core\types.hpp
找到基本数据类型的定义和声明,下面简单介绍常见的数据类型:
//base.hpp中的声明
template<typename _Tp, int cn> class Vec;
template<typename _Tp, int m, int n> class Matx;
template<typename _Tp> class Complex;
template<typename _Tp> class Point_;
template<typename _Tp> class Point3_;
template<typename _Tp> class Size_;
template<typename _Tp> class Rect_;
template<typename _Tp> class Scalar_;
class CV_EXPORTS Mat;
template<typename _Tp> class Mat_;
1、Point类
二维点类,作为一个模板类使用,模板实例宏定义如下:
typedef Point_<int> Point2i;
typedef Point_<int64> Point2l;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point2i Point;
接下来我们找到模板类Point_
的定义:
template<typename _Tp> class Point_
{
public:
typedef _Tp value_type;
//构造函数
Point_();
Point_(_Tp _x, _Tp _y);
Point_(const Point_& pt);
Point_(Point_&& pt) CV_NOEXCEPT;
Point_(const Size_<_Tp>& sz);
Point_(const Vec<_Tp, 2>& v);
Point_& operator = (const Point_& pt);
Point_& operator = (Point_&& pt) CV_NOEXCEPT;
//转换为另一种数据类型的Point_
template<typename _Tp2> operator Point_<_Tp2>() const;
//转化为旧类型
operator Vec<_Tp, 2>() const;
//点乘操作
_Tp dot(const Point_& pt) const;
//双精度点乘
double ddot(const Point_& pt) const;
//叉乘
double cross(const Point_& pt) const;
//检查点是否位于矩形内
bool inside(const Rect_<_Tp>& r) const;
_Tp x; //成员变量x
_Tp y; //成员变量y
};
除了二维点,OpenCV还有三维点的模板类Point3_
,包含变量x、y、z,其定义如下:
typedef Point3_<int> Point3i;
typedef Point3_<float> Point3f;
typedef Point3_<double> Pointd;
template<typename _Tp> class Point3_
{
public:
typedef _Tp value_type;
//! default constructor
Point3_();
Point3_(_Tp _x, _Tp _y, _Tp _z);
Point3_(const Point3_& pt);
Point3_(Point3_&& pt) CV_NOEXCEPT;
explicit Point3_(const Point_<_Tp>& pt);
Point3_(const Vec<_Tp, 3>& v);
Point3_& operator = (const Point3_& pt);
Point3_& operator = (Point3_&& pt) CV_NOEXCEPT;
//! conversion to another data type
template<typename _Tp2> operator Point3_<_Tp2>() const;
//! conversion to cv::Vec<>
operator Vec<_Tp, 3>() const;
//! 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
};
2、Scaler类
cv::Scalar类是四维点类,继承自Vec模板类,模板类的定义如下:
template<typename _Tp> class Scalar_ : public Vec<_Tp, 4>
{
public:
//构造函数
Scalar_();
Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
Scalar_(_Tp v0);
Scalar_(const Scalar_& s);
Scalar_(Scalar_&& s) CV_NOEXCEPT;
//运算符重载
Scalar_& operator=(const Scalar_& s);
Scalar_& operator=(Scalar_&& s) CV_NOEXCEPT;
template<typename _Tp2, int cn>
Scalar_(const Vec<_Tp2, cn>& v);
//将所有数值设为v0
static Scalar_<_Tp> all(_Tp v0);
//数据类型转换
template<typename T2> operator Scalar_<T2>() const;
//乘
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;
};
Scaler
类型默认为双精度类型:
typedef Scalar_<double> Scalar;
Scalar
可以用以下方法初始化:
Scalar col(255,255,255);
Scalar col[7];
col[0] = {255, 255,255};
col[1] = {0, 255,255};
col[2] = {255, 0,255};
col[3] = {255, 255,0};
col[4] = {0, 0,255};
col[5] = {255, 0,0};
col[6] = {0, 255,0};
3、Size类
Size类与Point类类似,而且可以与Point类互相转换,两者的主要区别在于Point类的数据成员是x和y,而size类中对应的成员是width和height。
Size类型的宏定义如下:
typedef Size_<int> Size2i;
typedef Size_<int64> Size2l;
typedef Size_<float> Size2f;
typedef Size_<double> Size2d;
typedef Size2i Size;
其中包含Size_模板类,Size_
的模板类的定义如下:
template<typename _Tp> class Size_
{
public:
typedef _Tp value_type;
//构造函数
Size_();
Size_(_Tp _width, _Tp _height);
Size_(const Size_& sz);
Size_(Size_&& sz) CV_NOEXCEPT;
Size_(const Point_<_Tp>& pt);
Size_& operator = (const Size_& sz);
Size_& operator = (Size_&& sz) CV_NOEXCEPT;
//求面积
_Tp area() const;
//求长宽比
double aspectRatio() const;
//true if empty
bool empty() const;
//类型转换
template<typename _Tp2> operator Size_<_Tp2>() const;
_Tp width; //!< the width
_Tp height; //!< the height
};
4、Rect类
Rect类表示矩形,包含Point类的成员x和y(矩形左上角)和Size类的成员width和height(代表矩形的大小),有以下几种数据类型表示:
typedef Rect_<int> Rect2i;
typedef Rect_<float> Rect2f;
typedef Rect_<double> Rect2d;
typedef Rect2i Rect;
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_(Rect_&& r) CV_NOEXCEPT;
Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
Rect_& operator = ( const Rect_& r );
Rect_& operator = ( Rect_&& r ) CV_NOEXCEPT;
//! 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;
//数据类型转换
template<typename _Tp2> operator Rect_<_Tp2>() const;
//检查点是否位于矩形内
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
};
5、RotatedRect类
RotatedRect
类表示一个矩形,包含成员变量为中心点坐标、长宽和旋转角度,代表矩形饶中心点旋转的角度。
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;
};
6、复数类
复数类包含re和im两个成员变量,其模板类和宏定义如下:
typedef Complex<float> Complexf;
typedef Complex<double> Complexd;
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;
//! 共轭
Complex conj() const;
_Tp re, im; //< the real and the imaginary parts
};
typedef Complex<float> Complexf;
typedef Complex<double> Complexd;
7、range类
range类是一个普通的类,表示一个区间范围start和end,数据类型为int:
class CV_EXPORTS Range
{
public:
Range();
Range(int _start, int _end);
int size() const;
bool empty() const;
static Range all();
int start, end;
};
8、固定矩阵类
固定矩阵类是OpenCV中比较核心的部分,为模板类Matx
,创建时需要已知行列数和数据类型。
要表示一个用来处理矩阵代数的矩阵的时候,就会用到矩阵类,如果是图像或者大型点列表这样的大数组,应该使用cv::Mat。
template<typename _Tp, int m, int n> class Matx;
//实例类型有以下类型
typedef Matx<float, 1, 2> Matx12f;
typedef Matx<double, 1, 2> Matx12d;
typedef Matx<float, 1, 3> Matx13f;
typedef Matx<double, 1, 3> Matx13d;
typedef Matx<float, 1, 4> Matx14f;
typedef Matx<double, 1, 4> Matx14d;
typedef Matx<float, 1, 6> Matx16f;
typedef Matx<double, 1, 6> Matx16d;
typedef Matx<float, 2, 1> Matx21f;
typedef Matx<double, 2, 1> Matx21d;
typedef Matx<float, 3, 1> Matx31f;
typedef Matx<double, 3, 1> Matx31d;
typedef Matx<float, 4, 1> Matx41f;
typedef Matx<double, 4, 1> Matx41d;
typedef Matx<float, 6, 1> Matx61f;
typedef Matx<double, 6, 1> Matx61d;
typedef Matx<float, 2, 2> Matx22f;
typedef Matx<double, 2, 2> Matx22d;
typedef Matx<float, 2, 3> Matx23f;
typedef Matx<double, 2, 3> Matx23d;
typedef Matx<float, 3, 2> Matx32f;
typedef Matx<double, 3, 2> Matx32d;
typedef Matx<float, 3, 3> Matx33f;
typedef Matx<double, 3, 3> Matx33d;
typedef Matx<float, 3, 4> Matx34f;
typedef Matx<double, 3, 4> Matx34d;
typedef Matx<float, 4, 3> Matx43f;
typedef Matx<double, 4, 3> Matx43d;
typedef Matx<float, 4, 4> Matx44f;
typedef Matx<double, 4, 4> Matx44d;
typedef Matx<float, 6, 6> Matx66f;
typedef Matx<double, 6, 6> Matx66d;
template<typename _Tp, int m, int n> class Matx
{
public:
enum {
rows = m,
cols = n,
channels = rows*cols,
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
depth = traits::Type<_Tp>::value,
type = CV_MAKETYPE(depth, channels),
#endif
shortdim = (m < n ? m : n)
};
typedef _Tp value_type;
typedef Matx<_Tp, m, n> mat_type;
typedef Matx<_Tp, shortdim, 1> diag_type;
//下面是构造函数,对应各种行列数
Matx();
explicit Matx(_Tp v0); //!< 1x1 matrix
Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5, _Tp v6, _Tp v7,
_Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5, _Tp v6, _Tp v7,
_Tp v8, _Tp v9, _Tp v10, _Tp v11,
_Tp v12, _Tp v13); //!< 1x14, 2x7, 7x2 or 14x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5, _Tp v6, _Tp v7,
_Tp v8, _Tp v9, _Tp v10, _Tp v11,
_Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix
explicit Matx(const _Tp* vals); //!< initialize from a plain array
Matx(std::initializer_list<_Tp>); //!< initialize from an initializer list
static Matx all(_Tp alpha); //统一元素矩阵
static Matx zeros(); //零矩阵
static Matx ones(); //全一矩阵
static Matx eye(); //单位矩阵
static Matx diag(const diag_type& d); //对角阵
static Matx randu(_Tp a, _Tp b); //均匀分布矩阵
static Matx randn(_Tp a, _Tp b); //正态分布矩阵
//点乘
_Tp dot(const Matx<_Tp, m, n>& v) const;
//双精度点乘
double ddot(const Matx<_Tp, m, n>& v) const;
//!数据类型转换
template<typename T2> operator Matx<T2, m, n>() const;
//改变矩阵形状
template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
//提取子矩阵
template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
//提取行
Matx<_Tp, 1, n> row(int i) const;
//提取列
Matx<_Tp, m, 1> col(int i) const;
//提取对角阵
diag_type diag() const;
//转置
Matx<_Tp, n, m> t() const;
//求逆
Matx<_Tp, n, m> inv(int method=DECOMP_LU, bool *p_is_ok = NULL) const;
//解线性方程
template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const;
Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const;
//元素级乘法
Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const;
//元素级除法
Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const;
//! element access
const _Tp& operator ()(int i, int j) const;
_Tp& operator ()(int i, int j);
//! 1D element access
const _Tp& operator ()(int i) const;
_Tp& operator ()(int i);
Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp);
Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp);
template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp);
Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp);
Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp);
template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp);
Matx(const Matx<_Tp, n, m>& a, Matx_TOp);
_Tp val[m*n]; //< matrix elements
};
调用方法:
m23d = cv::Matx23d::zeros();
m(i, j), m(i); //成员访问
m91f = m33f.reshape<9,1>();
m44f = (Matx44f) m44d;
m31f = m33f.solve(rhs31f, method);
9、固定向量类
固定向量类Vec由固定矩阵类派生得到,为列向量,创建时需要已知元素个数和数据类型。
template<typename _Tp, int cn> class Vec;
//实例如下
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;
typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;
typedef Vec<ushort, 2> Vec2w;
typedef Vec<ushort, 3> Vec3w;
typedef Vec<ushort, 4> Vec4w;
typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<int, 6> Vec6i;
typedef Vec<int, 8> Vec8i;
typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;
typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;
template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
{
public:
typedef _Tp value_type;
enum {
channels = cn,
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
depth = Matx<_Tp, cn, 1>::depth,
type = CV_MAKETYPE(depth, channels),
#endif
_dummy_enum_finalizer = 0
};
//构造函数
Vec();
Vec(_Tp v0); //!< 1-element vector constructor
Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13); //!< 14-element vector constructor
explicit Vec(const _Tp* values);
Vec(std::initializer_list<_Tp>);
Vec(const Vec<_Tp, cn>& v);
static Vec all(_Tp alpha); //统一元素向量
//元素级相乘
Vec mul(const Vec<_Tp, cn>& v) const;
//! conjugation (makes sense for complex numbers and quaternions)
Vec conj() const;
/*!
cross product of the two 3D vectors.
For other dimensionalities the exception is raised
*/
Vec cross(const Vec& v) const;
//数据类型
template<typename T2> operator Vec<T2, cn>() const;
/*! element access */
const _Tp& operator [](int i) const;
_Tp& operator[](int i);
const _Tp& operator ()(int i) const;
_Tp& operator ()(int i);
Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp);
Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp);
template<typename _T2> Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp);
};
调用:
v4f[i]; v3w(j); //元素访问,可以通过单个数索引各项
二、矩阵类型
1、CvMat
OpenCV中常用的矩阵类型有Mat
,CvMat
和IplImage
,其中CvMat
和IplImage
为结构体,CvMat
的定义如下:
struct CvMat
{
int type; //元素类型
int step; //以字节为单位的行数据长度
/* for internal use only */
int* refcount;
int hdr_refcount;
union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data; //数据指针
#ifdef __cplusplus
union
{
int rows;
int height;
};
union
{
int cols;
int width;
};
#else
int rows;
int cols;
#endif
#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)
CvMat() {}
CvMat(const cv::Mat& m) { *this = cvMat(m); }
#endif
}
CvMat;
CvMat
中的type成员用于标示元素类型和标记,OpenCV中用一系列的宏定义了可取的元素值,其中数据类型有8U、8S、16U、16S、32S、32F、64F
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
对CvMat的初始化有以下几种方式:
CvMat* mat = cvCreateMat( 2, 2, CV_64FC1 ); //初始化
cvZero( mat ); //元素置为0
cvmSet( mat, 0, 0, 1 ); //(0,0) = 1,以下以此类推
cvmSet( mat, 0, 1, 2 );
cvmSet( mat, 1, 0, 3 );
cvmSet( mat, 2, 2, 4 );
cvReleaseMat( &mat ); //释放
//---------------------------------------------------
double a[12] = { 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12 };
CvMat mat = cvMat( 3, 4, CV_64FC1, a ); //使用指针初始化
2、ImlImage
可以说IplImage
类型继承自CvMat
类型,较之CvMat
多了很多参数,当然还包括其他的变量将之解析成图像数据。其定义如下
typedef struct _IplImage IplImage;
struct
_IplImage
{
int nSize; /**< sizeof(IplImage) */
int ID; /**< version (=0)*/
int nChannels; /**< Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /**< Ignored by OpenCV */
int depth; /**< Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */
char colorModel[4]; /**< Ignored by OpenCV */
char channelSeq[4]; /**< ditto */
int dataOrder; /**< 0 - interleaved color channels, 1 - separate color channels.
cvCreateImage can only create interleaved images */
int origin; /**< 0 - top-left origin,
1 - bottom-left origin (Windows bitmaps style). */
int align; /**< Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead. */
int width; /**< Image width in pixels. */
int height; /**< Image height in pixels. */
struct _IplROI *roi; /**< Image ROI. If NULL, the whole image is selected. */
struct _IplImage *maskROI; /**< Must be NULL. */
void *imageId; /**< " " */
struct _IplTileInfo *tileInfo; /**< " " */
int imageSize; /**< Image data size in bytes
(==image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /**< Pointer to aligned image data. */
int widthStep; /**< Size of aligned image row in bytes. */
int BorderMode[4]; /**< Ignored by OpenCV. */
int BorderConst[4]; /**< Ditto. */
char *imageDataOrigin; /**< Pointer to very origin of image data
(not necessarily aligned) -
needed for correct deallocation */
#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)
_IplImage() {}
_IplImage(const cv::Mat& m) { *this = cvIplImage(m); }
#endif
}
IplImage;
可以直接将IplImage文件保存为图片:
IplImage img1;
//code
cvSaveImage("res.jpg",img1); //保存结果
3、Mat
Mat类可以被看做是OpenCV中C++版本的矩阵类,替代原来C版本的矩阵结构体CvMat和图像结构体IplImage;
Mat是一种高效的数据类型,它对内存进行动态的管理,不需要之前用户手动的管理内存。
Mat类定义于core.hpp
中,成员变量主要包含有两部分数据:一部分是矩阵头(matrix header),这部分的大小是固定的,包含矩阵的大小,存储的方式,矩阵存储的地址等等;另一个部分是一个指向矩阵包含像素值的指针(data)。
Mat类的定义如下:
class CV_EXPORTS Mat
{
public:
// ... a lot of methods ...
...
/*! includes several bit-fields:
- the magic signature
- continuity flag
- depth
- number of channels
*/
int flags;
//! the matrix dimensionality, >= 2
int dims;
//! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
int rows, cols;
//! pointer to the data
uchar* data;
//! helper fields used in locateROI and adjustROI
const uchar* datastart;
const uchar* dataend;
const uchar* datalimit;
//! custom allocator
MatAllocator* allocator;
//! and the standard allocator
static MatAllocator* getStdAllocator();
static MatAllocator* getDefaultAllocator();
static void setDefaultAllocator(MatAllocator* allocator);
//! internal use method: updates the continuity flag
void updateContinuityFlag();
//! interaction with UMat
UMatData* u;
MatSize size;
MatStep step;
};
数据类型:
Mat的存储是逐行存储的,矩阵中的数据类型包括:Mat_
• CV_8U - 8-bit unsigned integers ( 0..255 )
• CV_8S - 8-bit signed integers ( -128..127 )
• CV_16U - 16-bit unsigned integers ( 0..65535 )
• CV_16S - 16-bit signed integers ( -32768..32767 )
• CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
• CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
• CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
初始化
数据类型转换
因为OpenCV包含多种矩阵类,通常需要在各种矩阵类之间进行数据转换,下面是几种转换方式:
1、IplImage -> cvMat
IplImage *img = cvLoadImage("pic.jpg");
CvMat mathdr,*mat1 = cvGetMat( img, &mathdr );
CvMat *mat2 = cvCreateMat( img->height, img->width, CV_64FC3 );
cvConvert( img, mat2 );
2、cvMat -> IplImage
IplImage* img1 = cvCreateImage(cvGetSize(mat1),8,1); //初始化大小
cvGetImage(mat1,img1); //转换
cvSaveImage("res.jpg",img1); //保存结果