You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用cv::Mat::at<double>(i,j,k)访问多通道矩阵?

如何正确使用cv::Mat::at(i,j,k)访问多通道矩阵元素?

测试代码

#include <iostream>
#include <opencv2/highgui/highgui.hpp>

int main()
{
    double m[1][4][3] = 
        {
            {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}, {10.0, 11.0, 12.0}}};

    cv::Mat M(1, 4, CV_64FC3, m);

    for (int i = 0; i < 1; ++i)
        for (int j = 0; j < 4; ++j)
            for (int k = 0; k < 3; ++k)
                std::cout << M.at<double>(i, j, k) << std::endl;

    cv::namedWindow("Input", cv::WINDOW_NORMAL);
    cv::imshow("Input", M);
    cv::waitKey();

    return 0;
}

预期输出

1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
10.0
11.0
12.0

当前输出

1
8.10465e-320
5.31665e-315
4
8.11058e-320
2.122e-314  
7
8.11355e-320
-9.44163e+21
10
7.16685e-308
0

问题原因与解决方法

你当前的写法错误在于:OpenCV的2D多通道矩阵不能用at<double>(i,j,k)来访问通道元素。这里的k会被误认为是3D矩阵的第三个维度索引,但你的矩阵是2D结构(1行4列,3通道),并非3D矩阵,这种访问方式会直接越界读取内存,导致输出垃圾值。

针对多通道矩阵的元素访问,推荐两种正确方式:

方式一:使用对应通道数的向量类型访问(推荐)

对于CV_64FC3类型的矩阵,每个像素是包含3个double的向量,对应OpenCV的cv::Vec3d类型。通过at<cv::Vec3d>(i,j)获取像素的向量值,再通过索引访问单个通道:

for (int i = 0; i < 1; ++i)
    for (int j = 0; j < 4; ++j) {
        cv::Vec3d pixel = M.at<cv::Vec3d>(i, j);
        for (int k = 0; k < 3; ++k)
            std::cout << pixel[k] << std::endl;
    }

方式二:通过内存偏移直接访问单个通道

如果坚持用double类型访问,可以利用OpenCV行优先的内存存储规则,计算通道的内存偏移位置:

for (int i = 0; i < 1; ++i)
    for (int j = 0; j < 4; ++j)
        for (int k = 0; k < 3; ++k)
            std::cout << M.at<double>(i, j * 3 + k) << std::endl;

这种方式需要手动计算每个通道在内存中的位置,可读性较差,不推荐。

方式三:使用指针直接访问

对于性能要求较高的场景,也可以用ptr方法获取行指针,直接遍历内存:

for (int i = 0; i < M.rows; ++i) {
    double* row = M.ptr<double>(i);
    for (int j = 0; j < M.cols; ++j) {
        for (int k = 0; k < 3; ++k) {
            std::cout << row[j * 3 + k] << std::endl;
        }
    }
}

内容的提问来源于Stack Exchange,提问作者Display Name

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 15:06:47