04.OpenCV cv::Mat之(一)创建数据对象
在 OpenCV 中,cv::Mat 是一个非常重要的类,它负责存储图像以及其他多维数据。无论你是在进行简单的图像读取、图像变换,还是进行复杂的计算机视觉任务,对 cv::Mat 的深入理解都至关重要。本文将从多个角度介绍 cv::Mat 的基本概念、创建与初始化、数据访问、内存管理及常见应用实例,帮助你更好地使用 OpenCV 开发图像处理应用。
OpenCV cv::Mat之(一)创建数据对象
上一篇:OpenCV图片色彩空间转换与图片保存 经常使用cv::Mat。在 OpenCV 中,cv::Mat 是一个非常重要的类,它负责存储图像以及其他多维数据。无论你是在进行简单的图像读取、图像变换,还是进行复杂的计算机视觉任务,对 cv::Mat 的深入理解都至关重要。本文将从多个角度介绍 cv::Mat 的基本概念、创建与初始化、数据访问、内存管理及常见应用实例,帮助你更好地使用 OpenCV 开发图像处理应用。
1、cv::Mat 的基本概念
cv::Mat 是 OpenCV 中用于表示矩阵数据的类,主要用于存储图像。一个 cv::Mat 对象由两部分组成:头部(header)和数据区(data)。
-
头部:包含了图像的维度、通道数、数据类型、步长(step)等信息。
-
数据区:存储了图像实际的像素数据。这个部分采用引用计数(reference counting)的方式管理内存,当多个 cv::Mat 对象共享同一数据时,只在所有对象都释放后才真正释放内存。这种设计使得,从而实现高效的内存管理。
cv::Mat 在拷贝时(例如直接赋值=)只复制头部信息,而不复制实际数据。
参考图来自其他网友,可以清楚了解基本结构:


2、cv::Mat 的创建与初始化
OpenCV 提供了多种方式来创建和初始化 cv::Mat 对象:
2.1 通过构造函数直接创建
你可以直接调用 cv::Mat 构造函数来创建一个指定大小和数据类型的矩阵。例如:运行后显示蓝色
#include <opencv2/opencv.hpp>
/**
* 构造函数创建mat对象.
*
*/
int main() {
// 创建一个 480x640,类型为 8 位 3 通道(彩色图像)的 cv::Mat 对象
// Mat的排列是BGR
cv::Mat image(480, 640, CV_8UC3);
image = 255;
cv::imshow("test", image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
cv::Mat image(480, 640, CV_8UC3)构造时:CV_8UC3数据类型宏格式说明:
数据深度(Data Depth)
- CV_8U:8 位无符号整数,取值范围 0~255。常用于普通的图像像素表示。
- CV_8S:8 位有符号整数,取值范围 -128~127,使用较少。
- CV_16U:16 位无符号整数,取值范围 0~65535,常用于深度图或需要更大动态范围的图像。
- CV_16S:16 位有符号整数。
- CV_32S:32 位有符号整数。
- CV_32F:32 位浮点数,常用于需要浮点精度的图像处理,比如滤波、梯度计算等。
- CV_64F:64 位浮点数,用于更高精度的计算
通道数(Channel Count): 用 C? 来表示,其中数字代表通道数:
- C1:单通道图像,例如灰度图。
- C3:三通道图像,通常表示彩色图像(BGR 顺序)。
- C4:四通道图像,通常用于带有 Alpha 通道的图像(BGRA 顺序)
3. 常见组合举例
- CV_8UC1:8 位无符号单通道图像,常用于灰度图。
- CV_8UC3:8 位无符号三通道图像,常用于彩色图像(BGR 格式)。
- CV_8UC4:8 位无符号四通道图像,适用于需要透明度通道的图像(如 PNG 中的 BGRA 格式)。
- CV_16UC1:16 位无符号单通道图像,可能用于深度图或高动态范围图像。
- CV_32FC1:32 位浮点单通道图像,经常出现在图像滤波、梯度计算等场景中。
- CV_64FC1:64 位浮点单通道图像,适合对精度要求极高的计算。
2.2 使用预定义函数初始化
OpenCV 提供了常用的初始化函数,如 cv::Mat::zeros、cv::Mat::ones 以及 cv::Mat::eye 来分别创建全零、全一或单位矩阵:
// 创建一个全零矩阵
cv::Mat zerosMat = cv::Mat::zeros(480, 640, CV_8UC3);
// 创建一个全一矩阵(所有像素值为 1)
cv::Mat onesMat = cv::Mat::ones(480, 640, CV_32F);
// 创建一个 5x5 的单位矩阵
cv::Mat eyeMat = cv::Mat::eye(5, 5, CV_64F);
2.3 读取图像文件
最常用的 cv::Mat 应用就是存储从文件中读取的图像数据:
cv::Mat srcImage=cv::imread("E:/image/opencv-logo.png");
// 判断图像是否读取成功
if (srcImage.empty())
{
std::cerr << "Error: Image not found." << std::endl;
return -1;
}
imshow("srcImage", srcImage);
cv::waitKey();
cv::destroyWindow("srcImage");
2.4.深拷贝与浅拷贝
由于 cv::Mat 使用引用计数来管理数据内存,直接赋值操作不会复制实际数据,而只是共享同一块内存,这叫做浅拷贝:
浅拷贝如果修改其中一个数据,同时也会影响另外一个
cv::Mat img1 = cv::imread("E:/image/opencv-logo.png");
cv::Mat img2 = img1; // img2 与 img1 共享同一数据区域
如果你希望创建一个独立的拷贝(深拷贝),可以使用 clone() 或 copyTo() 方法:
cv::Mat imgClone = img1.clone();
// 或者
cv::Mat imgCopy;
img1.copyTo(imgCopy);
这样 imgClone 和 imgCopy 都拥有独立的数据拷贝,对其中一个进行修改不会影响另一个。
3、参考代码
#include "stdio.h"
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
int main()
{
//构造创建mat对象-------------------------------------------------------------------------------------------
cv::Mat image(480, 640, CV_8UC3);
image = 255;
cv::imshow("test", image);
cv::waitKey();
cv::destroyWindow("test");
// 读取图像属于直接赋值-------------------------------------------------------------------------------------
cv::Mat srcImage=cv::imread("E:/image/opencv-logo.png");
// 判断图像是否读取成功
if (srcImage.empty())
{
std::cerr << "Error: Image not found." << std::endl;
return -1;
}
imshow("srcImage", srcImage);
cv::waitKey();
cv::destroyWindow("srcImage");
// 深拷贝-------------------------------------------------------------------------------------------
cv::Mat image1;
image1 = srcImage.clone();
srcImage = Scalar(0, 0, 255);//赋值不影响image1;
imshow("srcImage", srcImage);
imshow("test", image1);
cv::waitKey();
cv::destroyAllWindows();
// 浅拷贝-------------------------------------------------------------------------------------------
srcImage = cv::imread("E:/image/opencv-logo.png");
image1 = srcImage;
srcImage = Scalar(0, 0, 255);//影响image数据
imshow("srcImage", srcImage);
imshow("test", image1);
// 等待按键事件,按任意键关闭窗口
cv::waitKey(0);
destroyAllWindows();
return 0;
}
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)