Android OpenCV中的几种基本数据结构

本文的代码基于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_MAKETYPECV_MAT_DEPTHCV_MAT_DEPTH_MASK

你会发现这个过程和Android中的MeasureSpec类是如此相似

DataType模板类

DataType定义在opencv2/core/traits.hpp中,该类的作用主要是将一些基本数据类型转换为opencv中的矩阵类型。这个类涉及到一个c++的模板的特性,有兴趣搜索c++ traits,这里给出两篇参考文章

 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<typename _Tp> 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类似的结构去获得一个矩阵类型

Point_等模板类

内部有几个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_& sz);
    Point_(const Vec& v);

    Point_& operator = (const Point_& pt);
    //! conversion to another data type
    template operator Point_() const;

    //! conversion to the old-style C structures
    operator Vec() 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_& r) const;

    _Tp x, y; //template<typename _Tp> 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<typename _Tp2> 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_<int> Point2i;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point2i Point;

当然为了兼容c,定义了对应的结构体,结构体中也有x,y两个属性,如果是c++,则在对应的宏中增加构造函数等定义

    CvPoint(const cv::Point_& pt): x((int)pt.x), y((int)pt.y) {}
    template
    operator cv::Point_() const { return cv::Point_(cv::saturate_cast(x), cv::saturate_cast(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<typename _Tp>
    CvPoint(const cv::Point_<_Tp>& pt): x((int)pt.x), y((int)pt.y) {}
    template<typename _Tp>
    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_& pt): x((float)pt.x), y((float)pt.y) {}
    template
    operator cv::Point_() const { return cv::Point_(cv::saturate_cast(x), cv::saturate_cast(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<typename _Tp>
    CvPoint2D32f(const cv::Point_<_Tp>& pt): x((float)pt.x), y((float)pt.y) {}
    template<typename _Tp>
    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_& pt): x((float)pt.x), y((float)pt.y), z((float)pt.z) {}
    template
    operator cv::Point3_() const { return cv::Point3_(cv::saturate_cast(x), cv::saturate_cast(y), cv::saturate_cast(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<typename _Tp>
    CvPoint3D32f(const cv::Point3_<_Tp>& pt): x((float)pt.x), y((float)pt.y), z((float)pt.z) {}
    template<typename _Tp>
    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<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 Vec<_Tp, 3>& v);

    Point3_& operator = (const Point3_& pt);
    //! 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, 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_<int> Point3i;
typedef Point3_<float> Point3f;
typedef Point3_<double> 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_& pt);

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

    //! conversion of another data type.
    template operator Size_() 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<typename _Tp> 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<typename _Tp2> 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_<int> Size2i;
typedef Size_<float> Size2f;
typedef Size_<double> Size2d;
typedef Size2i Size;
    CvSize(const cv::Size_& sz): width(cv::saturate_cast(sz.width)), height(cv::saturate_cast(sz.height)) {}
    template
    operator cv::Size_() const { return cv::Size_(cv::saturate_cast(width), cv::saturate_cast(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_& sz): width(cv::saturate_cast(sz.width)), height(cv::saturate_cast(sz.height)) {}
    template
    operator cv::Size_() const { return cv::Size_(cv::saturate_cast(width), cv::saturate_cast(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<typename _Tp>
    CvSize(const cv::Size_<_Tp>& sz): width(cv::saturate_cast<int>(sz.width)), height(cv::saturate_cast<int>(sz.height)) {}
    template<typename _Tp>
    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<typename _Tp>
    CvSize2D32f(const cv::Size_<_Tp>& sz): width(cv::saturate_cast<float>(sz.width)), height(cv::saturate_cast<float>(sz.height)) {}
    template<typename _Tp>
    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_& org, const Size_& sz);
    Rect_(const Point_& pt1, const Point_& pt2);

    Rect_& operator = ( const Rect_& r );
    //! the top-left corner
    Point_ tl() const;
    //! the bottom-right corner
    Point_ br() const;

    //! size (width, height) of the rectangle
    Size_ size() const;
    //! area (width*height) of the rectangle
    _Tp area() const;

    //! conversion to another data type
    template operator Rect_() const;

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

    _Tp x, y, width, height; //template<typename _Tp> 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<typename _Tp2> 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_<int> Rect2i;
typedef Rect_<float> Rect2f;
typedef Rect_<double> Rect2d;
typedef Rect2i Rect;
    CvRect(const cv::Rect_& 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_() const { return cv::Rect_((_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<typename _Tp>
    CvRect(const cv::Rect_<_Tp>& r): x(cv::saturate_cast<int>(r.x)), y(cv::saturate_cast<int>(r.y)), width(cv::saturate_cast<int>(r.width)), height(cv::saturate_cast<int>(r.height)) {}
    template<typename _Tp>
    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
{
public:
    //! various constructors
    Scalar_();
    Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
    Scalar_(_Tp v0);

    template
    Scalar_(const Vec& v);

    //! returns a scalar with all elements set to v0
    static Scalar_ all(_Tp v0);

    //! conversion to another data type
    template operator Scalar_() const;

    //! per-element product
    Scalar_ mul(const Scalar_& a, double scale=1 ) const;

    // returns (v0, -v1, -v2, -v3)
    Scalar_ 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<typename _Tp> 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<typename _Tp2, int cn>
    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<typename T2> operator Scalar_<T2>() 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_<double> Scalar;

对应的结构体数据结构

    CvScalar(const cv::Scalar_& 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_() const { return cv::Scalar_(cv::saturate_cast(val[0]), cv::saturate_cast(val[1]), cv::saturate_cast(val[2]), cv::saturate_cast(val[3])); }
    template
    CvScalar(const cv::Vec& v)
    {
        int i;
        for( i = 0; i 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<typename _Tp>
    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<typename _Tp>
    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<typename _Tp, int cn>
    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
{
public:
    typedef _Tp value_type;
    enum { depth    = Matx::depth,
           channels = cn,
           type     = CV_MAKETYPE(depth, channels)
         };

    //! default constructor
    Vec();

    Vec(_Tp v0); //!& v);

    static Vec all(_Tp alpha);

    //! per-element multiplication
    Vec mul(const Vec& 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& a, const Matx& b, Matx_AddOp);
    Vec(const Matx& a, const Matx& b, Matx_SubOp);
    template Vec(const Matx& a, _T2 alpha, Matx_ScaleOp);
};" data-snippet-id="ext.9fbeff498f6c5d474948fb6f521eb6c2" data-snippet-saved="false" data-csrftoken="pkNaj3ui-Zb7fMfUOVQ4GPVvPqUhpPe0W_XU" data-codota-status="done">template<typename _Tp, int cn> 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<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);
};

用typedef定义了很多类型。。。

 Vec2b;
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;
" data-snippet-id="ext.e6b8d44a1c35142a61c410e5dcc324f2" data-snippet-saved="false" data-csrftoken="1jzjQxZO-iiqj3w7CQkjFegcev0mSGbXLkCE" data-codota-status="done">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;

除了这些类之外,这几个头文件中还定义了很多其他的基本数据类型,有兴趣自行查看

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-27 22:07:09

Android OpenCV中的几种基本数据结构的相关文章

android开发中的5种存储数据方式

数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences存储数据 SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在Activity中 重载窗口状态onSaveInstance State保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整

Android开发中退出程序几种方法

参考:http://johncookie.iteye.com/blog/890734 Android程序有很多Activity,比如说主窗口A,调用了子窗口B,子窗口B又调用子窗口C,back返回子窗口B后,在B中如何关闭整个Android应用程序呢? 这里用到几种方法. 1.finish()方法 finish是Activity的类,仅仅针对Activity,当调用finish()时,只是将活动推向后台,并没有立即释放内存,活动的资源并没有被清理:调用finish()方法会执行Activity.

Android Activity中的四种启动模式

Android总Activity的启动模式分为四种: <activity android:name=".MainActivity" android:launchMode="standard" /> [standard]    默认模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中. [singleTop]    如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在

Android平台中实现翻页特效

Android平台中的二种翻页效果实现.第一种翻页效果如下: 实现原理:当前手指触摸点为a,则 a点坐标为(ax,ay), 由三角形acb与三角形cmb为对称三角形并且直线cp为am垂直平分线,则 B点坐标为(ax/2,ay/2).作gf垂直于om且cb垂直于am, 三角形cfg与gfm相似,则 cf:gf = gf:mf cf=(gf * gf) / mf gf长度为g点纵坐标 mf长度为g点横坐标cf长度可求 c点坐标可求 由c点.g点可确定过两点间的直线, 当该直线中x=0时求出与y足交点

Android开发中高效的数据结构用SparseArray代替HashMap

Android开发中高效的数据结构 android开发中,在java2ee或者android中常用的数据结构有Map,List,Set,但android作为移动平台,有些api(很多都是效率问题)显然不够理想,本着造更好轮子的精神,android团队编写了自己的api用来代替java api 1.SimpleArrayMap<K,V>与ArrayMap<K,V> 实质上ArrayMap继承自SimpleArrayMap,主要是为了实现像HashMap一样的api方法,让习惯使用Ha

从Android代码中来记忆23种设计模式

我的简书同步发布:从Android代码中来记忆23种设计模式 相信大家都曾经下定决心把23种设计模式牢记于心,每次看完之后过一段时间又忘记了~,又得回去看,脑子里唯一依稀记得的是少数设计模式的大致的定义.其实,网上很多文章讲得都非常好,我也曾经去看过各种文章.也曾一直苦恼这些难以永久记下的设计模式,直到我接触到了<Android源码设计模式解析与实战>--何红辉与关爱明著,发现原来其实我们在Android中都接触过这些设计模式,只是我们不知道而已.既然我们都接触过,我们只需一一对号入座,对设计

Android基础入门教程——8.1.3 Android中的13种Drawable小结 Part 3

Android基础入门教程--8.1.3 Android中的13种Drawable小结 Part 3 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来把剩下的四种Drawable也学完,他们分别是: LayerDrawable,TransitionDrawable,LevelListDrawable和StateListDrawable, 依旧贴下13种Drawable的导图: 1.LayerDrawable 层图形对象,包含一个Drawable数组,然后按照数组对应的顺序来

Android基础入门教程——8.1.2 Android中的13种Drawable小结 Part 2

Android基础入门教程--8.1.2 Android中的13种Drawable小结 Part 2 标签(空格分隔): Android基础入门教程 本节引言: 本节我们继续来学习Android中的Drawable资源,上一节我们学习了: ColorDrawable:NinePatchDrawable: ShapeDrawable:GradientDrawable!这四个Drawable~ 而本节我们继续来学习接下来的五个Drawable,他们分别是: BitmapDrawable:Insert

android开发中监听器的三种实现方法(OnClickListener)

Android开发中监听器的实现有三种方法,对于初学者来说,能够很好地理解这三种方法,将能更好地增进自己对android中监听器的理解. 一.什么是监听器. 监听器是一个存在于View类下的接口,一般以On******Llistener命名,实现该接口需要复写相应的on****(View v)方法(如onClick(View v)). 二.监听器的三种实现方法 (以OnClickListener为例) 方法一:在Activity中定义一个内部类继承监听器接口(这里是OnClickListener