• OpenCV 使用at和ptr指针访问像素的区别


    mat.at<int>( i ); 整型数组问中的元素 i
    mat.at<float>( i,j ); 浮点型数组附中的元素(i, j)
    mat.at<int>( pt ) 整型矩阵问中处于 (pt.x,pt.y) 的元素
    mat.at<float>( i,j,k ); 三维浮点型矩阵M 中处于 (1,j,k) 位置的元素
    mat.at<uchar>( idx ); 无符号字符数组问中位于idx[ ]所索引的n维位置的元素

      为了访问二维数组,你可以使用 C风格的指针来指定某行 。这个工作由cv::Mat类的成员函数 ptr<>()完成(再次强调,数组中的数据是按行连续组织的,因此不可以通过这种方式访问一个指定的列),由于at<>(),ptr<>() 都是模板函数,所以需要一个类型名来进行实例化。函数接收一个整型参数来指示希望指针指向的行,函数将返回一个和矩阵原始数据类型相同的数据指针(比如说,如果数组类型是CV_32FC3,它会返回一个float* 。因此,给定一个类型为float三通道的矩阵mtx,结构体mtx.ptr<VeC3f>(3)将会返回mtx的第三行指向第一个元素第一个(浮点)通道的指针,这通常是访问数组最快的方式,因为一旦你拥有指针,就可以向指定的位置写入数据。

      使用at<>和利用指针访问的差距取决于编译器的优化程度。使用at<>进行存储性能更接近于好的优化器所能够达到的效果(尽管稍微慢一些)但是如果优化器被关闭了,其性能相较于没有优化器优化会有一个数量级的提升。 而通过迭代器的访问几乎总是比这两种方法都要慢,然而在几乎所  有情况下,使用内置的opencv函数都比你写的所有通过循环来控制直接访问的方法快,所以在任何情况下,都要避免通过循环来大量访问矩阵内部结构。

      有两种方式可以获得一个指向矩阵的数据区域的指针。一种是使用ptr<>()成员函数,另一种是直接使用数据指针data,然后使用成员数组step来计算地址,后者更接近于C语言操作。但是一般来说,由于at<>()和ptr<>()以及迭代器的存在,这种方式已经不再推荐了。

      直接计算地址始终是最有效率的做法,尤其是要处理多于二维的数组时!

     1     int sz[3] = { 4, 4, 4 };
     2     cv::Mat m(3, sz, CV_32FC3); // A three-dimensional array of size 4-bY-4-bY-4
     3     cv::randu(m, -1.0f, 1.0f); // fill with random numbers from -1.0 to 1.0
     4  
     5     for (int i = 0; i < 4; i++)
     6     {
     7         for (int j = 0; j < 4; j++)
     8         {
     9             for (int k = 0; k < 4; k++)
    10             {
    11                 cout << m.at<float>(i, j, k) << " ";
    12             }
    13             cout << "
    ";
    14         }
    15         cout << "
    ";
    16     }
    17  
    18     float max = 0.0f;
    19     //cv::MatConstIterator<Vec3f> it = m.begin();
    20     //cv::MatConstIterator it = m.begin();
    21     for (int i = 0; i < 4; i++)
    22     {
    23         for (int j = 0; j < 4; j++)
    24         {
    25             float *data = m.ptr<float>(i, j);
    26             for (int k = 0; k < 4; k++)
    27             {
    28                 float len2;
    29                 len2 = *data + *(data + 1) + *(data + 2) + *(data + 3);
    30                 if ( len2 > max )
    31                     max = len2;
    32             }
    33         }
    34     }
    35  
    36     cout << "max = " << max << endl;
    
    
  • 相关阅读:
    内置的包装类
    子类继承父类的哪些成员
    JAVA笔记140-使用this语句解决构造器重载相互调用问题
    Java学习
    AngularJs2
    Angular
    检测是否所有的栏位都已经填充了内容了。(可以用来判断动态放置的东西和外加的框是否一致)
    上下各有一个框,框里有元素(点击下面的元素,显示到上面的框里面去,按一定顺序排放)
    Nashorn 在JDK 8中融合Java与JavaScript之力
    2014年Facebook的开源成就
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14095678.html
Copyright © 2020-2023  润新知