OpenCV Mat类

news2024/11/16 1:21:21

文章目录

  • Mat类
    • Mat类数据类型读取
    • Mat类支持的运算
      • OpenCV Mat数据类型指针ptr的使用
        • 多维矩阵创建


Mat类

在这里插入图片描述
在这里插入图片描述

Mat类数据类型读取

S = 有符号整型 
U = 无符号整型 
F = 浮点型

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位浮点数(-FLT_MAX…FLT_MAX,INF,NAN)

CV_64F - 64位浮点数(-DBL_MAX…DBL_MAX,INF,NAN)

CV_8UC3而后面的C1、C2、C3是什么意思呢?
这里的1、2、3代表的是通道数,比如RGB就是3通道,颜色表示最大为255,所以可以用CV_8UC3这个数据类型来表示;灰度图就是C1,只有一个通道;而带alph通道的PNG图像就是C4,是4通道图片。
如果矩阵是类型:CV_8U 则使用 : Mat.at<uchar>(y,x)
如果矩阵是类型:CV_8S 则使用 : Mat.at<schar>(y,x)
如果矩阵是类型:CV_16U 则使用 : Mat.at<ushort>(y,x)
如果矩阵是类型:CV_16S 则使用 : Mat.at<short>(y,x)
如果矩阵是类型:CV_32S 则使用 : Mat.at<int>(y,x)
如果矩阵是类型:CV_32F 则使用 : Mat.at<float>(y,x)
如果矩阵是类型:CV_64F 则使用 : Mat.at<double>(y,x)


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;

在这里插入图片描述

Mat类支持的运算

在这里插入图片描述在这里插入图片描述

设为A,B为Mat类型,s是Scalar类型,a是一个实数。下面列出关于Mat的常用运算:

矩阵加减: A+B,A-B,A+s,A-s,s+A,s-A,-A.
矩阵乘以实数: A*a,a*A
逐元素乘除: A.mul(B),A/B,a/A
矩阵乘法: A*BmaxVal; Point minPos,m
矩阵倒置: A.t()
矩阵的逆: A.inv()
矩阵比较: A comp B,A comp a,a comp A。这里comp包括 >, >=,==,!=,<=,<。得出的结果是一个单通道8位的矩阵,元素的值为255或0。
矩阵位操作: A logic B, A logic s,s logic A。这里logic包括:&,|,^
向量的差乘和内积: A.cross(B),A.dot(B);

OpenCV是一个广泛使用的计算机视觉库,它提供了许多用于图像处理和计算机视觉任务的函数和工具。在OpenCV中,Mat是一个重要的数据结构,用于表示图像和矩阵。Mat类提供了一种方便的方式来处理图像和矩阵数据。

下面是使用OpenCV的Mat类创建各种类型的图像和矩阵的介绍:

  1. 创建空白图像:
   cv::Mat image; // 创建一个空的图像对象
   cv::Mat image(rows, cols, type); // 创建指定行数、列数和类型的空白图像
  1. 从已有数据创建图像:
   cv::Mat image(rows, cols, type, data); // 使用指定的数据创建图像,data是指向数据的指针
  1. 创建单通道图像:
   cv::Mat image(rows, cols, CV_8UC1); // 创建一个8位单通道图像
  1. 创建三通道彩色图像:
   cv::Mat image(rows, cols, CV_8UC3); // 创建一个8位三通道彩色图像
  1. 创建带有初始值的图像:
   cv::Mat image(rows, cols, type, cv::Scalar(value)); // 使用指定的初始值创建图像
  1. 从文件加载图像:
   cv::Mat image = cv::imread("image.jpg"); // 从文件加载图像
  1. 创建矩阵:
   cv::Mat matrix(rows, cols, CV_32FC1); // 创建一个32位浮点型单通道矩阵
  1. 创建具有初始值的矩阵:
   cv::Mat matrix = cv::Mat::eye(rows, cols, CV_32FC1); // 创建一个单位矩阵

这些只是创建不同类型的图像和矩阵的一些示例。OpenCV的Mat类还提供了许多其他方法和操作,可以对图像和矩阵进行各种处理和分析。你可以参考OpenCV的官方文档和教程,以获取更详细的信息和示例代码。

OpenCV(Open Source Computer Vision Library)是一个广泛使用的开源计算机视觉库,提供了许多用于图像和视频处理的功能。在OpenCV中,Mat类是用于表示图像和矩阵的主要数据结构。Mat类提供了许多方法和操作符,用于访问和处理图像的像素值和矩阵的元素。

下面是一些常见的Mat类的访问和操作方法:

  1. 创建Mat对象:
    使用默认构造函数创建空的Mat对象:
   cv::Mat image;

使用图像文件路径创建Mat对象:

   cv::Mat image = cv::imread("image.jpg");

使用矩阵数据创建Mat对象:

   cv::Mat matrix = cv::Mat::ones(3, 3, CV_32F);
  1. 访问像素值:
    使用at方法访问像素值:
   cv::Vec3b pixel = image.at<cv::Vec3b>(row, col);

使用ptr方法访问像素值:

   uchar* pixelPtr = image.ptr(row);
   uchar blue = pixelPtr[col * image.channels()];
   uchar green = pixelPtr[col * image.channels() + 1];
   uchar red = pixelPtr[col * image.channels() + 2];
  1. 修改像素值:
    使用at方法修改像素值:
   image.at<cv::Vec3b>(row, col) = cv::Vec3b(255, 0, 0);  // 设置像素为蓝色

使用ptr方法修改像素值:

   uchar* pixelPtr = image.ptr(row);
   pixelPtr[col * image.channels()] = blue;
   pixelPtr[col * image.channels() + 1] = green;
   pixelPtr[col * image.channels() + 2] = red;
  1. 获取图像属性:
    获取图像的宽度和高度:
   int width = image.cols;
   int height = image.rows;

获取图像的通道数:

   int channels = image.channels();

获取图像的数据类型:

   int type = image.type();
  1. 图像操作:
    图像的拷贝:
   cv::Mat imageCopy = image.clone();

图像的裁剪:

   cv::Mat croppedImage = image(cv::Rect(x, y, width, height));

图像的缩放:

   cv::Mat resizedImage;
   cv::resize(image, resizedImage, cv::Size(newWidth, newHeight));

这只是一些Mat类的常见访问和操作方法示例。Mat类还提供了许多其他方法和操作符,用于在图像处理中进行各种操作。你可以参考OpenCV的官方文档和示例代码,了解更多关于Mat类的详细信息和用法。

cv::Mat 是 OpenCV 中用于表示图像和矩阵的类。它是 OpenCV 中最基本的数据结构之一,提供了许多功能和操作,使得图像处理和计算变得更加方便。下面是一些关于 cv::Mat 类的常见修改方法的介绍:

  1. 构造函数:cv::Mat 提供了多种构造函数来创建矩阵对象。可以使用默认构造函数创建一个空的矩阵,也可以使用指定行数、列数、数据类型的构造函数创建具有特定尺寸和数据类型的矩阵。例如:
   cv::Mat emptyMat; // 创建一个空矩阵
   cv::Mat mat(3, 3, CV_8UC1); // 创建一个3x3的无符号8位单通道矩阵
  1. 复制和赋值:可以使用 = 运算符将一个 cv::Mat 对象复制给另一个对象,从而进行矩阵的复制。复制操作将复制矩阵的数据和属性。例如:
   cv::Mat srcMat = cv::imread("image.jpg"); // 从文件读取图像
  1. 修改矩阵元素:可以使用 at() 成员函数来访问和修改矩阵的像素值。该函数接受行索引和列索引作为参数,并返回相应位置的像素值的引用。例如,修改单通道图像的像素值:
   cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); // 以灰度模式读取图像
   image.at<uchar>(y, x) = 255; // 将位置 (x, y) 的像素值设置为255
  1. 修改矩阵属性:cv::Mat 类提供了一些成员函数来修改矩阵的属性,如行数、列数和数据类型。可以使用 rowscolstype 成员函数分别获取矩阵的行数、列数和数据类型,并使用 reshape() 函数来改变矩阵的尺寸。例如:
   cv::Mat mat(3, 3, CV_8UC1); // 创建一个3x3的无符号8位单通道矩阵
   int rows = mat.rows; // 获取行数
   int cols = mat.cols; // 获取列数
   int type = mat.type(); // 获取数据类型
   mat = mat.reshape(1, 1); // 转换为1行1列的矩阵
  1. 修改矩阵数据:可以使用 data 成员变量来直接访问和修改矩阵的数据。数据以行优先顺序存储,并且可以通过指针算术运行访问和修改数据。例如,将矩阵的所有像素值乘以2:
cv::Mat mat(3, 3, CV_8UC1); // 创建一个3x3的无符号8位单通道矩阵
for (int i = 0; i < mat.rows; i++) {
    for (int j = 0; j < mat.cols; j++) {
        mat.data[i * mat.cols + j] *= 2; // 修改像素值
    }
}
  1. 修改矩阵尺寸:可以使用 resize() 成员函数来修改矩阵的尺寸。可以指定新的行数、列数和插值方法。例如,将矩阵的尺寸调整为2倍:
cv::Mat mat(3, 3, CV_8UC1); // 创建一个3x3的无符号8位单通道矩阵
cv::resize(mat, mat, cv::Size(), 2.0, 2.0, cv::INTER_LINEAR); // 将矩阵尺寸调整为原来的2倍
  1. 修改矩阵数据类型:可以使用 convertTo() 成员函数来修改矩阵的数据类型。可以指定新的数据类型和比例因子。例如,将矩阵的数据类型转换为浮点型:
cv::Mat mat(3, 3, CV_8UC1); // 创建一个3x3的无符号8位单通道矩阵
cv::Mat floatMat;
mat.convertTo(floatMat, CV_32FC1); // 将矩阵数据类型转换为单精度浮点型

这些是 cv::Mat 类的一些常见修改方法的介绍。使用这些方法,可以对矩阵进行各种操作,包括访问和修改像素值、修改矩阵属性、调整尺寸和数据类型转换等。

Mat_Mat是OpenCV中用于表示矩阵和图像的两个类。它们之间有一些区别和关联。

  1. 数据存储方式:Mat类是OpenCV中通用的矩阵和图像数据结构,可以存储不同维度、通道数和数据类型的数据。它使用一个连续的内存块来存储数据。而Mat_类是Mat类的模板化版本,用于表示多维数组。它也使用连续的内存块存储数据,但在编译时期就确定了矩阵的大小和数据类型。

  2. 类型安全性:由于Mat_类在编译时期确定了矩阵的大小和数据类型,因此它提供了更高的类型安全性。在使用Mat_类时,编译器可以在编译时进行类型检查,从而避免一些潜在的错误。

  3. 成员函数和操作符重载:Mat类和Mat_类提供了一些相似的成员函数和操作符重载,用于访问和操作矩阵的元素。例如,两者都支持使用括号运算符重载来访问和修改矩阵中的元素。此外,它们都提供了一些常见的函数,如转置、求逆、行列式计算等。

  4. 兼容性:Mat_类是Mat类的子类,因此可以将Mat_对象赋值给Mat对象,反之亦然。这使得在使用OpenCV的函数和算法时可以无缝切换使用这两个类。

综上所述,Mat类是OpenCV中通用的矩阵和图像数据结构,可以适用于各种维度、通道数和数据类型的数据。而Mat_类是Mat类的模板化版本,提供了更高的类型安全性,并在编译时确定了矩阵的大小和数据类型。根据实际需求,可以选择适合的类来表示和处理矩阵和图像数据。

使用Mat_类可以按照以下步骤进行:

  1. 包含头文件:首先,需要包含OpenCV库的头文件。
#include <opencv2/opencv.hpp>
  1. 创建Mat_对象:使用Mat_类的模板形式来创建矩阵对象,并指定矩阵的大小和数据类型。
cv::Mat_<float> mat(3, 3);  // 创建一个3x3的单通道浮点型矩阵
  1. 访问和修改元素:可以使用括号运算符重载来访问和修改矩阵中的元素。根据需要,可以使用行列索引或线性索引来访问元素。
mat(0, 0) = 1.0f;  // 设置第一行第一列的元素为1.0
float value = mat(1, 2);  // 获取第二行第三列的元素值
  1. 使用迭代器遍历矩阵元素:通过获取矩阵的迭代器,可以遍历矩阵中的元素。
for (auto it = mat.begin(); it != mat.end(); ++it)
{
    float value = *it;  // 访问迭代器当前位置的元素
    // 进行处理
}
  1. 使用循环遍历矩阵元素:通过嵌套循环可以遍历矩阵中的元素。
for (int i = 0; i < mat.rows(); ++i)
{
    for (int j = 0; j < mat.cols(); ++j)
    {
        float value = mat(i, j);  // 获取(i, j)位置的元素值
        // 进行处理
    }
}
  1. 其他操作:Mat_类还提供了一些常见的操作,如获取矩阵尺寸、转置、求逆、行列式计算等。可以使用相应的成员函数来执行这些操作。
cv::Size size = mat.size();  // 获取矩阵的尺寸
cv::Mat_<float> matT = mat.t();  // 对矩阵进行转置操作
cv::Mat_<float> matInv = mat.inv();  // 求矩阵的逆矩阵
float det = cv::determinant(mat);  // 计算矩阵的行列式

这些是Mat_类的基本使用方法,您可以根据需要进行进一步的矩阵操作和图像处理。请参考OpenCV的文档和示例代码以了解更多关于Mat_类的详细信息和用法。

OpenCV Mat数据类型指针ptr的使用


    cv::Mat image = cv::Mat(400, 600, CV_8UC1); //宽400,长600
    uchar * data00 = image.ptr<uchar>(0);
    uchar * data10 = image.ptr<uchar>(1);
    uchar * data01 = image.ptr<uchar>(0)[1];

解释:
定义了一个Mat变量image。
data00是指向image第一行第一个元素的指针。
data10是指向image第二行第一个元素的指针。
data01是指向image第一行第二个元素的指针。

    注意:
    如果你的程序使用来image.ptr指针,并且出现了下面这样的错误:(假设你使用的软件是Visual Studio 201x)

    某某.exe中的 0x75065b68 处有未经处理的异常:Microsoft C++ 异常; 内存位置0x85e790处的cv::Exception。


    这可能是因为你不理解image.ptr这个指针,犯了这样的错误:image.ptr(1);指的不是image中第二个像素,而是第一行第二个像素的指针。
    使用上面的代码举例:image有400行,有400*600个像素。假设现在你想得到第3行第42个像素的指针,如果你写成:

    uchar * data = image.ptr<uchar>(3*image.cols + 41);


    这样写是错误的,会出现上面的错误。你得到的不是第3行第42个像素的指针,而是第(3×image.cols + 41)行第0个像素的指针,因为没有(3×image.cols + 41)行,所以没有这个指针,所以错误。
    正确的写法:

    uchar * data = image.ptr<uchar>(3)[41];


    所以要注意这一点:如果程序可以正常编译,但是运行时出错,很有可能是你给指针赋值的时候,索引值溢出指定范围,指针乱指,导致程序跑偏,所以只有在运行时才能发现错误。

多维矩阵创建

Mat(int ndims, const int* sizes, int type);

该函数定义了一个名为"Mat"的构造函数,用于创建一个矩阵对象。参数说明如下:

  • ndims:整数类型,表示矩阵的维数(即矩阵的阶数)。( 如果是3 就是三维,对应的sizes 就是三个数)
  • sizes:指向整数数组的指针,包含了每个维度的大小。数组的长度应与ndims相等,每个元素表示对应维度的大小。
  • type:整数类型,表示矩阵元素的数据类型。

用于表示图像或任意维度的多维数组。

比如:

    //最后面的两个数:(行,列),确定了一个面
	//是一个依次降维的过程
	//8,10组成了面,5个面,组成了立方体
	int matSize[] = {5,8,10};//每一维元素的个数:8:行,10:列
	//  3 表示三维 对应三个数{5,8,10}
	Mat mat1(3,matSize, CV_16UC3, Scalar::all(0));

在这里插入图片描述

int main()
{
	
	system("color F0");

	//Demo1(2维矩阵)///
	printf("//Demo1(2维矩阵)\n");
	//创建16位无符号整形,每个元素三个通道为1,5,6
	Mat f(4, 5, CV_16UC3, Scalar(1, 5, 6, 9));
	std::cout << f << std::endl;
	/*
	[1, 5, 6, 1, 5, 6, 1, 5, 6, 1, 5, 6, 1, 5, 6;
	1, 5, 6, 1, 5, 6, 1, 5, 6, 1, 5, 6, 1, 5, 6;
	1, 5, 6, 1, 5, 6, 1, 5, 6, 1, 5, 6, 1, 5, 6;
	1, 5, 6, 1, 5, 6, 1, 5, 6, 1, 5, 6, 1, 5, 6]
	*/


	/*
	step的几个类别区分:
	step:矩阵第一行元素的字节数
	step[0] : 矩阵第一行元素的字节数
	step[1] : 矩阵中一个元素的字节数
	step1(0) : 矩阵中一行有几个通道数
	step1(1) : 一个元素有几个通道数(channel())
	*/
	//获取列数
	std::cout << f.cols << std::endl;//5
	//获取行数
	std::cout << f.rows << std::endl;//4
	//获取一行的最大字节数  CV_16UC3 = 2*3=6   6*5=30
	std::cout << f.step << std::endl;//30
	//矩阵中一行元素的字节数
	std::cout << f.step[0] << std::endl;//30
	//矩阵中一个元素的字节数
	std::cout << f.step[1] << std::endl;//6
	//矩阵中一行有几个通道数  元素个数*通道数  = 5*3=15
	std::cout << f.step1() << std::endl;//15
	//矩阵中一行有几个通道数  元素个数*通道数  = 5*3=15
	std::cout << f.step1(0) << std::endl;//15
	//一个元素有几个通道数(channel())
	std::cout << f.step1(1) << std::endl;//3

	//获取每个元素的字节数  CV_16UC3  = 2*3=6
	std::cout << f.elemSize() << std::endl;//6
	//获取矩阵中元素的个数  4*5 = 20
	std::cout << f.total() << std::endl;//20
	//获取通道数  
	std::cout << f.channels() << std::endl;//3
	//Vec3s 获取(0,0)为第一个元素,为3通道
	cv::Vec3s vc3 = f.at<cv::Vec3s>(0, 0);
	//获取元素中第一个通道值
	std::cout << (int)vc3.val[0] << std::endl;//1




	/*用数据流指针获取通道值
	f.data:数据存储的起始地址 (uchar*类型);
	*/

	//通道1: 1     
	std::cout << "通道1:" << (int)*(f.data + f.step[0] * 2 + f.step[1] * 2 + 0) << std::endl;
	//通道2: 5
	std::cout << "通道2:" << (int)*(f.data + f.step[0] * 2 + f.step[1] * 2 + 2) << std::endl;
	//通道3: 6
	std::cout << "通道3:" << (int)*(f.data + f.step[0] * 2 + f.step[1] * 2 + 4) << std::endl;
	//创建一行5列单通道数据 枚举
	Mat a = (cv::Mat_<int>(1, 5) << 1, 2, 3, 4, 5);
	std::cout << a << std::endl;//[1, 2, 3, 4, 5]

	//向量生成对角线矩阵
	Mat b = Mat::diag(a);
	std::cout << b << std::endl;
	/*
	[1, 0, 0, 0, 0;
	0, 2, 0, 0, 0;
	0, 0, 3, 0, 0;
	0, 0, 0, 4, 0;
	0, 0, 0, 0, 5]
	*/
	//抠图或者裁剪  获取第2,3行和第3,4列相交 的数据 
	//按照矩阵中的元素抠图
	Mat c = Mat(b, Range(2, 4), Range(3, 5));
	std::cout << c << std::endl;
	/*
	[0, 0;
	4, 0]
	*/

	//生成5行6列,对角线为1的数据,每个元素为16位
	Mat d = Mat::eye(5, 6, CV_16U);
	std::cout << d << std::endl;
	/*
	[1, 0, 0, 0, 0, 0;
	 0, 1, 0, 0, 0, 0;
	 0, 0, 1, 0, 0, 0;
	 0, 0, 0, 1, 0, 0;
	 0, 0, 0, 0, 1, 0]
	*/

	//生成5行6列,全部元素为1,每个元素为16位
	Mat e = Mat::ones(5, 6, CV_16U);
	std::cout << e << std::endl;
	/*
	[1, 1, 1, 1, 1, 1;
	 1, 1, 1, 1, 1, 1;
	 1, 1, 1, 1, 1, 1;
	 1, 1, 1, 1, 1, 1;
	 1, 1, 1, 1, 1, 1]
	*/
	//生成5行6列,全部元素为0,每个元素为16位
	Mat g = Mat::zeros(5, 6, CV_16U);
	std::cout << g << std::endl;
	/*
	[0, 0, 0, 0, 0, 0;
	 0, 0, 0, 0, 0, 0;
	 0, 0, 0, 0, 0, 0;
	 0, 0, 0, 0, 0, 0;
	 0, 0, 0, 0, 0, 0]
	*/





	//Demo1(3维矩阵)///
	printf("//Demo1(3维矩阵)\n");
	//最后面的两个数:(行,列),确定了一个面
	//是一个依次降维的过程
	//8,10组成了面,5个面,组成了立方体
	int matSize[] = { 5,8,10 };//每一维元素的个数:8:行,10:列
	Mat mat1(3, matSize, CV_16UC3, Scalar::all(0));

	//求step[i]的大小:每一维元素的大小(单位字节)
	std::cout << "step[i]的大小" << std::endl;
	std::cout << "step[0]:" << mat1.step[0] << std::endl;//CV_16UC3 (2*3)*8*10 = 480:面的大小(第一维)
	std::cout << "step[1]:" << mat1.step[1] << std::endl;//(2*3)*10 = 60:线的大小(第二维)
	std::cout << "step[2]:" << mat1.step[2] << std::endl;//(2*3) = 6:点的大小(第三维)

	//求size[i]:每一维元素的个数
	std::cout << "size[i]的大小" << std::endl;
	std::cout << "size[0]:" << mat1.size[0] << std::endl;//5:面
	std::cout << "size[1]:" << mat1.size[1] << std::endl;//8:线 (行)  8行
	std::cout << "size[2]:" << mat1.size[2] << std::endl;//10:列   10列

	//求step1(i):每一维元素的通道数  
	std::cout << "step1(i)的大小" << std::endl;
	std::cout << "step1(0):" << mat1.step1(0) << std::endl;//channels(3)*8*10 = 240:面  (step1 = step / elemSize1  = 480 /2 = 240)
	std::cout << "step1(1):" << mat1.step1(1) << std::endl;//(3)*10 = 30: 线 (行) 
	std::cout << "step1(2):" << mat1.step1(2) << std::endl;//3:点

	//求elemSize:每个元素的大小(单位字节) CV_16UC3 16位 两个字节,三个通道 2*3 =6
	std::cout << "elemSize的大小" << std::endl;
	std::cout << "elemSize:" << mat1.elemSize() << std::endl;//6:每个元素的大小

	//求elemSize1:每个通道的大小(单位字节)  CV_16UC3 16位 两个字节
	std::cout << "elemSize1的大小" << std::endl;
	std::cout << "elemSize1:" << mat1.elemSize1() << std::endl;//2:每个通道的大小

	waitKey(0);
	return 0;
}

在OpenCV中,cv::Mat类代表一个矩阵或多维数组。如果你有一个四维的cv::Mat对象,你可以使用以下方法来查看其内容:

  1. 使用cv::Mat::dims()方法获取矩阵的维度数量。
int dimensions = mat.dims();
  1. 使用cv::Mat::size方法获取每个维度的大小。
int size1 = mat.size[0];  // 第一维度的大小
int size2 = mat.size[1];  // 第二维度的大小
int size3 = mat.size[2];  // 第三维度的大小
int size4 = mat.size[3];  // 第四维度的大小
  1. 使用下标操作符[]来访问矩阵中的元素。对于四维矩阵,你需要提供四个下标来访问元素的值。
// 访问四维矩阵中某个位置的元素值
int value = mat.at<int>(index1, index2, index3, index4);

请注意,上述代码中的int类型是一个示例,你需要根据实际情况来确定矩阵中元素的数据类型,并将其替换为正确的类型。

希望这可以帮助你查看和访问四维矩阵的内容!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/655767.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基础(1)——Python简介

Python基础&#xff08;1&#xff09;——Python简介 文章目录 Python基础&#xff08;1&#xff09;——Python简介目标Python介绍Python版本总结 目标 了解PythonPython的应用领域Python的版本 Python介绍 Python是时下最流行、最火爆的编程语言之一&#xff0c;具体原因如…

SAP从入门到放弃系列之BOM组-Part1

目录 BOM组两种模式&#xff1a; 创建BOM的方式 方式一&#xff1a;直接在每个工厂分别创建BOM。 方式二&#xff1a;创建BOM组&#xff0c;然后每个工厂参考创建 方式三&#xff1a;创建BOM组&#xff0c;每个工厂参考创建&#xff0c;针对有特殊的工厂复制BOM组后进行调…

人机交互学习-9 以用户为中心的设计

以用户为中心的设计 以用户为中心的设计思想工程设计过程的三个假设以人为本设计思想三个方面的假设以用户为中心的设计四原则UDC项目包含的方法 用户参与设计用户参与的重要性选择哪些用户&#xff1f;为什么要让用户参与&#xff1f; 用户参与的形式参与式设计PICTIVECARD 理…

Nacos-手写注册中心基本原理

本文已收录于专栏 《中间件合集》 目录 概念说明需求分析核心功能代码实现AService模块BService模块NacosService模块NacosSDK模块 注意事项总结提升 概念说明 注册中心是微服务架构中的纽带&#xff0c;类似于“通讯录”&#xff0c;它记录了服务和服务地址的映射关系。在分布…

香蕉派(Banana Pi) BPI-M2 Zero 评测试,与树莓派 Zero同尺寸的开发板

Banana Pi M2 Zero 是一款微型计算机&#xff0c;配备四核处理器并内置 Wi-Fi 和蓝牙。这是一款非常适合基本计算任务甚至轻度游戏的小型设备。在这篇评论中&#xff0c;我们将了解 M2 Zero 的性能、功能和价值。 什么是 Banana Pi BPI-M2 Zero Banana Pi M2 Zero 是由深圳公…

MongoDB(Windows版)安装

首先需要下载 官网&#xff1a;MongoDB: The Developer Data Platform | MongoDB 安装过程 需要安装的版本 第一步&#xff1a;安装时&#xff0c;Custom是指可以自定义安装路径&#xff0c;然后傻瓜式安装即可&#xff08;注意&#xff1a;先不要安装图形化工具&#xff0…

2023-06-17 LeetCode每日一题(分割圆的最少切割次数)

2023-06-17每日一题 一、题目编号 2481. 分割圆的最少切割次数二、题目链接 点击跳转到题目位置 三、题目描述 圆内一个 有效切割 &#xff0c;符合以下二者之一&#xff1a; 该切割是两个端点在圆上的线段&#xff0c;且该线段经过圆心。该切割是一端在圆心另一端在圆上…

【Vue】学习笔记-Vue Router activated deactivated 路由守卫

Vue Router activated deactivated 路由守卫 activated deactivated路由守卫1.全局守卫2.独享守卫3.组件内守卫全局路由守卫路由器的两种工作模式 activated deactivated activated 和 deactivated 是路由组件所独有的两个钩子&#xff0c;用于捕获路由组件的激活状态 具体使用…

管理类联考——英语——趣味篇——阅读——考题的来源

Part One考研英语阅读——Part A 1.卫报 《卫报》( The Guardian)是英国的全国性综合内容日报。与《泰晤士报》、《每日电讯报》被合称为英国三大报。由约翰爱德华容泰勒创办于1821年5月5日。该报注重报道国际新闻&#xff0c;擅长发表评论和分析性专题文章。一般公众视《卫报…

【数据分析之道-Matplotlib(九)】Matplotlib棉棒图

文章目录 专栏导读1、Matplotlib棉棒图stem()基本语法2、Matplotlib棉棒图stem()定义样式2.1linefmt参数2.2markerfmt参数2.3举例一&#xff1a;直线样式2.4举例二&#xff1a;圆点样式 3、棉棒图案例实战3.1绘制每月销量的棉棒图3.2绘制每月销量与平均销量之差 专栏导读 ✍ 作…

Prometheus介绍安装和快速入门

Prometheus介绍安装和快速入门 1、Prometheus介绍 1.1 什么是 Prometheus? Prometheus&#xff08;普罗米修斯&#xff09;是古希腊的一个神明&#xff0c;名字的意思是「先见之明」。从它的名字可以看出&#xff0c; Prometheus 是做「先见之明」的监控告警用途。维基百科…

HJ26 字符串排序

题目&#xff1a; HJ26 字符串排序 题解&#xff1a; 规则 1 &#xff1a;英文字母从 A 到 Z 排列&#xff0c;不区分大小写。 统一转换&#xff0c;通过减去对应字母的起始值&#xff0c;得到一个相对值&#xff0c;抹平大小写&#xff0c;例如&#xff1a;B - A&#xff…

【Java项目】使用LruCache提高DSP广告主需求方 (Demand Side Platform)系统性能

文章目录 背景LruCache简介LruCache在DSP系统中的应用场景LruCacheRedis增加LruCache数据过期清除机制ConcurrentHashMapLruCache零拷贝机制 源码 背景 我之前工作的一家公司是一家传媒公司&#xff0c;公司的主要盈利方式为在公司项目中接入广告&#xff0c;以及自媒体广告宣…

Windows下编译安装Acise

Acise是济南友泉软件公司自主研发的一套跨平台的通用CAx(CAD/CAE)软件开发框架&#xff0c;本文旨在记录Windows下编译安装Acise的流程。 零、系统环境 操作系统Windows 10编译器Visual Studio 2019 CommunityCMake2.24.2Boost1.80.0Qt5.14.0OpenCASCADE7.6.0VTK9.0.0 一、依…

Linux之线程安全(下)

文章目录 前言一、Linux线程互斥1.mutex的理解锁原子性互斥锁实现原子性的原理 2.mutex的封装——Mutex.hpp3.可重入和线程安全可重入线程安全线程安全不一定是可重入的&#xff0c;而可重入函数一定是线程安全的。 4.死锁概念造成死锁的四个必要条件如何避免死锁 二、Linux线程…

Mendix低代码开发

Mendix低代码开发 目录概述需求&#xff1a; 设计思路实现思路分析1.URL管理2.LL3.Mendix 低代码可视化开发4.Mendix 低代码可视化开发 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip har…

许多智能算法并不智能

数学的精髓在于不断寻找简洁而优美的解决方法&#xff0c;而智能的精髓也在于尽可能地避免繁琐的计算&#xff0c;通过更高效的方式来解决问题。从实践角度看&#xff0c;现代人工智能技术的发展&#xff0c;正是基于这个思路不断推进的。在机器学习领域中&#xff0c;人们通过…

【C语言复习】第二篇、VS2017软件的使用以及常用小技巧

目录 1、VS2017软件无法打开stdio.h文件的解决办法 2、VS2017软件解决scanf函数问题以及如何建立初始模板 2.1、visual Studio使用scanf函数出现报错问题 2.2、如何实现新建一个.c文件就有初始模板 3、VS2017软件如何显示代码行号&#xff1f; 4、VS2017软件如何快速复制…

Redis(Windows版)安装

Redis安装过程 目前只是Windows下安装&#xff0c;后续会添加linux下安装过程 Windows安装 下载地址&#xff1a;Releases tporadowski/redis (github.com) Redis安装要根据系统平台的实际情况而定&#xff0c;我使用的是免安装的 下载完成&#xff0c;解压之后打开文件夹…

怎么计算 flex-shrink 的缩放尺寸

计算公式: 子元素的宽度 - (子元素的宽度的总和 - 父盒子的宽度) * (某个元素的flex-shrink / flex-shrink总和) 面试问题是这样的下面 left 和 right 的宽度分别是多少 * {padding: 0;margin: 0;}.container {width: 500px;height: 300px;display: flex;}.left {width: 500px…