在 OpenCV C++ 中访问“Mat”对象(不是 CvMat 对象)中的矩阵元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1844736/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing a matrix element in the "Mat" object (not the CvMat object) in OpenCV C++
提问by neptune
How to access elements by row, col in OpenCV 2.0's new "Mat" class? The documentation is linked below, but I have not been able to make any sense of it. http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat
如何在 OpenCV 2.0 的新“Mat”类中按行、列访问元素?文档链接如下,但我无法理解它。 http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat
回答by J. Calleja
On the documentation:
在文档上:
http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat
http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat
It says:
它说:
(...) if you know the matrix element type, e.g. it is float, then you can use at<>() method
(...) 如果您知道矩阵元素类型,例如它是浮点数,那么您可以使用 at<>() 方法
That is, you can use:
也就是说,您可以使用:
Mat M(100, 100, CV_64F);
cout << M.at<double>(0,0);
Maybe it is easier to use the Mat_
class. It is a template wrapper for Mat
.
Mat_
has the operator()
overloaded in order to access the elements.
也许使用Mat_
类更容易。它是Mat
.
Mat_
具有operator()
重载以访问元素。
回答by Mircea Paul Muresan
The ideas provided above are good. For fast access (in case you would like to make a real time application) you could try the following:
上面提供的想法很好。为了快速访问(如果您想制作实时应用程序),您可以尝试以下操作:
//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
}
}
Pointer access is much faster than the Mat.at<> accessing. Hope it helps!
指针访问比 Mat.at<> 访问快得多。希望能帮助到你!
回答by WY Hsu
Based on what @J. Calleja said, you have two choices
基于什么@J。Calleja说,你有两个选择
Method 1 - Random access
方法 1 - 随机访问
If you want to random access the element of Mat, just simply use
如果你想随机访问 Mat 的元素,只需简单地使用
Mat.at<data_Type>(row_num, col_num) = value;
Method 2 - Continuous access
方法 2 - 连续访问
If you want to continuous access, OpenCV provides Mat iterator compatible with STL iterator
and it's more C++
style
如果你想连续访问,OpenCV提供了兼容的Mat迭代器STL iterator
,它的C++
风格更
MatIterator_<double> it, end;
for( it = I.begin<double>(), end = I.end<double>(); it != end; ++it)
{
//do something here
}
or
或者
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
}
}
If you have any difficulty to understand how Method 2 works, I borrow the picture from a blog post in the article Dynamic Two-dimensioned Arrays in C, which is much more intuitive and comprehensible.
如果您对方法2的工作原理有任何理解上的困难,我借用C中动态二维数组一文中的博文中的图片,它更加直观和易于理解。
See the picture below.
见下图。
回答by Ben
OCV goes out of its way to make sure you can't do this without knowing the element type, but if you want an easily codable but not-very-efficient way to read it type-agnostically, you can use something like
OCV 竭尽全力确保您在不知道元素类型的情况下无法执行此操作,但是如果您想要一种易于编码但不是非常有效的方式来读取它的类型不可知,您可以使用类似
double val=mean(someMat(Rect(x,y,1,1)))[channel];
To do it well, you do have to know the type though. The at<> method is the safe way, but direct access to the data pointer is generally faster if you do it correctly.
要想做得好,你必须知道类型。at<> 方法是一种安全的方法,但如果操作正确,直接访问数据指针通常会更快。