OpenCV Mat 数据成员访问

Posted

技术标签:

【中文标题】OpenCV Mat 数据成员访问【英文标题】:OpenCV Mat data member access 【发布时间】:2015-12-02 11:54:46 【问题描述】:

我见过很多直接访问cv::Mat 的数据成员的OpenCV 代码。 cv::Mat 将指向数据的指针存储在 unsigned char* data 成员中。对数据成员的访问如下所示:

cv::Mat matUC(3,3,CV_8U)
int rowIdx = 1;
int colIdx = 1;

unsigned char val = matUC.data[ rowIdx * matUC.cols + colIdx]

我想知道这是否适用于像素类型不是unsigned charcv::Mat

cv::Mat matF(3,3,CV_32F)
int rowIdx = 1;
int colIdx = 1;

float val = matF.data[ rowIdx * matF.cols + colIdx];

我的理解是需要进行类型转换才能正确访问元素。比如:

float val = ((float*)matF.data)[ rowIdx * matF.cols + colIdx];

我见过很多不使用类型转换的代码。所以我的问题是:类型转换是否必须访问正确的元素?

【问题讨论】:

试试:float val = matF.at<float>(rowIdx, colIdx); 请注意,data[row * cols + col] 仅适用于矩阵 isContinuous()。如果您没有该信息,最安全的方法是matrix.ptr<type>(row)[col] 【参考方案1】:

Mat 数据是uchar*。如果你有一个浮点矩阵CV_32FC1,你需要以float 访问数据。

你可以用不同的方式来做,不一定使用强制转换:

#include <opencv2\opencv.hpp>
using namespace cv;

int main()

    cv::Mat matF(3, 3, CV_32F);
    randu(matF, Scalar(0), Scalar(10));

    int rowIdx = 1;
    int colIdx = 1;

    // 1
    float f1 = matF.at<float>(rowIdx, colIdx);

    // 2
    float* fData2 = (float*)matF.data;
    float f2 = fData2[rowIdx*matF.step1() + colIdx];

    // 3
    float* fData3 = matF.ptr<float>(0);
    float f3 = fData3[rowIdx*matF.step1() + colIdx];

    // 4
    float* fData4 = matF.ptr<float>(rowIdx);
    float f4 = fData4[colIdx];

    // 5
    Mat1f mm(matF); // Or directly create like: Mat1f mm(3, 3);
    float f5 = mm(rowIdx, colIdx);

    // f1 == f2 == f3 == f4 == f5

    return 0;

备注

通过指针直接访问data时最好使用step1()而不是cols,因为图像可能不连续。更多详情请查看here。 sn-p 改编自这个my other answer

【讨论】:

cv::Mat matF(3,3,CV_32F) 这样创建的 Mat 是否始终保证是连续的? 是的,请查看here 了解更多详情。 这完全回答了我的问题。感谢您的努力!

以上是关于OpenCV Mat 数据成员访问的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV Mat类常用成员属性和成员方法

OpenCV Mat类常用成员属性和成员方法

OpenCV中Mat的data成员解析

详解OpenCV的Mat类(构造方法初始化方法常用属性常用成员函数常用操作)

Opencv 在 cv::Mat 中存储 Yuyv (YCrCb)

OpenCV_Mat类对象的基本操作常用操作及相关成员函数介绍