读取数据cv :: Mat

时间:2014-08-01 08:16:31

标签: c++ opencv

我正在寻找一种更好的方式从cv::Mat 32F3C获取数据,我使用的是: Vec3f c1 = _image.at<Vec3f>(i,j);它工作得很好,但不是很快,我看到这种方式更好:

Vec3f c1(_image.data[step[0]*i + step[1]*j + 0],_image.data[step[0]*i + step[1]*j + 1],_image.data[step[0]*i + step[1]*j + 2]);

它编译但是它不正确,我也试过了:

Vec3f c1(_image.data[step*i + channels*j + 0],_image.data[step*i + channels*j + 1],_image.data[step*i + channels*j + 2]);

但同样的事情,它编译但给我另一个荒谬的结果。

我一定是错过了一个因素。

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以超越at()函数调用并直接访问数据。使用cv :: Mat :: ptr(http://docs.opencv.org/modules/core/doc/basic_structures.html)获取指向图像每行第一个元素的指针。接下来,您可以使用数组[index] -operator。

访问该行中的所有元素

图像数据大部分时间是在内存中连续的,但并非总是如此(考虑在另一个cv :: Mat中选择感兴趣的区域)。您可以在此处找到示例:OpenCV C++: how access pixel value CV_32F through uchar data pointer。图像行是连续的,这就是为什么你在每次迭代中询问指向第一个元素的指针,然后可以安全地访问其他元素。

答案 1 :(得分:2)

您可能会发现OpenCV文档中的this article有用。但是,我首先要编写易于理解的代码,并且只有优化它,如果很明显我必须完全优化源代码的那部分。

文章的要点是,有三种方法可以访问像素:

  1. 动态地址计算:

    const cv::Vec3f& pixel = img.at< cv::Vec3f >(y, x)
    
  2. 迭代器:

    cv::MatIterator< cv::Vec3f > it=img.begin(), end=img.end();
    for ( ; it != end ; ++it ) (*it)[0] = (*it)[1]
    
  3. 指针:

    cv::Vec3f* pixel_ptr;
    for (int y = 0; y < img.rows; ++y)
    {
        pixel_ptr = img.ptr<cv::Vec3f>(y);
        for  (int x = 0; x < img.cols; ++x)
        {
            (*pixel_ptr)[0] = (*pixel_ptr)[1]
            ++pixel_ptr;
        }
    }
    

答案 2 :(得分:1)

基于the efficient way

cv::Mat _image = something;

for(int y = 0; y < _image.rows; ++y)
{
    cv::Vec3f* _image_row = _image.ptr<cv::Vec3f>(y);
    for(int x = 0; x< _image.cols; ++x)
    {
        cout << _image_row[x] << " ";
    }
    cout << endl;
}