編輯:關於android開發
本文的代碼基於OpenCV for Android 3.0
在opencv中,矩陣的類型結構被定義在opencv2/core/cvdef.h中,如下
#define CV_CN_MAX 512
#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
#define CV_8U 0
#define CV_8S 1
#define CV_16U 2
#define CV_16S 3
#define CV_32S 4
#define CV_32F 5
#define CV_64F 6
#define CV_USRTYPE1 7
#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1)
#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK)
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
#define CV_MAKE_TYPE CV_MAKETYPE
#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))
#define CV_8SC1 CV_MAKETYPE(CV_8S,1)
#define CV_8SC2 CV_MAKETYPE(CV_8S,2)
#define CV_8SC3 CV_MAKETYPE(CV_8S,3)
#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))
#define CV_16UC1 CV_MAKETYPE(CV_16U,1)
#define CV_16UC2 CV_MAKETYPE(CV_16U,2)
#define CV_16UC3 CV_MAKETYPE(CV_16U,3)
#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))
#define CV_16SC1 CV_MAKETYPE(CV_16S,1)
#define CV_16SC2 CV_MAKETYPE(CV_16S,2)
#define CV_16SC3 CV_MAKETYPE(CV_16S,3)
#define CV_16SC4 CV_MAKETYPE(CV_16S,4)
#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))
#define CV_32SC1 CV_MAKETYPE(CV_32S,1)
#define CV_32SC2 CV_MAKETYPE(CV_32S,2)
#define CV_32SC3 CV_MAKETYPE(CV_32S,3)
#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))
#define CV_32FC1 CV_MAKETYPE(CV_32F,1)
#define CV_32FC2 CV_MAKETYPE(CV_32F,2)
#define CV_32FC3 CV_MAKETYPE(CV_32F,3)
#define CV_32FC4 CV_MAKETYPE(CV_32F,4)
#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))
#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
#define CV_64FC2 CV_MAKETYPE(CV_64F,2)
#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))
可以看出都是通過一個CV_MAKETYPE宏定義的,該宏有兩個參數,第一個參數是數據位深度,不同數據結構的位深度的值在前面的宏中定義過了,比如
CV_8U 8位無符號整型(0-255)
CV_8S 8位有符號整型(-128-127)
CV_16U 16位無符號整型(0-65535)
CV_16S 16位有符號整型(-32768-32767)
CV_32S 32位有符號整型(-2147483648-2147483647)
CV_32F 32為浮點型
CV_64F 64位浮點型
Depth的最大值為8,一般0到7,即CV_8U到CV_USRTYPE1,這個可以從宏
#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
看出CV_DEPTH_MAX 的值,1左移3就是8,這個值需要占3位
第二個參數指明每個元素的通道數,每個元素至少需要有一個通道數,直接使用CV_8U這樣的類型表示的是一個通道
從宏
#define CV_CN_MAX 512
可以看出通道數最大是512,這個值需要占9位
而CV_MAKETYPE這個宏就是將位深度depth作為低3位,通道數作為高9位,總共需要12位,形成一個type值,即矩陣類型。具體的計算過程見上面定義的幾個宏CV_MAKETYPE,CV_MAT_DEPTH,CV_MAT_DEPTH_MASK
你會發現這個過程和Android中的MeasureSpec類是如此相似
DataType定義在opencv2/core/traits.hpp中,該類的作用主要是將一些基本數據類型轉換為opencv中的矩陣類型。這個類涉及到一個c++的模板的特性,有興趣搜索c++ traits,這裡給出兩篇參考文章
【C++模版之旅】神奇的Traits Step By Step(C++模板Trait)
class DataType
{
public:
typedef _Tp value_type;
typedef value_type work_type;
typedef value_type channel_type;
typedef value_type vec_type;
enum { generic_type = 1,
depth = -1,
channels = 1,
fmt = 0,
type = CV_MAKETYPE(depth, channels)
};
}; data-snippet-id=ext.2a994896399ad96d833d67a27fb86431 data-snippet-saved=false data-csrftoken=qu1mHaLb-2lWWzqJgazP6DNqD3Iwfex-lk4g data-codota-status=done>template class DataType
{
public:
typedef _Tp value_type;
typedef value_type work_type;
typedef value_type channel_type;
typedef value_type vec_type;
enum { generic_type = 1,
depth = -1,
channels = 1,
fmt = 0,
type = CV_MAKETYPE(depth, channels)
};
};
我們可以調用DataType::type、DataType::type類似的結構去獲得一個矩陣類型
內部有幾個c++模板類,定義在opencv2/core/types.hpp中
Point_是一個可以認為是一個點的封裝,內部具有x,y屬性,代表這個點的坐標,並重載了一些運算符
class Point_
{
public:
typedef _Tp value_type;
// various constructors
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 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, y; //< the point coordinates
}; data-snippet-id=ext.9ad91bcb13e3e3dd41769b98859c1abd data-snippet-saved=false data-csrftoken=P2nQ956w-8Zt1VN1_VOv5GK1N9IV8LOyjREU data-codota-status=done>template class Point_
{
public:
typedef _Tp value_type;
// various constructors
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 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, y; //< the point coordinates
};
同時用typedef重新定義了float,int,double類型的點,默認情況下我們使用的Point是整型的
Point2i; typedef Point_Point2f; typedef Point_ Point2d; typedef Point2i Point; data-snippet-id=ext.8e54bb674d2eab853d570de6e03a454a data-snippet-saved=false data-csrftoken=VZZywFoA-E-LOJ_Q_fOkmcDBQ0_Wedw_DQjg data-codota-status=done> typedef Point_Point2i; typedef Point_ Point2f; typedef Point_ Point2d; typedef Point2i Point;
當然為了兼容c,定義了對應的結構體,結構體中也有x,y兩個屬性,如果是c++,則在對應的宏中增加構造函數等定義
CvPoint(const cv::Point_<_Tp>& pt): x((int)pt.x), y((int)pt.y) {}
template
operator cv::Point_<_Tp>() const { return cv::Point_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y)); }
#endif
}
CvPoint; data-snippet-id=ext.ef183a310a00c3208b7fb44ff18ca032 data-snippet-saved=false data-csrftoken=PNKFP40T-hDksBTK93aUsqGKPmEyNjxbgGzA data-codota-status=done>typedef struct CvPoint
{
int x;
int y;
#ifdef __cplusplus
CvPoint(int _x = 0, int _y = 0): x(_x), y(_y) {}
template
CvPoint(const cv::Point_<_Tp>& pt): x((int)pt.x), y((int)pt.y) {}
template
operator cv::Point_<_Tp>() const { return cv::Point_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y)); }
#endif
}
CvPoint;
浮點型的對應定義
CvPoint2D32f(const cv::Point_<_Tp>& pt): x((float)pt.x), y((float)pt.y) {}
template
operator cv::Point_<_Tp>() const { return cv::Point_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y)); }
#endif
}
CvPoint2D32f;
typedef struct CvPoint2D64f
{
double x;
double y;
}
CvPoint2D64f;
data-snippet-id=ext.ee69b555c55597be8de0e453977fbed8 data-snippet-saved=false data-csrftoken=ulViCmHe-udteXXtPtr80p7kqi6-ulJzjgN0 data-codota-status=done>typedef struct CvPoint2D32f
{
float x;
float y;
#ifdef __cplusplus
CvPoint2D32f(float _x = 0, float _y = 0): x(_x), y(_y) {}
template
CvPoint2D32f(const cv::Point_<_Tp>& pt): x((float)pt.x), y((float)pt.y) {}
template
operator cv::Point_<_Tp>() const { return cv::Point_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y)); }
#endif
}
CvPoint2D32f;
typedef struct CvPoint2D64f
{
double x;
double y;
}
CvPoint2D64f;
立體空間的坐標系,也就是具有z坐標的定義
CvPoint3D32f(const cv::Point3_<_Tp>& pt): x((float)pt.x), y((float)pt.y), z((float)pt.z) {}
template
operator cv::Point3_<_Tp>() const { return cv::Point3_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y), cv::saturate_cast<_Tp>(z)); }
#endif
}
CvPoint3D32f;
typedef struct CvPoint3D64f
{
double x;
double y;
double z;
}
CvPoint3D64f; data-snippet-id=ext.d874774d1168b6b7ddf48f7733fabc49 data-snippet-saved=false data-csrftoken=MwfpzAus-PKDIcqvn7si5BnzTf0GcsufhE-0 data-codota-status=done>typedef struct CvPoint3D32f
{
float x;
float y;
float z;
#ifdef __cplusplus
CvPoint3D32f(float _x = 0, float _y = 0, float _z = 0): x(_x), y(_y), z(_z) {}
template
CvPoint3D32f(const cv::Point3_<_Tp>& pt): x((float)pt.x), y((float)pt.y), z((float)pt.z) {}
template
operator cv::Point3_<_Tp>() const { return cv::Point3_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y), cv::saturate_cast<_Tp>(z)); }
#endif
}
CvPoint3D32f;
typedef struct CvPoint3D64f
{
double x;
double y;
double z;
}
CvPoint3D64f;
當然對應的c++中肯定是有這個類的
template 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 Vec<_Tp, 3>& v);
Point3_& operator = (const Point3_& pt);
//! conversion to another data type
template 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, y, z; //< the point coordinates
};
同樣用typedef定義了int,float,double類型
Point3i; typedef Point3_Point3f; typedef Point3_ Point3d; data-snippet-id=ext.a4d06b1c26dc649348129bcd20c472a8 data-snippet-saved=false data-csrftoken=QRWEKjBg-FNUCNRd2xYlSslh9g31PRCaa0zY data-codota-status=done> typedef Point3_Point3i; typedef Point3_ Point3f; typedef Point3_ Point3d;
除了點,還有一個Size,裡面有兩個屬性,width和height屬性,內部結構和Point類的定義十分相似,還有對應的結構體CvSize
class Size_
{
public:
typedef _Tp value_type;
//! various constructors
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;
//! conversion of another data type.
template operator Size_<_Tp2>() const;
_Tp width, height; // the width and the height
}; data-snippet-id=ext.576291eed6f24947a834f2006ebfda5b data-snippet-saved=false data-csrftoken=kjM8pn3C-tcMP6-0HP2kG0oxIFc1OzQXvbN0 data-codota-status=done>template class Size_
{
public:
typedef _Tp value_type;
//! various constructors
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;
//! conversion of another data type.
template operator Size_<_Tp2>() const;
_Tp width, height; // the width and the height
};
Size2i; typedef Size_Size2f; typedef Size_ Size2d; typedef Size2i Size; data-snippet-id=ext.0f6294d4ed8a3a7c808b72b4bf7ce33c data-snippet-saved=false data-csrftoken=GkEJRfWX-_uPJ3TKfbPUeFCL8hQfrWmU29GE data-codota-status=done> typedef Size_Size2i; typedef Size_ Size2f; typedef Size_ Size2d; typedef Size2i Size;
CvSize(const cv::Size_<_Tp>& sz): width(cv::saturate_cast(sz.width)), height(cv::saturate_cast(sz.height)) {}
template
operator cv::Size_<_Tp>() const { return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(width), cv::saturate_cast<_Tp>(height)); }
#endif
}
CvSize;
typedef struct CvSize2D32f
{
float width;
float height;
#ifdef __cplusplus
CvSize2D32f(float w = 0, float h = 0): width(w), height(h) {}
template
CvSize2D32f(const cv::Size_<_Tp>& sz): width(cv::saturate_cast(sz.width)), height(cv::saturate_cast(sz.height)) {}
template
operator cv::Size_<_Tp>() const { return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(width), cv::saturate_cast<_Tp>(height)); }
#endif
}
CvSize2D32f; data-snippet-id=ext.7d0d6f1883d595241a17595907879900 data-snippet-saved=false data-csrftoken=Cxoq0Hnt-vAkLiPfopNe3wlTwszuCAoik0xM data-codota-status=done>typedef struct CvSize
{
int width;
int height;
#ifdef __cplusplus
CvSize(int w = 0, int h = 0): width(w), height(h) {}
template
CvSize(const cv::Size_<_Tp>& sz): width(cv::saturate_cast(sz.width)), height(cv::saturate_cast(sz.height)) {}
template
operator cv::Size_<_Tp>() const { return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(width), cv::saturate_cast<_Tp>(height)); }
#endif
}
CvSize;
typedef struct CvSize2D32f
{
float width;
float height;
#ifdef __cplusplus
CvSize2D32f(float w = 0, float h = 0): width(w), height(h) {}
template
CvSize2D32f(const cv::Size_<_Tp>& sz): width(cv::saturate_cast(sz.width)), height(cv::saturate_cast(sz.height)) {}
template
operator cv::Size_<_Tp>() const { return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(width), cv::saturate_cast<_Tp>(height)); }
#endif
}
CvSize2D32f;
下面這個類基本上算具備了Point和Size的所有屬性,可以認為它是一個矩形,一旦有矩形左上角的坐標,以及寬度和高度,就可以表示這個矩形了。
class Rect_
{
public:
typedef _Tp value_type;
//! various constructors
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;
//! conversion to another data type
template operator Rect_<_Tp2>() 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
}; data-snippet-id=ext.df1c91a854cd2cc6c7c907c289768269 data-snippet-saved=false data-csrftoken=kDSI6C8l-243AnOZAvBIYb7yNLCHr-nDSrgM data-codota-status=done>template class Rect_
{
public:
typedef _Tp value_type;
//! various constructors
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;
//! conversion to another data type
template operator Rect_<_Tp2>() 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
};
Rect2i; typedef Rect_Rect2f; typedef Rect_ Rect2d; typedef Rect2i Rect; data-snippet-id=ext.1bdbca0808297e758a3e304eb1e6eb3a data-snippet-saved=false data-csrftoken=I2stmttR-N3X-flg3m7DFpsAlRLeALiu1Sns data-codota-status=done> typedef Rect_Rect2i; typedef Rect_ Rect2f; typedef Rect_ Rect2d; typedef Rect2i Rect;
CvRect(const cv::Rect_<_Tp>& r): x(cv::saturate_cast(r.x)), y(cv::saturate_cast(r.y)), width(cv::saturate_cast(r.width)), height(cv::saturate_cast(r.height)) {}
template
operator cv::Rect_<_Tp>() const { return cv::Rect_<_Tp>((_Tp)x, (_Tp)y, (_Tp)width, (_Tp)height); }
#endif
}
CvRect; data-snippet-id=ext.a8a0369ab3231ffce44624d0ac3e078b data-snippet-saved=false data-csrftoken=oq4gkq2q-3Dy_K2erQTi7OIn7Q57T6jkdAic data-codota-status=done>typedef struct CvRect
{
int x;
int y;
int width;
int height;
#ifdef __cplusplus
CvRect(int _x = 0, int _y = 0, int w = 0, int h = 0): x(_x), y(_y), width(w), height(h) {}
template
CvRect(const cv::Rect_<_Tp>& r): x(cv::saturate_cast(r.x)), y(cv::saturate_cast(r.y)), width(cv::saturate_cast(r.width)), height(cv::saturate_cast(r.height)) {}
template
operator cv::Rect_<_Tp>() const { return cv::Rect_<_Tp>((_Tp)x, (_Tp)y, (_Tp)width, (_Tp)height); }
#endif
}
CvRect;
Scalar_ 是一個四維向量,暫時你可以認為在使用顏色時,一個argb表示的顏色具有a,r,g,b四個值,剛好可以由Scalar_ 內部的四個屬性表示
class Scalar_ : public Vec<_Tp, 4>
{
public:
//! various constructors
Scalar_();
Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
Scalar_(_Tp v0);
template
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 operator Scalar_() 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;
}; data-snippet-id=ext.445f3c95331e9023550c1833aefe8671 data-snippet-saved=false data-csrftoken=Hd2HWKI5-awPwABGMxK8HMpwks_jzb5LPpLs data-codota-status=done>template class Scalar_ : public Vec<_Tp, 4>
{
public:
//! various constructors
Scalar_();
Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
Scalar_(_Tp v0);
template
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 operator Scalar_() 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
typedef Scalar_ Scalar;
對應的結構體數據結構
CvScalar(const cv::Scalar_<_Tp>& s) { val[0] = s.val[0]; val[1] = s.val[1]; val[2] = s.val[2]; val[3] = s.val[3]; }
template
operator cv::Scalar_<_Tp>() const { return cv::Scalar_<_Tp>(cv::saturate_cast<_Tp>(val[0]), cv::saturate_cast<_Tp>(val[1]), cv::saturate_cast<_Tp>(val[2]), cv::saturate_cast<_Tp>(val[3])); }
template
CvScalar(const cv::Vec<_Tp, cn>& v)
{
int i;
for( i = 0; i < (cn < 4 ? cn : 4); i++ ) val[i] = v.val[i];
for( ; i < 4; i++ ) val[i] = 0;
}
#endif
}
CvScalar; data-snippet-id=ext.d501003c0d6e352f1247d0d2d0fc5e29 data-snippet-saved=false data-csrftoken=QYL4BKw8-rwUPpp78JnuYY37lFbGy41y_kzo data-codota-status=done>typedef struct CvScalar
{
double val[4];
#ifdef __cplusplus
CvScalar() {}
CvScalar(double d0, double d1 = 0, double d2 = 0, double d3 = 0) { val[0] = d0; val[1] = d1; val[2] = d2; val[3] = d3; }
template
CvScalar(const cv::Scalar_<_Tp>& s) { val[0] = s.val[0]; val[1] = s.val[1]; val[2] = s.val[2]; val[3] = s.val[3]; }
template
operator cv::Scalar_<_Tp>() const { return cv::Scalar_<_Tp>(cv::saturate_cast<_Tp>(val[0]), cv::saturate_cast<_Tp>(val[1]), cv::saturate_cast<_Tp>(val[2]), cv::saturate_cast<_Tp>(val[3])); }
template
CvScalar(const cv::Vec<_Tp, cn>& v)
{
int i;
for( i = 0; i < (cn < 4 ? cn : 4); i++ ) val[i] = v.val[i];
for( ; i < 4; i++ ) val[i] = 0;
}
#endif
}
CvScalar;
Scalar類繼承了Vec類,Vec被定義在opencv2/core/matx.hpp中,它表示向量
class Vec : public Matx<_Tp, cn, 1>
{
public:
typedef _Tp value_type;
enum { depth = Matx<_Tp, cn, 1>::depth,
channels = cn,
type = CV_MAKETYPE(depth, channels)
};
//! default constructor
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;
//! conversion to another data type
template operator Vec() 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 Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp);
}; data-snippet-id=ext.9fbeff498f6c5d474948fb6f521eb6c2 data-snippet-saved=false data-csrftoken=pkNaj3ui-Zb7fMfUOVQ4GPVvPqUhpPe0W_XU data-codota-status=done>template class Vec : public Matx<_Tp, cn, 1>
{
public:
typedef _Tp value_type;
enum { depth = Matx<_Tp, cn, 1>::depth,
channels = cn,
type = CV_MAKETYPE(depth, channels)
};
//! default constructor
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;
//! conversion to another data type
template operator Vec() 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 Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp);
};
用typedef定義了很多類型。。。
Vec2b; typedef VecVec3b; typedef Vec Vec4b; typedef Vec Vec2s; typedef Vec Vec3s; typedef Vec Vec4s; typedef Vec Vec2w; typedef Vec Vec3w; typedef Vec Vec4w; typedef Vec Vec2i; typedef Vec Vec3i; typedef Vec Vec4i; typedef Vec Vec6i; typedef Vec Vec8i; typedef Vec Vec2f; typedef Vec Vec3f; typedef Vec Vec4f; typedef Vec Vec6f; typedef Vec Vec2d; typedef Vec Vec3d; typedef Vec Vec4d; typedef Vec Vec6d; data-snippet-id=ext.e6b8d44a1c35142a61c410e5dcc324f2 data-snippet-saved=false data-csrftoken=1jzjQxZO-iiqj3w7CQkjFegcev0mSGbXLkCE data-codota-status=done> typedef VecVec2b; typedef Vec Vec3b; typedef Vec Vec4b; typedef Vec Vec2s; typedef Vec Vec3s; typedef Vec Vec4s; typedef Vec Vec2w; typedef Vec Vec3w; typedef Vec Vec4w; typedef Vec Vec2i; typedef Vec Vec3i; typedef Vec Vec4i; typedef Vec Vec6i; typedef Vec Vec8i; typedef Vec Vec2f; typedef Vec Vec3f; typedef Vec Vec4f; typedef Vec Vec6f; typedef Vec Vec2d; typedef Vec Vec3d; typedef Vec Vec4d; typedef Vec Vec6d;
除了這些類之外,這幾個頭文件中還定義了很多其他的基本數據類型,有興趣自行查看
javascript基礎【一】
javascript基礎【一】2015/11/13 16:10:04javascript自誕生之初就處於爭論之中,但是這依舊不影響其成為今天WEB編程的主流語言。最初的j
Android 貝塞爾曲線的淺析,android貝塞爾淺析
Android 貝塞爾曲線的淺析,android貝塞爾淺析博客也開了挺長時間了,一直都沒有來寫博客,主要原因是自己懶~~~此篇博客算是給2017年一個好的開始,同時也給2
《Android Studio實用指南》8.20 提煉接口
《Android Studio實用指南》8.20 提煉接口 提煉接口重構是從一個已存在的類中提煉接口,它可以從某個類中選擇方法,把選中的方法提取到一個單獨的接口中. 操
在android中使用SQLite數據庫
在android中使用SQLite數據庫 SQLite數據庫以其輕量、體積小等特點,使其在開發中運用的非常廣泛,在前面的博客中我也介紹過在Cocos2d-x中使用SQ