OpenCV: Mat存储方式全解析-单通道、多通道内存布局详解

在使用 OpenCV 的过程中,我们经常会接触 cv::Mat 这种图像矩阵类型。理解 Mat 在内存中的布局非常重要,尤其是做指针访问、性能优化、SIMD(如 AVX/NEON)加速时。本文将详细介绍:

  • Mat 的存储方式

  • 单通道 vs 多通道的内存布局

  • 如何用指针访问某个像素

  • 判断 Mat 是否连续

  • 实战图示与代码

1️⃣ Mat 的存储特性

cv::Mat 是一个行优先(Row-major)、通常连续(Continuous)的多维数组,数据区存储像素值。

  • 行优先:按行存储,每一行像素紧挨着。

  • 通道连续:多通道像素的各通道值依次存储。

  • 可能有行间对齐填充 :当 Mat 是 ROI(子图)或手动创建带 padding 的图像时,行与行之间可能有"间隙",此时 Mat::isContinuous() 会返回 false

2️⃣ 单通道示例(CV_8UC1)

假设一张 3×3 的灰度图:

在内存中是这样的:

cpp 复制代码
data →
[10][20][30][40][50][60][70][80][90]

每个像素占用 1 字节,行优先顺序排列。

3️⃣ 多通道示例(CV_8UC3)

假设一张 2×3 的彩色图像,每个像素是 (B,G,R)

内存布局:

cpp 复制代码
Row 0: [10][20][30][40][50][60][70][80][90]
Row 1: [11][21][31][41][51][61][71][81][91]

注意:

  • 并不是"打包成一个 24 位整数",而是 3 个独立的字节 挨着存储。

  • 每像素大小 = elemSize() = 3 字节。

4️⃣ 像素索引 → 内存地址

要访问 (row, col) 的像素,可以用

cpp 复制代码
cv::Mat img = cv::imread("test.png"); // 假设是 CV_8UC3
int row = 1, col = 2;

// 定位到(row,col)的像素指针
uchar* pixelPtr = img.data + row * img.step + col * img.elemSize();

uchar B = pixelPtr[0];
uchar G = pixelPtr[1];
uchar R = pixelPtr[2];
  • img.data:首地址

  • img.step:每行占用字节数

  • img.elemSize():每个像素占用字节数(多通道时>1)

5️⃣ 判断 Mat 是否连续

有些操作(如 memcpy、手动指针循环)需要连续内存

cpp 复制代码
if (img.isContinuous()) {
    // 数据连续,可以直接用指针一次性遍历所有像素
} else {
    // 数据不连续,需要按行处理
}

6️⃣ 图示

下面是 2×3,CV_8UC3 的直观示意图:

cpp 复制代码
内存布局 (2x3, CV_8UC3):
data →
┌───────────── Row 0 ─────────────┐┌───────────── Row 1 ─────────────┐
[10][20][30][40][50][60][70][80][90][11][21][31][41][51][61][71][81][91]
└─────────────  9 * 1 byte ───────┘└─────────────  9 * 1 byte ───────┘

7️⃣ 小结

  • cv::Mat 默认是行优先、连续存储。

  • 多通道像素值按通道顺序紧挨着。

  • 使用 data + row*step + col*elemSize() 快速定位像素。

  • isContinuous() 判断是否可以一次性处理所有数据。

相关推荐
阿里巴巴中间件18 小时前
阿里云 AI 中间件重磅发布,打通 AI 应用落地“最后一公里”
人工智能·阿里云·中间件·云计算
学海一叶18 小时前
Agent开发02-关键思想(ReAct、ReWOO、Reflexion、LLM Compiler等)
人工智能·算法·llm·agent·plan
虹科数字化与AR19 小时前
安宝特科技丨【行业首发】Vuzix LX1智能眼镜:仓储物流的下一代智能助手
人工智能·科技·ar眼镜·智慧仓储·仓储物流·工业ar·vuzix
用户62568518576119 小时前
基于51单片机的电子密码锁设计与实现
人工智能
Learn Beyond Limits19 小时前
Initializing K-means|初始化K-means
人工智能·python·算法·机器学习·ai·kmeans·吴恩达
自成居士19 小时前
从神经网络到深度学习
人工智能·深度学习·神经网络·莱布尼茨·普遍语言
CoovallyAIHub19 小时前
数据稀缺?不存在的!手把手教你用ChatGPT+Stable Diffusion合成铁路异物检测数据集
深度学习·算法·计算机视觉
Wah-Aug19 小时前
PyTorch 模型评估与全局平均池化的应用实践
人工智能·pytorch·python
诸葛箫声19 小时前
基于PyTorch的CIFAR-10图像分类项目总结(2)
人工智能·pytorch·分类
Elastic 中国社区官方博客19 小时前
理解 Elasticsearch 中的分块策略
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索