繁体   English   中英

在 OpenCV C++ 中访问“Mat”对象(不是 CvMat 对象)中的矩阵元素

[英]Accessing a matrix element in the “Mat” object (not the CvMat object) in OpenCV C++

如何在 OpenCV 2.0 的新“Mat”类中按行、列访问元素? 文档链接如下,但我无法理解它。 http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat

在文档上:

http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat

它说:

(...) 如果您知道矩阵元素类型,例如它是浮点数,那么您可以使用 at<>() 方法

也就是说,您可以使用:

Mat M(100, 100, CV_64F);
cout << M.at<double>(0,0);

也许使用Mat_类更容易。 它是Mat的模板包装器。 Mat_重载了operator()以访问元素。

上面提供的想法很好。 为了快速访问(如果您想制作实时应用程序),您可以尝试以下操作:

//suppose you read an image from a file that is gray scale
Mat image = imread("Your path", CV_8UC1);
//...do some processing
uint8_t *myData = image.data;
int width = image.cols;
int height = image.rows;
int _stride = image.step;//in case cols != strides
for(int i = 0; i < height; i++)
{
    for(int j = 0; j < width; j++)
    {
        uint8_t val = myData[ i * _stride + j];
        //do whatever you want with your value
    }
}

指针访问比 Mat.at<> 访问快得多。 希望能帮助到你!

基于什么@J。 Calleja说,你有两个选择

方法 1 - 随机访问

如果你想随机访问 Mat 的元素,只需简单地使用

Mat.at<data_Type>(row_num, col_num) = value;

方法 2 - 连续访问

如果你想连续访问,OpenCV提供了与STL iterator器兼容的Mat迭代STL iterator ,它更像C++风格

MatIterator_<double> it, end;
for( it = I.begin<double>(), end = I.end<double>(); it != end; ++it)
{
    //do something here
}

要么

for(int row = 0; row < mat.rows; ++row) {
    float* p = mat.ptr(row); //pointer p points to the first place of each row
    for(int col = 0; col < mat.cols; ++col) {
         *p++;  // operation here
    }
}

如果您对方法2的工作方式有任何理解上的困难,我借用C中动态二维数组一文中的博客文章中的图片,它更加直观和易于理解。

见下图。

在此处输入图片说明

OCV 竭尽全力确保您在不知道元素类型的情况下无法执行此操作,但是如果您想要一种易于编码但不是非常有效的方式来读取它的类型不可知,您可以使用类似

double val=mean(someMat(Rect(x,y,1,1)))[channel];

要想做得好,你必须知道类型。 at<> 方法是一种安全的方法,但如果操作正确,直接访问数据指针通常会更快。

对于cv::Mat_<T> mat只需使用mat(row, col)

访问具有指定类型cv::Mat_< _Tp >的矩阵元素更方便,因为您可以跳过模板规范。 文档中也指出了这一点。

代码:

cv::Mat1d mat0 = cv::Mat1d::zeros(3, 4);
std::cout << "mat0:\n" << mat0 << std::endl;
std::cout << "element: " << mat0(2, 0) << std::endl;
std::cout << std::endl;

cv::Mat1d mat1 = (cv::Mat1d(3, 4) <<
    1, NAN, 10.5, NAN,
    NAN, -99, .5, NAN,
    -70, NAN, -2, NAN);
std::cout << "mat1:\n" << mat1 << std::endl;
std::cout << "element: " << mat1(0, 2) << std::endl;
std::cout << std::endl;

cv::Mat mat2 = cv::Mat(3, 4, CV_32F, 0.0);
std::cout << "mat2:\n" << mat2 << std::endl;
std::cout << "element: " << mat2.at<float>(2, 0) << std::endl;
std::cout << std::endl;

输出:

mat0:
[0, 0, 0, 0;
 0, 0, 0, 0;
 0, 0, 0, 0]
element: 0

mat1:
[1, nan, 10.5, nan;
 nan, -99, 0.5, nan;
 -70, nan, -2, nan]
element: 10.5

mat2:
[0, 0, 0, 0;
 0, 0, 0, 0;
 0, 0, 0, 0]
element: 0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM