访问Opencv中的Mat数据

如何访问Opencv中的Mat数据

 

第一种:使用成员函数at

                cv::Mat m = (cv::Mat_(2 ,3) << 1,2,3,4,5,6);//3行2列
                for (int i = 0; i < m.rows; ++i) {
                        for (int j = 0; j < m.cols; ++j) {
                              LOGD("optionMat i = %d, j = %d , at  = %d",i,j,m.at(i,j));
                        }
                 } 

  

第二种:使用成员函数ptr

                cv::Mat m = (cv::Mat_(2 ,3) << 11,12,33,43,51,16);//3行2列

                第一个元素是列坐标(列号),第二个元素是行坐标(行号),我们将水平方向作为x轴,将垂直方向作为y轴的习惯, 只是这里的y轴的方向是朝下的。

                对于Mat中的数值在内存中的存储,每一行的值是存储在连续的内存区域中的,通过成员函数ptr获得指向每一行首地址的指针。m中所有的值在内存中的存储方式如下图所示,其中如果行与行之间的存储是有内存间隔的,那么间隔也是相等的。

                                                         访问Opencv中的Mat数据_第1张图片

                 利用成员函数ptr返回的指针访问m中的值。

                 cv::Mat m = (cv::Mat_(2 ,3) << 11,12,33,43,51,16);//3行2列
                 for (int i = 0; i < m.rows; ++i) {
                        const int * ptr = m.ptr(i);
                        for (int j = 0; j < m2.cols; ++j) {
                              LOGD("optionMat ptr = %d",ptr[j]);
                        }
                   }

第三种:使用成员函数isContinuous和ptr

       每一行的所有值存储在连续的内存区域中,行与行之间可能会有间隔,如果isContinuous返回值为true,则代表行与行之间也是连续存储的,即所有的值都是连续存储的,如下图。

                                                               访问Opencv中的Mat数据_第2张图片

                cv::Mat m = (cv::Mat_(2 ,3) << 11,12,33,43,51,16);//3行2列
                if(m.isContinuous()){
                         int* ptr = m.ptr(0);
                        for (int i = 0; i < m.cols * m.rows; ++i) {
                               LOGD("optionMat is continuous %d ",ptr[i]);
                        }
                  } 

第四种:使用成员变量step和data

               成员变量---step和data。如果行与行之间有相等的内存间隔的情况,如下:

                                         访问Opencv中的Mat数据_第3张图片

                 如何行与行之间没有内存间隔,如下:

                                         访问Opencv中的Mat数据_第4张图片

          对于单通道矩阵来说,step[0]代表每一行所占的字节数,而如果有间隔的话,这个间隔也作为字节数的一部分被计算在内;step[1]代表每一个数值所占的字节数,data是指向第一个数值的指针,类型为uchar。所以,无论哪一种情况,如访问一个int类型的单通到矩阵的第r行第c列的值,都可以通过以下代码来实现。
                              *(int*)(m.data + m.step[0]*r + c * m.step[1]))
如果是CV_32F类型,则将int替换成float即可。

注:从取值效率上说,直接使用指针的形式取值是最快的,使用at是最慢的,但是可读性很高。

上一篇:Opencv中核心类Mat的创建方式

 

 

你可能感兴趣的:(OpenCV)