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

发布于 2024-08-13 15:12:57 字数 233 浏览 2 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

她比我温柔 2024-08-20 15:12:57

关于文档:

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

它说:

(...) 如果你知道矩阵元素
输入,例如它是float,那么你可以
使用at<>()方法

即可以使用:

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

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

On the documentation:

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

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.

柠檬色的秋千 2024-08-20 15:12:57

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

//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<> 快得多。访问。希望有帮助!

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!

浮生面具三千个 2024-08-20 15:12:57

基于@J. Calleja 说,你有两种选择

方法 1 - 随机访问

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

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

方法 2 - 连续访问

如果你想连续访问,OpenCV 提供了与 STL 迭代器兼容的 Mat 迭代器< /code> ,它更具 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 语言的动态二维数组,更加直观和易于理解。

见下图。

输入图片描述这里

Based on what @J. Calleja said, you have two choices

Method 1 - Random access

If you want to random access the element of Mat, just simply use

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

Method 2 - Continuous access

If you want to continuous access, OpenCV provides Mat iterator compatible with STL iterator and it's more C++ style

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.

See the picture below.

enter image description here

z祗昰~ 2024-08-20 15:12:57

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

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

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

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

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.

墟烟 2024-08-20 15:12:57

对于cv::Mat_; 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

For cv::Mat_<T> mat just use mat(row, col)

Accessing elements of a matrix with specified type cv::Mat_< _Tp > is more comfortable, as you can skip the template specification. This is pointed out in the documentation as well.

code:

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;

output:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文