OpenCV图像处理——存储结构 Mat (Matrices)(版本 4.12.0)

张开发
2026/6/9 14:22:44 15 分钟阅读
OpenCV图像处理——存储结构 Mat (Matrices)(版本 4.12.0)
目录1. Mat说明2. 通道宏定义说明3. 创建 Mat对象的方式1. Mat说明在opencv中图像用一个矩阵数组表示类名为Mat(Matrices的前三个字母的缩写)。类Mat表示一个n维密度数值的单通道或多通道数组(注所谓密度是否每一个元素都会存储哪怕该值为零而稀疏矩阵不存储零值)。它可用于存储实数或复数向量、以及矩阵、灰度图像或彩色图像、立体像素(voxel)体积、向量域(fields)、点云(point clouds一系列在三维空间中描述物体几何形状的点)、张量(tensors)、直方图(不过非常高维的直方图可能存储在 SparseMat 中更好)。数组M的数据布局由数组M.step[]所定义因此元素的地址(其中)计算为在二维数组的情况下上述公式缩减为注意( 事实上这意味着二维矩阵是逐行存储的三维矩阵逐平面存储的如此等等。是最小的并且总是等于元素数目 M.elemSize()。因此Mat 中的数据布局与标准工具包和 SDK 中的大多数密度数组类型兼容例如 Numpy (ndarray)、Win32(独立设备位图)等即使用逐步(steps)(或大步(strides))的任何数组来计算像素的位置。由于这种兼容性可以为用户分配的数据创建 Mat 头文件并使用 OpenCV 函数就地处理它。2.通道宏定义说明#defineCV_8U0 //8位无符号整数#defineCV_8S1 //8位有符号整数#defineCV_16U2 // 16位无符号整数#defineCV_16S3 // 16位有符号整数#defineCV_32S4 // 32位有符号整数#defineCV_32F5 // 32位浮点数#defineCV_64F6 // 64位浮点数#defineCV_16F7 //16位浮点数#defineCV_8UC1 CV_MAKETYPE(CV_8U,1)#defineCV_8UC2 CV_MAKETYPE(CV_8U,2)#defineCV_8UC3 CV_MAKETYPE(CV_8U,3)#defineCV_8UC4 CV_MAKETYPE(CV_8U,4)#defineCV_8UC(n) CV_MAKETYPE(CV_8U,(n))//CV_8UC1表示8位无符号1通道//最后的数字表示通道数,数字前的C是Channel道字母(下同)#defineCV_8SC1 CV_MAKETYPE(CV_8S,1)#defineCV_8SC2 CV_MAKETYPE(CV_8S,2)#defineCV_8SC3 CV_MAKETYPE(CV_8S,3)#defineCV_8SC4 CV_MAKETYPE(CV_8S,4)#defineCV_8SC(n) CV_MAKETYPE(CV_8S,(n))#defineCV_16UC1 CV_MAKETYPE(CV_16U,1)#defineCV_16UC2 CV_MAKETYPE(CV_16U,2)#defineCV_16UC3 CV_MAKETYPE(CV_16U,3)#defineCV_16UC4 CV_MAKETYPE(CV_16U,4)#defineCV_16UC(n) CV_MAKETYPE(CV_16U,(n))#defineCV_16SC1 CV_MAKETYPE(CV_16S,1)#defineCV_16SC2 CV_MAKETYPE(CV_16S,2)#defineCV_16SC3 CV_MAKETYPE(CV_16S,3)#defineCV_16SC4 CV_MAKETYPE(CV_16S,4)#defineCV_16SC(n) CV_MAKETYPE(CV_16S,(n))#defineCV_32SC1 CV_MAKETYPE(CV_32S,1)#defineCV_32SC2 CV_MAKETYPE(CV_32S,2)#defineCV_32SC3 CV_MAKETYPE(CV_32S,3)#defineCV_32SC4 CV_MAKETYPE(CV_32S,4)#defineCV_32SC(n) CV_MAKETYPE(CV_32S,(n))#defineCV_32FC1 CV_MAKETYPE(CV_32F,1)#defineCV_32FC2 CV_MAKETYPE(CV_32F,2)#defineCV_32FC3 CV_MAKETYPE(CV_32F,3)#defineCV_32FC4 CV_MAKETYPE(CV_32F,4)#defineCV_32FC(n) CV_MAKETYPE(CV_32F,(n))#defineCV_64FC1 CV_MAKETYPE(CV_64F,1)#defineCV_64FC2 CV_MAKETYPE(CV_64F,2)#defineCV_64FC3 CV_MAKETYPE(CV_64F,3)#defineCV_64FC4 CV_MAKETYPE(CV_64F,4)#defineCV_64FC(n) CV_MAKETYPE(CV_64F,(n))#defineCV_16FC1 CV_MAKETYPE(CV_16F,1)#defineCV_16FC2 CV_MAKETYPE(CV_16F,2)#defineCV_16FC3 CV_MAKETYPE(CV_16F,3)#defineCV_16FC4 CV_MAKETYPE(CV_16F,4)#defineCV_16FC(n) CV_MAKETYPE(CV_16F,(n))3.创建 Mat对象的方式有多种方式可以创建Mat对象下面是常用方式(1)使用create(nrows, ncols, type)方法或类似的Mat(nrows, ncols, type[, fillValue])构造函数。这将分配一个指定大小和类型的新数组。type的含义与cvCreateMat方法中的相同。例如CV_8UC1 表示一个 8 位无符号单通道数组CV_32FC2 表示一个双通道(复数)浮点数组依此类推。//创建一个 7x7 复矩阵其内容用 13j 填充MatM(7, 7,CV_32FC2,Scalar(1, 3));//现在将 M 转换为一个 100x60 15通道 8位矩阵.//旧内容将被移除。M.create(100, 60,CV_8UC(15));create() 仅在当前数组的形状或类型与指定的形状或类型不同时才分配一个新数组。(2)创建一个多维数组//创建一个 100x100x100 8位数组intsz[] { 100, 100, 100 };MatbigCube(3, sz,CV_8U,Scalar::all(0));(3)使用复制构造函数或赋值运算符其中右侧可以是数组或表达式。数组赋值是 O(1) 操作因为它只复制数组头并增加引用计数器。如果需要可以使用 Mat::clone() 方法获取数组的完整(深度)副本。为另一个数组的一部分构造数组头。它可以是单行、单列、多行、多列、数组中的矩形区域(在代数中称为“次区域”)或对角线。此类操作也是 O(1) 操作因为新数组头引用的是相同的数据。您可以使用此功能实际修改数组的一部分例如//填加第5行并乘以3再加到第3行M.row(3) M.row(3) M.row(5) * 3;//第7列复制到第1列MatM1 M.col(1);M.col(7).copyTo(M1);//创建一个 320x240 图像Matimg(Size(320, 240),CV_8UC3);//先择一个 ROIMatroi(img,Rect(10, 10, 100, 100));//用 (0,255,0) 填充 ROI (在 RGB 颜色空间中是绿色);//原 320x240 图像将被修改roiScalar(0, 255, 0);(4)由于增加了 datastart 和 dataend 成员可以使用 locateROI() 计算子数组在主 容器 数组中的相对位置MatA Mat::eye(10, 10,CV_32S);//提取 A 列第 1 列含至第 3 列不含。MatB A(Range::all(),Range(1, 3));//提取 B 行第 5 行含至第 9 行不含。//即, C \~ A(Range(5, 9), Range(1, 3))MatC B(Range(5, 9),Range::all());Sizesize;Pointofs;C.locateROI(size, ofs);(5)快速初始化小型矩阵和/或实现超高速的元素访问。doublem[3][3] { {a,b,c}, {d,e,f}, {g,h,i}};MatM Mat(3, 3,CV_64F, m).inv();(6)用 MATLAB 风格数组初始化器zeros(), ones(), eye() 。//创建一个 double 精度恒等矩阵并将其加入 MM Mat::eye(M.rows, M.cols,CV_64F);(7)使用逗号分隔的初始化列表。//创建一个 3x3 double 精度恒等矩阵MatM (Mat_double(3, 3)1,0,0,0,1,0,0,0,1);

更多文章