二,opencv2.x模块core介绍(一)

一,opencv模块core内容第一部分——Basic Structures(基本数据结构)

该模块中包含了opencv所利用到的最基本的数据结构,是opencv最基础最核心,也是最需要掌握的内容,本章节主要介绍opencv2.x基于c++的类,只是顺带提一下opencv1.x中的基于c语言类型的数据结构。
opencv2.x中最基础的数据类型有如下几个:
DataType——数据类型
Point_,Point3_——点(x,y,z)
Size_——尺寸(width*heigth)
Rect_,RotatedRect——矩形(x,y,width,height)
TermCriteria——终止条件
Matx——小矩阵
Vec——向量
Scalar_——标量
Range——范围
Ptr——指针(重点,难点,需花时间)
Mat,Mat_——矩阵(最重要,最核心,需要很多时间)
InputArray,OutputArray——输入输出数组
NartMatIterator——矩阵迭代
SparseMat,SparseMat_——稀疏矩阵
Algorithm——算法

">

二,DataType

数据类型简介:

该类是opencv的最原始的数据类型,opencv的基本的数据类型有unsigned char, bool, signed char, unsigned short, signed short, int , float, double 或者是这些类型的多个元素的组合(rgb,三通道数据类型)。以上列表中任何原始数据类型都可以被CV_ <bit-depth>{U|S|F}C(<number_of_channels>)来定义。例如,uchar——CV_8UC1,3个元素的浮点元组——CV_32FC3等等。一个通用的能够存储这样一个原始数据类型的opencv结构就是Vec。这样的数据类型的实例可以被存储在std::vector, Mat, Mat_, SparseMat, SparseMat_, 或者是任何其他能偶存储Vec实例的容器类。
结论:DataType就是opencv最基本的数据类型,CV_8UC1之类的东西。

类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<> class DataType<uchar>
{
typedef uchar value_type;
typedef int work_type;
typedef uchar channel_type;
enum { channel_type = CV_8U, channels = 1, fmt='u', type = CV_8U };
};
...
template<typename _Tp> DataType<std::complex<_Tp> >
{
typedef std::complex<_Tp> value_type;
typedef std::complex<_Tp> work_type;
typedef _Tp channel_type;
// DataDepth is another helper trait class
enum { depth = DataDepth<_Tp>::value, channels=2,
fmt=(channels-1)*256+DataDepth<_Tp>::fmt,
type=CV_MAKETYPE(depth, channels) };
};
...

这个类的作用就是讲可确定编译时间类型的数据转化为opencv特定的可编译数据类型。例如:

1
2
3
4
5
6
// allocates a 30x40 floating-point matrix
Mat A(30, 40, DataType<float>::type);

Mat B = Mat_<std::complex<double> >(3, 3);
// the statement below will print 6, 2 /*, that is depth == CV_64F, channels == 2 */
cout << B.depth() << ", " << B.channels() << endl;

在平常的使用中,一般不会直接使用这个类的对象,而是直接使用CV_8UC3等预定义常量


三,Point_,Point3_

数据类型简介

这两个类就是为了描述计算机图像中的点,Point_描述的是2维的点(x, y)(在opencv1.x中对应的是CvPoint和CvPoint2D32f),Point3_描述的是3维的点(x, y, z) 。

类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
template<typename _Tp> class CV_EXPORTS Point_
{
public:
typedef _Tp value_type;

// various constructors
Point_();
Point_(_Tp _x, _Tp _y);
Point_(const Point_& pt);
Point_(const CvPoint& pt);
Point_(const CvPoint2D32f& 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 CvPoint() const;
operator CvPoint2D32f() const;
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, y; //< the point coordinates
};

其中以Point_模板类为原型预定义了许多表示2维坐标点的类供我们使用:如

1
2
3
4
typedef Point_<int> Point2i;
typedef Point2i Point;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;

使用范例:

1
2
3
Point2f a(0.3f, 0.f), b(0.f, 0.4f);
Point pt = (a + b)*10.f;
cout << pt.x << ", " << pt.y << endl;

Point_类实例能够进行多种运算:
pt1 = pt2 + pt3;
pt1 = pt2 - pt3;
pt1 = pt2 a;
pt1 = a
pt2;
pt1 += pt2;
pt1 -= pt2;
pt1 *= a;
double value = norm(pt); // L2 norm
pt1 == pt2;
pt1 != pt2;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
template<typename _Tp> class CV_EXPORTS Point3_
{
public:
typedef _Tp value_type;

// various constructors
Point3_();
Point3_(_Tp _x, _Tp _y, _Tp _z);
Point3_(const Point3_& pt);
explicit Point3_(const Point_<_Tp>& pt);
Point3_(const CvPoint3D32f& 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 the old-style CvPoint...
operator CvPoint3D32f() 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, y, z; //< the point coordinates
};

同样的,Point3_也预定义了一些类让我们直接使用:如

1
2
3
typedef Point3_<int> Point3i;
typedef Point3_<float> Point3f;
typedef Point3_<double> Point3d;

点 类型的数据结构是opencv中很重要的类型之一。


四,Size_

数据类型简介

该数据类型主要用来表示一定大小的矩形框,它的最主要的数据成员就是width和height了。在opencv1.x中和Size_有相同作用的数据结构就是CvSize和CvSize2D32f了。

类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template<typename _Tp> class CV_EXPORTS Size_
{
public:
typedef _Tp value_type;

//! various constructors
Size_();
Size_(_Tp _width, _Tp _height);
Size_(const Size_& sz);
Size_(const CvSize& sz);
Size_(const CvSize2D32f& sz);
Size_(const Point_<_Tp>& pt);

Size_& operator = (const Size_& sz);
//! the area (width*height)
_Tp area() const;

//! conversion of another data type.
template<typename _Tp2> operator Size_<_Tp2>() const;

//! conversion to the old-style OpenCV types
operator CvSize() const;
operator CvSize2D32f() const;

_Tp width, height; // the width and the height
};

当然同Point_一样,Size_也预定义了一些数据类型供我们使用

1
2
3
typedef Size_<int> Size2i;
typedef Size2i Size;
typedef Size_<float> Size2f;

该数据类型时opencv中我们最常用的数据类型之一。


五,Rect_,RotatedRect

数据类型简介

该类则是点Point和尺寸Size的合体了,代表着一副图像中在某个特定位置的矩形框。它最主要的数据成员就是(x, y, width, height),(x, y)表示矩形框左上顶点的位置,而RotatedRect则代表着一个旋转以后的矩形框,除了和矩形框拥有相同的(x, y, width, height)以外,还多了一个angel(旋转角度)的数据成员:
Alt text

类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
template<typename _Tp> class CV_EXPORTS Rect_
{
public:
typedef _Tp value_type;

//! various constructors
Rect_();
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
Rect_(const Rect_& r);
Rect_(const CvRect& 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;

//! conversion to another data type
template<typename _Tp2> operator Rect_<_Tp2>() const;
//! conversion to the old-style CvRect
operator CvRect() const;

//! checks whether the rectangle contains the point
bool contains(const Point_<_Tp>& pt) const;

_Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle
};

该模版类预定义了一些类,来供我们使用

1
typedef Rect_<int> Rect;

该类实例能够进行多种数学运算如下:

1
2
3
4
5
6
7
rect = rect + point (矩形位置平移)
rect = rect + size (扩大或缩小矩形)
rect += point, rect -= point, rect += size, rect -= size
rect = rect1 & rect2
rect = rect1 | rect2
rect &= rect1, rect |= rect1
rect == rect1, rect != rect1

该类型是opencv中最常用的数据类型之一。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 class CV_EXPORTS RotatedRect
{
public:
//! various constructors
RotatedRect();
RotatedRect(const Point2f& center, const Size2f& size, float angle);
RotatedRect(const CvBox2D& box);
//! returns 4 vertices of the rectangle
void points(Point2f pts[]) const;
//! returns the minimal up-right rectangle containing the rotated rectangle
Rect boundingRect() const;
//! conversion to the old-style CvBox2D structure
operator CvBox2D() const;
Point2f center; //< the rectangle mass center
Size2f size; //< width and height of the rectangle
float angle; //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
};

旋转矩形使用范例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
Mat image(200, 200, CV_8UC3, Scalar(0));
RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);

Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0));

Rect brect = rRect.boundingRect();
rectangle(image, brect, Scalar(255,0,0));

imshow("rectangles", image);
waitKey(0);


六,Mat, Matx, Mat_, SparseMat, SparseMat_

数据类型简介

矩阵是计算机视觉,计算机图像处理中最终要的概念。由于图像在计算机中都采用像素点来表示,一副图像是由width*height个像素点来组成,这所有的点组合起来就像是数学中的Mat(矩阵)。将矩阵的使用学好了,对于计算机图像处理,计算机视觉的认知就算是真正的开始了。毫无疑问,矩阵(Mat)这种数据类型是opencv最核心的数据类型,没有之一。然而为了应对各种图像的情况,opencv定义了多种类型的矩阵供我们使用。以下便让我一一介绍:

类定义

  • Mat(矩阵)
    该矩阵代表着n维数字类型的单通道或者是多通道的数组类型的数据。它可以存储实数或者是复数向量和矩阵,灰度图或者彩色图,立体像素卷,向量域,点云,直方图(高维的直方图最好用稀疏矩阵SparseMat来存储)等等。数组M的数据位置被数组M.step[]定义,所以访问矩阵中的M(i0,i1,···,in-1),就可以通过如下公式访问:
    = M.data + M.step[0]*i_0 + M.step[1]*i_1 + ... + M.step[M.dims-1]*i_{M.dims-1} ```
    1
    对于二维矩阵来说,访问其中的元素就是
    ```addr(M_{i,j}) = M.data + M.step[0]*i + M.step[1]*j

在opencv1.x中与矩阵Mat相对应的数据类型就是CvMat, IplImage, 和CvMatND等,其类定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 array dimensionality, >= 2
int dims;
//! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions
int rows, cols;
//! pointer to the data
uchar* data;

//! pointer to the reference counter;
// when array points to user-allocated data, the pointer is NULL
int* refcount;

// other members
...
};

一般情况下表示一副图像只需要二维矩阵就够了,要么一个像素点事灰度值,要么一个像素点是一个向量,存储rgb三色。
基本的构造一个Mat对象的方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// make a 7x7 complex matrix filled with 1+3j.
Mat M(7,7,CV_32FC2,Scalar(1,3));

// and now turn M to a 100x60 15-channel 8-bit matrix.
// The old content will be deallocated
M.create(100,60,CV_8UC(15));

// create a 100x100x100 8-bit array
int sz[] = {100, 100, 100};
Mat bigCube(3, sz, CV_8U, Scalar::all(0));
// add the 5-th row, multiplied by 3 to the 3rd row
M.row(3) = M.row(3) + M.row(5)*3;

// now copy the 7-th column to the 1-st column
// M.col(1) = M.col(7); // this will not work
Mat M1 = M.col(1);
M.col(7).copyTo(M1);

// create a new 320x240 image
Mat img(Size(320,240),CV_8UC3);
// select a ROI
Mat roi(img, Rect(10,10,100,100));
// fill the ROI with (0,255,0) (which is green in RGB space);
// the original 320x240 image will be modified
roi = Scalar(0,255,0);
Mat A = Mat::eye(10, 10, CV_32S);
// extracts A columns, 1 (inclusive) to 3 (exclusive).
Mat B = A(Range::all(), Range(1, 3));
// extracts B rows, 5 (inclusive) to 9 (exclusive).
// that is, C ~ A(Range(5, 9), Range(1, 3))
Mat C = B(Range(5, 9), Range::all());
Size size; Point ofs;
C.locateROI(size, ofs);
// size will be (width=10,height=10) and the ofs will be (x=1, y=5)

Mat的构造函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
C++: Mat::Mat()
C++: Mat::Mat(int rows, int cols, int type)
C++: Mat::Mat(Size size, int type)
C++: Mat::Mat(int rows, int cols, int type, const Scalar& s)
C++: Mat::Mat(Size size, int type, const Scalar& s)
C++: Mat::Mat(const Mat& m)
C++: Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
C++: Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
C++: Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all() )
C++: Mat::Mat(const Mat& m, const Rect& roi)
C++: Mat::Mat(const CvMat* m, bool copyData=false)
C++: Mat::Mat(const IplImage* img, bool copyData=false)
C++: template<typename T, int n> explicit Mat::Mat(const Vec<T, n>& vec, bool copyData=true)
C++: template<typename T, int m, int n> explicit Mat::Mat(const Matx<T, m, n>& vec, bool copyData=true)
C++: template<typename T> explicit Mat::Mat(const vector<T>& vec, bool copyData=false)
C++: Mat::Mat(int ndims, const int* sizes, int type)
C++: Mat::Mat(int ndims, const int* sizes, int type, const Scalar& s)
C++: Mat::Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0)
C++: Mat::Mat(const Mat& m, const Range* ranges)
Parameters:
ndims – Array dimensionality.
rows – Number of rows in a 2D array.
cols – Number of columns in a 2D array.
roi – Region of interest.
size – 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the number of columns go in the reverse order.
sizes – Array of integers specifying an n-dimensional array shape.
type – Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
s – An optional value to initialize each matrix element with. To set all the matrix elements to the particular value after the construction, use the assignment operator Mat::operator=(const Scalar& value) .
data – Pointer to the user data. Matrix constructors that take data and step parameters do not allocate matrix data. Instead, they just initialize the matrix header that points to the specified data, which means that no data is copied. This operation is very efficient and can be used to process external data using OpenCV functions. The external data is not automatically deallocated, so you should take care of it.
step – Number of bytes each matrix row occupies. The value should include the padding bytes at the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed and the actual step is calculated as cols*elemSize() . See Mat::elemSize() .
steps – Array of ndims-1 steps in case of a multi-dimensional array (the last step is always set to the element size). If not specified, the matrix is assumed to be continuous.
m – Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied by these constructors. Instead, the header pointing to m data or its sub-array is constructed and associated with it. The reference counter, if any, is incremented. So, when you modify the matrix formed using such a constructor, you also modify the corresponding elements of m . If you want to have an independent copy of the sub-array, use Mat::clone() .
img – Pointer to the old-style IplImage image structure. By default, the data is shared between the original image and the new matrix. But when copyData is set, the full copy of the image data is created.
vec – STL vector whose elements form the matrix. The matrix has a single column and the number of rows equal to the number of vector elements. Type of the matrix matches the type of vector elements. The constructor can handle arbitrary types, for which there is a properly declared DataType . This means that the vector elements must be primitive numbers or uni-type numerical tuples of numbers. Mixed-type structures are not supported. The corresponding constructor is explicit. Since STL vectors are not automatically converted to Mat instances, you should write Mat(vec) explicitly. Unless you copy the data into the matrix ( copyData=true ), no new elements will be added to the vector because it can potentially yield vector data reallocation, and, thus, the matrix data pointer will be invalid.
copyData – Flag to specify whether the underlying data of the STL vector or the old-style CvMat or IplImage should be copied to (true) or shared with (false) the newly constructed matrix. When the data is copied, the allocated buffer is managed using Mat reference counting mechanism. While the data is shared, the reference counter is NULL, and you should not deallocate the data until the matrix is not destructed.
rowRange – Range of the m rows to take. As usual, the range start is inclusive and the range end is exclusive. Use Range::all() to take all the rows.
colRange – Range of the m columns to take. Use Range::all() to take all the columns.
ranges – Array of selected ranges of m along each dimensionality.

Mat的其他各种成员方法见Mat详解

  • Matx(小矩阵)
    该类型的矩阵为能够确定类型,确定尺寸和确定编译时间的小矩阵。
    其基本定义如下;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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, 6> Matx16f;
    typedef Matx<double, 1, 6> Matx16d;

    typedef Matx<float, 2, 1> Matx21f;
    typedef Matx<double, 2, 1> Matx21d;
    ...
    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, 6, 6> Matx66f;
    typedef Matx<double, 6, 6> Matx66d;

使用范例如下:

1
2
3
4
Matx33f m(1, 2, 3,
4, 5, 6,
7, 8, 9)
;

cout << sum(Mat(m*m.t())) << endl;

  • Mat_

  • SparseMat(稀疏矩阵)

  • SparseMat_


七,Vec和Scalar_

数据类型简介

Vec是一个储存短数字类型的向量,相当于Matx的特例。
Scalar_是从Vec继承来的4元向量。

类定义

Vec有许多预定义的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template<typename _Tp, int n> class Vec : public Matx<_Tp, n, 1> {...};

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<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;

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;

因为Vec的特殊性质,Vec可以和Point_互相转换,而Vec可以和Point3_互相转换,而Vec则可以和CvScalar 或者是Scalar_互相转换,可以使用[]来访问Vec的数据。
以下是Vec的一些基本运算:

1
2
3
4
5
6
7
8
v1 = v2 + v3
v1 = v2 - v3
v1 = v2 * scale
v1 = scale * v2
v1 = -v2
v1 += v2 and other augmenting operations
v1 == v2, v1 != v2
norm(v1) (euclidean norm)

因为Scalar_是从Vec继承而来,而且Scalar_只能为4元向量。它与opencv1.x的CvScalar相对应,并且二者可以相互转化。Scalar_的主要作用是传递像素值。(rgbe)。
Scalar_的定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
template<typename _Tp> class CV_EXPORTS Scalar_ : public Vec<_Tp, 4>
{
public:
//! various constructors
Scalar_();
Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
Scalar_(const CvScalar& s);
Scalar_(_Tp v0);

//! returns a scalar with all elements set to v0
static Scalar_<_Tp> all(_Tp v0);
//! conversion to the old-style CvScalar
operator CvScalar() const;

//! conversion to another data type
template<typename T2> operator Scalar_<T2>() const;

//! per-element product
Scalar_<_Tp> mul(const Scalar_<_Tp>& t, 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;


八,Range

数据类型简介

该数据类型顾名思义表示的是一个范围,它的主要数据成员就是start和end,它和opencv1.x中的CvSlice相对应
,这个类的主要作用就相当于matlab矩阵中的:运算符,可以访问矩阵中的行或者列的范围。

类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
class CV_EXPORTS Range
{
public:
Range();
Range(int _start, int _end);
Range(const CvSlice& slice);
int size() const;
bool empty() const;
static Range all();
operator CvSlice() const;

int start, end;
};

九,Ptr

数据类型简介

在opencv2.x介绍中,已经说明opencv具有自动内存管理的功能。其实现自动内存管理功能的最主要的方式就是通过Ptr这个指针类来实现的,它相当于c++中的shared_ptr,具有引用计数的功能,当没有任何变量引用一块内存区域时,Ptr就会自动释放这块内存区域。

类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
template<typename _Tp> class Ptr
{
public:
// default constructor
Ptr();
// constructor that wraps the object pointer
Ptr(_Tp* _obj);
// destructor: calls release()
~Ptr();
// copy constructor; increments ptr's reference counter
Ptr(const Ptr& ptr);
// assignment operator; decrements own reference counter
// (with release()) and increments ptr's reference counter
Ptr& operator = (const Ptr& ptr);
// increments reference counter
void addref();
// decrements reference counter; when it becomes 0,
// delete_obj() is called
void release();
// user-specified custom object deletion operation.
// by default, "delete obj;" is called
void delete_obj();
// returns true if obj == 0;
bool empty() const;

// provide access to the object fields and methods
_Tp* operator -> ();
const _Tp* operator -> () const;

// return the underlying object pointer;
// thanks to the methods, the Ptr<_Tp> can be
// used instead of _Tp*
operator _Tp* ();
operator const _Tp*() const;
protected:
// the encapsulated object pointer
_Tp* obj;
// the associated reference counter
int* refcount;
};

通过使用Ptr < T > obj = new T()来声明一个变量,就会由Ptr来自动管理内存分配和释放。


十,InputArray和OutputArray

数据类型简介

InputArray是用来在opencv函数中用来传递只读参数的代理类。typedef const _InputArray& InputArray;,_InputArray是一个可以通过Mat,Mat__< T >,Matx,std::vector< T >,std::vector>或者std::vector< Mat >等数组类型的类来构造,所以当opencv函数中传递参数的数据类型不明确时,可以通过InputArray来作为代理。
例:
函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m)
{

// get Mat headers for input arrays. This is O(1) operation,
// unless _src and/or _m are matrix expressions.
Mat src = _src.getMat(), m = _m.getMat();
CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) );

// [re]create the output array so that it has the proper size and type.
// In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize.
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();

for( int i = 0; i < src.rows; i++ )
for( int j = 0; j < src.cols; j++ )
{
Point2f pt = src.at<Point2f>(i, j);
dst.at<Point2f>(i, j) = Point2f(m.at<float>(0, 0)*pt.x +
m.at<float>(0, 1)*pt.y +
m.at<float>(0, 2),
m.at<float>(1, 0)*pt.x +
m.at<float>(1, 1)*pt.y +
m.at<float>(1, 2));
}
}

当你使用这个函数时,可以将Mat,Mat__< T >,Matx,std::vector< T >,std::vector>或者std::vector< Mat >中的任意一个数据类型传递进去。这个特性与c++中的多态特性有些类似。
而OutputArray是从InputArray继承而来的。它的功能与InputArray类似。
这两个数据类型都有一个共同的限制就是:不要为这两个类显示的构造实例对象。简单来说,他们应该只出现在函数的形参声明中。

文章目录
  1. 1. 一,opencv模块core内容第一部分——Basic Structures(基本数据结构)
  2. 2. ">
  3. 3. 二,DataType
    1. 3.1. 数据类型简介:
    2. 3.2. 类定义
  4. 4. 三,Point_,Point3_
    1. 4.1. 数据类型简介
    2. 4.2. 类定义
  5. 5. 四,Size_
    1. 5.1. 数据类型简介
    2. 5.2. 类定义
  6. 6. 五,Rect_,RotatedRect
    1. 6.1. 数据类型简介
    2. 6.2. 类定义
  7. 7. 六,Mat, Matx, Mat_, SparseMat, SparseMat_
    1. 7.1. 数据类型简介
    2. 7.2. 类定义
  8. 8. 七,Vec和Scalar_
    1. 8.1. 数据类型简介
    2. 8.2. 类定义
  9. 9. 八,Range
    1. 9.1. 数据类型简介
    2. 9.2. 类定义
  10. 10. 九,Ptr
    1. 10.1. 数据类型简介
    2. 10.2. 类定义
  11. 11. 十,InputArray和OutputArray
    1. 11.1. 数据类型简介
,