/*********************************************************************************************
程序功能:
OpenCv的基本数据结构源代码的解读,我们常用的OpenCv的基本数据结构有六种:
1--Point类
2--Size类
3--Rect类
4--Scalar类
5--Vec3b--向量模板类
6--Range类
编写环境:
OpenCv2.4.8+VS2010
地点时间:
陕西师范大学 2016.4.23
作者信息:
九月
**********************************************************************************************/
(一)OpenCv的基本数据类型简述
OpenCv提供了多种基本的数据类型,虽然这些类型在C/C++中不是基本的数据类型,但是它们的结构都很简单,
我们可以将它们视为原子类型.它们的源代码所在的目录如下所示(对于我来说,我的OpenCv装在C盘):
C:\Program Files\opencv\build\include\opencv2\core\core.hpp(C++版本)
C:\Program Files\opencv\build\include\opencv2\core\core_c.h(C语言版本)
(一)OpenCv中点的表示--------Point类源代码分析
在这些数据类型中,最简单的就是Point点类,Point类是一个包含两个整形数据成员x和y的以及一些简单成员
方法的类类型,和它有关的好几个Point点类的变种如下所示:
//【1】Point2f----二维单精度浮点型点类
//【2】Point2d----二维双精度浮点型点类
//【3】Point3i----三维整形点类
********************************************************************************************
其源代码如下所示:
typedef Point_<int> Point2i;
typedef Point2i Point;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point3_<int> Point3i;
typedef Point3_<float> Point3f;
typedef Point3_<double> Point3d;
/**********************************************************************************************
template 2D point class.
The class defines a point in 2D space. Data type of the point coordinates is specified
as a template parameter. There are a few shorter aliases available for user convenience.
See cv::Point, cv::Point2i, cv::Point2f and cv::Point2d.
**********************************************************************************************/
/**********************************************************************************************
*【1】二维空间中,点的类模板
*【2】这个类定义了一个二维空间中的点,这个点的坐标可以被作为一个模板参数被指定.
*【3】这个类也有一些比较短的别名可以方便用户的使用,比如:
* cv::Point, cv::Point2i, cv::Point2f and cv::Point2d
*
**********************************************************************************************/
//【1】这是一个典型的类模板
template<typename _Tp> class Point_
{
public:
typedef _Tp value_type;
// various constructors
//【1】各种构造函数
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
//【2】函数模板--转换为另一种类型
template<typename _Tp2> operator Point_<_Tp2>() const;
//! conversion to the old-style C structures
//【3】转换为旧式风格的C的结构体
operator CvPoint() const;
operator CvPoint2D32f() const;
operator Vec<_Tp, 2>() const;
//! dot product
//【4】点积运算
_Tp dot(const Point_& pt) const;
//! dot product computed in double-precision arithmetics
double ddot(const Point_& pt) const;
//! cross-product
//【5】向量积运算
double cross(const Point_& pt) const;
//! checks whether the point is inside the specified rectangle
//【6】判断当前这个点是否在指定的矩形之内
bool inside(const Rect_<_Tp>& r) const;
//【7】这是这个Point类模板最重要的两个信息------Point点的x和y坐标
_Tp x, y; //< the point coordinates
};
/**********************************************************************************************
template 3D point class----------【1】三维空间的点类
【2】比如点类---Point3i,Point3f,Point3d
The class defines a point in 3D space. Data type of the point coordinates is specified
as a template parameter.
see cv::Point3i, cv::Point3f and cv::Point3d
**********************************************************************************************/
template<typename _Tp> class 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
};
(二)OpenCv中尺寸的表示--------Size类源代码分析
OpenCv中尺寸Size类与点Point类的表示十分类似,最主要的区别是,Size(尺寸)类的数据成员是width和
height,而Point类的数据成员是坐标点
********************************************************************************************
其源代码如下所示:
typedef Size_<int> Size2i;
typedef Size2i Size;
typedef Size_<float> Size2f;
/**********************************************************************************************
The 2D size class
The class represents the size of a 2D rectangle, image size, matrix size etc.
Normally, cv::Size ~ cv::Size_ is used.
**********************************************************************************************/
/**********************************************************************************************
*【1】二维空间中,尺寸Size类的表示
*【2】这个类用于描述一个二维矩阵的大小,比如:
* 1--图像的大小
* 2--矩阵的大小
*【3】我们同样适用的尺寸Size类----是---cv::Size类
**********************************************************************************************/
template<typename _Tp> class Size_
{
public:
typedef _Tp value_type;
//! various constructors
//【1】-------------------------Size类(尺寸类)的各种构造函数-----------------------------
//【1】默认构造函数
Size_();
//【2】指定宽和高的Size类的构造函数
Size_(_Tp _width, _Tp _height);
Size_(const Size_& sz);
Size_(const CvSize& sz);
Size_(const CvSize2D32f& sz);
Size_(const Point_<_Tp>& pt);
//【2】------------------------------------成员函数--------------------------------------
//【1】重载=号运算符,判断两个Size是否相等
Size_& operator = (const Size_& sz);
//! the area (width*height)
//【2】计算Size类所描述的那个区域的--面积
_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;
//【3】------------------------------------类的数据成员----------------------------------
//【1】Size模板类中,最重要的两个数据成员----宽和高
_Tp width, height; // the width and the height
};
(三)OpenCv中矩形的表示--------Rect类源代码分析
Rect矩形类,它有四个很重要的数据成员x,y,width,height,分别代表这个矩形左上角的坐标点和矩形
的宽度和高度,并且Rect类提供了很实用的一些成员方法,比如说:求左上角和右下角的成员函数,等等
********************************************************************************************
其源代码如下所示:
typedef Rect_<int> Rect;
/**********************************************************************************************
*【1】二维空间中,矩形Rect类的表示
*【2】这个类用指定数据类型的坐标描述一个二维的矩形
**********************************************************************************************/
/**********************************************************************************************
The 2D up-right rectangle class
The class represents a 2D rectangle with coordinates of the specified data type.
Normally, cv::Rect ~ cv::Rect_ is used.
**********************************************************************************************/
/******************************【矩形类Rect所对应的类模板】***********************************/
template<typename _Tp> class Rect_
{
public:
typedef _Tp value_type;
//! various constructors
//【1】默认构造函数
Rect_();
//【2】指定左上角坐标点和矩形的宽和高的构造函数-------------很重要的构造函数
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);
//【2】--------------------------------矩形Rect模板类的成员函数-----------------------------
//【1】运算符重载
Rect_& operator = ( const Rect_& r );
//! the top-left corner
//【2】表示矩形左上角的坐标点
Point_<_Tp> tl() const;
//! the bottom-right corner
//【3】表示矩形右下角的坐标点
Point_<_Tp> br() const;
//! size (width, height) of the rectangle
//【4】矩形的尺寸
Size_<_Tp> size() const;
//! area (width*height) of the rectangle
//【5】矩形的面积
_Tp area() const;
//! conversion to another data type
//【6】函数模板---转换为其他类型
template<typename _Tp2> operator Rect_<_Tp2>() const;
//! conversion to the old-style CvRect
operator CvRect() const;
//! checks whether the rectangle contains the point
//【7】判断矩形是否包含这个点
bool contains(const Point_<_Tp>& pt) const;
//【3】---------------------------------矩形模板类的数据成员---------------------------------
//【1】x,y----矩形Rect左上角的坐标
//【2】widht,height---矩形的宽和高
_Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle
};
(四)OpenCv中颜色的表示--------Scalar类源代码分析
typedef Scalar_<double> Scalar;
/**********************************************************************************************
The template scalar class.
This is partially specialized cv::Vec class with the number of elements = 4, i.e. a short vector of four elements.
Normally, cv::Scalar ~ cv::Scalar_ is used.
**********************************************************************************************/
/**********************************************************************************************
*【1】Scalar类的--类模板
*【2】这是一个使用4个元素指定的特殊的Vec向量类模板的类模板
*【3】通常使用的是--cv::Scalar
*【3】其实也就是说---Scalar颜色类---是一个特殊的----向量类
**********************************************************************************************/
template<typename _Tp> class Scalar_ : public Vec<_Tp, 4>
{
public:
//! various constructors
//【1】默认构造函数
Scalar_();
//【2】很重要的一个默认构造函数
//【3】这个默认构造函数的四个参数分别表示RGB+Alpha颜色中的:
//【1】v0---表示RGB中的------blue-----B---蓝色分量
//【2】v1---表示RGB中的------Green----G---绿色分量
//【3】v2---表示RGB中的------Red------R---红色分量
//【4】v3---表示Alpha---------------------透明色分量
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
//【2】------------------------------成员函数--------------------------------------
//【1】返回一个用v0设置所有颜色的Scalar类
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;
};
(五)OpenCv中向量模板类Vec的表示--------Vec2b,Vec3b,Vec2s,Vec3s类源代码分析
*******************************************************************************************************************************
*【1】Vec---是一个OpenCv的---向量类模板(向量模板类)----我比较喜欢Vec把称作向量类模板,这是因为“向量类”--首相说明Vec---它是一个类,、
* 然后"模板"---说明它是一个---模板类
*【2】Vec---向量类模板的类模板原型:
* template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
*【3】我们可以看得出,它其实就是一个“一维的矩阵”,这是因为:
* 1--在OpenCv中没有向量(vector)结构,任何时候需要向量,都只需要一个列矩阵(如果需要一个转置或者共轭向量,则需要一个行向量)
* 2--OpenCv矩阵的概念与我们线性代数课上学习的概念相比,更加抽象,这是因为线性代数中的矩阵,矩阵中的矩阵元素只能存储--数值型数
* 据,而OpenCv不是这样的
*【4】Vec<int,n>---就是用类型int和将向量模板类做一个实例化,实例化为一个具体的类.其中,第一个参数int--表示Vec中存储的为int类型;第二
* 个参数n为一个整型值,表示Vec每个对象中存储n个int值,也就是---n维向量(列向量)
*******************************************************************************************************************************
//【1】下面是OpenCv中定义---定义---向量模板类----的源代码
//【2】一个拥有非类型模板形参的---类模板-----向量模板类
template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
{
public:
typedef _Tp value_type;
enum { depth = DataDepth<_Tp>::value, channels = cn, type = CV_MAKETYPE(depth, channels) };
//! default constructor
//【1】向量类的默认构造函数
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
explicit Vec(const _Tp* values);
Vec(const Vec<_Tp, cn>& v);
static Vec all(_Tp alpha);
//! per-element multiplication
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;
//! convertion to another data type
template<typename T2> operator Vec<T2, cn>() const;
//! conversion to 4-element CvScalar.
operator CvScalar() 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);
};
//【3】用typedef关键字给---向量类模板----template class Vec
//【1】向量模板类Vec的实例化,并且给相应实例的Vec向量模板类实例---指定新的名字
//【1】Vec2b--这是一个具体的--类类型---这个类类型实例话的类对象表示如下所示:
//【1】Vec2b---表示每个Vec2b对象中,可以存储2个char(字符型)数据
typedef Vec<uchar, 2> Vec2b; 、
//【2】Vec3b---表示每一个Vec3b对象中,可以存储3个char(字符型)数据,比如可以用这样的对象,去存储RGB图像中的
//一个像素点
typedef Vec<uchar, 3> Vec3b;
//【3】Vec4b---表示每一个Vec4b对象中,可以存储4个字符型数据,可以用这样的类对象去存储---4通道RGB+Alpha的图
//像中的像素点
typedef Vec<uchar, 4> Vec4b;
//【1】Vec2s---表示这个类的每一个类对象,可以存储2个short int(短整型)的数据
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;
(六)OpenCv中Range类作用的详解
******************************************************************************************
*功能描述:
* 这个类的作用是:用于指定一个连续的子序列例如一个轮廓的一部分,或者一个矩阵的列空间
******************************************************************************************
其源代码如下所示:
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;
};
******************************************************************************************
示例:
//【10】指定的src图像的区域包括图像的所有行和从第0列到第199列
Mat dstRange=src(Range::all(),Range(0,200));
namedWindow(WINDOW_RANGE_NAME,CV_WINDOW_AUTOSIZE);
imshow(WINDOW_RANGE_NAME,dstRange);