Opencv源码解析(1)数据结构

本文详细解析了OpenCV中的Mat数据结构,包括其成员变量如flags、channels和type,以及常用函数如create、copyTo和图像截取。还介绍了其他基础数据结构如Size和Array,以及Mat类的创建过程和imwrite函数的工作原理。

目录

一,Mat基础数据结构

1,Mat的数据成员

2,flags

(1)深度 depth()

(2)通道数 channels()

(3)图像类型 type()

(4)flag第13-14位

(5)判断连续 isContinuous()

(6)子图标志 isSubmatrix()

(7)magic signature

3,UMatData

4,step

二,Mat常用函数

1,Mat类的create函数

2,Mat类的copyTo函数

3,Mat类的=运算符

4,图像截取 Mat(const Mat&, const Rect&)

5,imwrite

三,其他基础数据结构

1,图像尺寸上限

2,Size

3,***Array

(1)InputArray

(2)OutputArray

(3)InputOutputArray


一,Mat基础数据结构

1,Mat的数据成员

    int flags;
    //! the matrix dimensionality, >= 2
    int dims;
    //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
    int rows, cols;
    //! pointer to the data
    uchar* data;

    //! helper fields used in locateROI and adjustROI
    const uchar* datastart;
    const uchar* dataend;
    const uchar* datalimit;

    //! custom allocator
    MatAllocator* allocator;

    UMatData* u;

    MatSize size;
    MatStep step;

其中flags、u指针、step在下面的章节。

成员dims是维数,当维数是2时,成员rows和cols才有意义。

data是图像的数据指针。

2,flags

以下宏来自opencv-4.2.0\modules\gapi\include\opencv2\gapi\own\cvdefs.hpp中的源代码。

按照从低到高位分别是:

(1)深度 depth()

#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_16F  7

#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)
#define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)

即flags的前3位存的是8种深度。

后缀表示数据类型,U unsigned   S signed  F float

inline
int Mat::depth() const
{
    return CV_MAT_DEPTH(flags);
}

depth函数用来获取深度。

(2)通道数 channels()

#define CV_CN_MAX     512
#define CV_CN_SHIFT   3
#define CV_MAT_CN_MASK          ((CV_CN_MAX - 1) << CV_CN_SHIFT)
#define CV_MAT_CN(flags)        ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)

最少1通道,最多513个通道,即flag的低3位是深度,接下来9位是通道数-1。

inline
int Mat::channels() const
{
    return CV_MAT_CN(flags);
}

channels函数用来获取通道数。

CV_8U和CV_8UC1都等于0(表示1通道)

(3)图像类型 type()

#define CV_MAT_TYPE_MASK        (CV_DEPTH_MAX*CV_CN_MAX - 1)
#define CV_MAT_TYPE(flags)      ((flags) & CV_MAT_TYPE_MASK)

flag的前12位是type,由深度和通道数组合而成。

type() == (channels()-1) * 8 + depth()

(4)flag第13-14位

暂无用途

(5)判断连续 isContinuous()

#define CV_MAT_CONT_FLAG_SHIFT  14
#define CV_MAT_CONT_FLAG        (1 << CV_MAT_CONT_FLAG_SHIFT)
#define CV_IS_MAT_CONT(flags)   ((flags) & CV_MAT_CONT_FLAG)
#define CV_IS_CONT_MAT          CV_IS_MAT_CONT

即flag的第15位,判断整个mat所有像素是否是连续存储。

inline
bool Mat::isContinuous() const
{
    return (flags & CONTINUOUS_FLAG) != 0;
}

(6)子图标志 isSubmatrix()

#define CV_SUBMAT_FLAG_SHIFT    15
#define CV_SUBMAT_FLAG          (1 << CV_SUBMAT_FLAG_SHIFT)
#define CV_IS_SUBMAT(flags)     ((flags) & CV_MAT_SUBMAT_FLAG)

CV_MAT_SUBMAT_FLAG找不到定义,应该就是CV_SUBMAT_FLAG

flag的第16位,判断图像是不是另外一个图像的子图。

SUBMATRIX_FLAG = CV_SUBMAT_FLAG

inline
bool Mat::isSubmatrix() const
{
    return (flags & SUBMATRIX_FLAG) != 0;
}

(7)magic signature

flags的高16位是magic signature,用来区分Mat的类型

3,UMatData

Mat对象包含了一个UMatData的结构体指针:UMatData* u;

struct CV_EXPORTS UMatData
{
    enum MemoryFlag { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
        DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24,
        USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64,
        ASYNC_CLEANUP=128
    };
    UMatData(const MatAllocator* allocator);
    ~UMatData();

    // provide atomic access to the structure
    void lock();
    void unlock();

    bool hostCopyObsolete() const;
    bool deviceCopyObsolete() const;
    bool deviceMemMapped() const;
    bool copyOnMap() const;
    bool tempUMat() const;
    bool tempCopiedUMat() const;
    void markHostCopyObsolete(bool flag);
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值