1. 程式人生 > >OpenCv學習筆記(三)---OpenCv中基本資料型別--Point,Size,Rect,Scalar,Vec3b類型別的詳細解釋及其OpenCv中原始碼的詳細分析

OpenCv學習筆記(三)---OpenCv中基本資料型別--Point,Size,Rect,Scalar,Vec3b類型別的詳細解釋及其OpenCv中原始碼的詳細分析

/*********************************************************************************************
程式功能:
        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_<int> 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_<int> 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_<double> 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<typename _Tp, int cn> 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);