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_8U8位无符号整数uchar
CV_8S8位有符号整数char
CV_16U16位无符号整数ushort
CV_32S32位有符号整数int
CV_32F32位浮点数float
CV_64F64位浮点数double
CV_16F16位浮点数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;

更多推荐