【C++&opencv】cv::Mat矩阵操作
·
OpenCV 中的矩阵主要通过 cv::Mat 类实现,它是存储和操作图像/矩阵数据的核心数据结构。
1. 创建矩阵
#include <opencv2/opencv.hpp>
// 空矩阵
cv::Mat emptyMat;
// 指定尺寸和类型 (行, 列, 类型)
cv::Mat mat(3, 3, CV_8UC1); // 3x3 单通道 8位无符号整数
// 初始化值
cv::Mat ones = cv::Mat::ones(2, 2, CV_32F); // 全1矩阵
cv::Mat zeros = cv::Mat::zeros(3, 3, CV_64F); // 全0矩阵
cv::Mat eye = cv::Mat::eye(4, 4, CV_32S); // 单位矩阵
// 直接初始化数据
cv::Mat data = (cv::Mat_<float>(2, 2) << 1.0, 2.5, -1.3, 4.7);
2. 访问和修改元素
单通道矩阵
// 方法1: at<类型>(行, 列)
float val = data.at<float>(1, 0); // 获取 (1,0) 位置的值
data.at<float>(0, 1) = 3.14; // 修改 (0,1) 位置的值
// 方法2: 指针遍历
for (int r = 0; r < data.rows; r++) {
float* row = data.ptr<float>(r);
for (int c = 0; c < data.cols; c++) {
row[c] *= 2; // 每个元素乘以2
}
}
多通道矩阵 (如BGR图像)
cv::Mat img(100, 200, CV_8UC3); // 100行 x 200列 x 3通道 (BGR)
// 访问像素 (y, x)
img.at<cv::Vec3b>(10, 20) = cv::Vec3b(255, 0, 0); // 设置 (10,20) 为蓝色
// 拆分通道
std::vector<cv::Mat> channels;
cv::split(img, channels); // channels[0]=B, channels[1]=G, channels[2]=R
3. 矩阵运算
cv::Mat A = (cv::Mat_<float>(2,2) << 1, 2, 3, 4);
cv::Mat B = (cv::Mat_<float>(2,2) << 5, 6, 7, 8);
// 基本运算
cv::Mat add = A + B; // 加法
cv::Mat sub = A - B; // 减法
cv::Mat mul = A * B; // 矩阵乘法 (不是逐元素乘!)
cv::Mat scale = 2.5 * A; // 标量乘法
// 逐元素乘法/除法
cv::Mat elemMul;
cv::multiply(A, B, elemMul);
// 转置和逆
cv::Mat T = A.t(); // 转置
cv::Mat invA;
cv::invert(A, invA, cv::DECOMP_LU); // 求逆 (需可逆矩阵)
4. 矩阵属性
int rows = A.rows; // 行数
int cols = A.cols; // 列数
int channels = A.channels(); // 通道数
cv::Size size = A.size(); // 尺寸 (width=cols, height=rows)
int depth = A.depth(); // 数据类型 (e.g., CV_32F)
// 检查空矩阵
if (A.empty()) {
std::cerr << "Matrix is empty!";
}
5. 实用操作
// 克隆数据 (深拷贝)
cv::Mat copy = data.clone();
// 裁剪区域 (ROI)
cv::Mat roi = data(cv::Rect(0, 0, 2, 2)); // 前2行前2列
// 改变形状 (不复制数据)
cv::Mat reshaped = data.reshape(1, 6); // 改为6行1列单通道
// 保存/加载矩阵
cv::FileStorage fs("matrix.xml", cv::FileStorage::WRITE);
fs << "mat" << data;
fs.release();
6. 数据类型说明
| 类型常量 | 含义 | 对应C++类型 |
|---|---|---|
CV_8U | 8位无符号整数 | uchar |
CV_8S | 8位有符号整数 | char |
CV_16U | 16位无符号整数 | ushort |
CV_32S | 32位有符号整数 | int |
CV_32F | 32位浮点数 | float |
CV_64F | 64位浮点数 | double |
CV_16F | 16位浮点数 | cv::float16_t |
- 通道表示:
CV_[位数][类型]C[通道数]
例如:CV_8UC3表示 8位无符号整数 + 3通道(BGR图像)。
示例:矩阵乘法解线性方程组
// 解 Ax = b
cv::Mat A = (cv::Mat_<float>(3, 3) << 1, 2, 3,
4, 5, 6,
7, 8, 10);
cv::Mat b = (cv::Mat_<float>(3, 1) << 3, 6, 9);
cv::Mat x;
cv::solve(A, b, x, cv::DECOMP_LU);
std::cout << "Solution:\n" << x << std::endl;
更多推荐


所有评论(0)