目录
4,图像截取 Mat(const Mat&, const Rect&)
一,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);

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

被折叠的 条评论
为什么被折叠?



