【学习OpenCV】高效遍历Mat
2014-11-29 14:07
363 查看
用指针来遍历图像
方法:取出图像中第i行数据的指针:image.ptr<uchar>(i),再访问各列元素。
一般来说图像行与行之间往往存储是不连续的,但是有些图像可以是连续的,Mat提供了一个检测图像是否连续的函数isContinuous()。当图像连通时,我们就可以把图像完全展开,看成是一行。
注:若算法对行列敏感,不能采用第2种方法,因为已经转换为1维!
用指针除了用上面的方法外,还可以用指针来索引固定位置的像素:
image.step返回图像一行像素元素的个数(包括空白元素),image.elemSize()返回一个图像像素的大小。
&image.at<uchar>(i,j)=image.data+i*image.step+j*image.elemSize();
实验证明
虽然把遍历方式改为指针,但发现release下的速度与at方法差不多(快一点点);而debug下的确是快很多;这说明,在编译的时候,release会对at方法进行优化的!所以,在满足算法的实时性要求的条件下,为了代码的可读性,还是直接用at方法吧,而且用着还方便。
另一个比较at方法与指针方法的例子:
1000*1000矩阵的16位整型转换32位浮点,输入Mat src为1000*1000的CV_16U类型,输出Mat dst
-------------------------END---------------------------------
方法:取出图像中第i行数据的指针:image.ptr<uchar>(i),再访问各列元素。
unsigned char * pData = BmpStream+1078; int nr=img1.rows; int nc=img1.cols; for(int i=nr-1;i>=0;i--) //遍历mat { const uchar* inData=img1.ptr<uchar>(i); for(int j=0;j<nc;j++) { *pData++= inData[j]; } }
一般来说图像行与行之间往往存储是不连续的,但是有些图像可以是连续的,Mat提供了一个检测图像是否连续的函数isContinuous()。当图像连通时,我们就可以把图像完全展开,看成是一行。
unsigned char * pData = BmpStream+1078; int nr=img1.rows; int nc=img1.cols; if(img1.isContinuous()) { nr=1; nc=nc*img1.rows*img1.channels(); } for(int i=0;i<nr;i++) //遍历mat { const uchar* inData=img1.ptr<uchar>(i); for(int j=0;j<nc;j++) { *pData++= * inData ++; } }
注:若算法对行列敏感,不能采用第2种方法,因为已经转换为1维!
用指针除了用上面的方法外,还可以用指针来索引固定位置的像素:
image.step返回图像一行像素元素的个数(包括空白元素),image.elemSize()返回一个图像像素的大小。
&image.at<uchar>(i,j)=image.data+i*image.step+j*image.elemSize();
实验证明
虽然把遍历方式改为指针,但发现release下的速度与at方法差不多(快一点点);而debug下的确是快很多;这说明,在编译的时候,release会对at方法进行优化的!所以,在满足算法的实时性要求的条件下,为了代码的可读性,还是直接用at方法吧,而且用着还方便。
另一个比较at方法与指针方法的例子:
1000*1000矩阵的16位整型转换32位浮点,输入Mat src为1000*1000的CV_16U类型,输出Mat dst
//方式一 : at方法 for(int i=0;i<h;i++) //遍历行 { for(int j=0;j<w;j++) //遍历列 { dst.at<float>(i,j) = (float)src.at<unsigned short>(i,j); } }速度最慢
//方式二 : converTo方法 src.convertTo(dst,CV_32F);比at方法快
//方式三 : 指针 unsigned short* psrc = (unsigned short*)src.data; //float *pdst = new float [src.total()]; float *pdst = (float*)dst.data; for(int i=0;i<h;i++) //遍历行 { const unsigned short* p0 = psrc + i*w; float* p1 = pdst + i*w; for(int j=0;j<w;j++) //遍历列 { *p1++= (float)p0[j]; } }速度与convertTo差不多
-------------------------END---------------------------------
相关文章推荐
- 小赵学习Opencv(3)之高效图像遍历循环
- OpenCV学习C++接口 Mat像素遍历详解
- OpenCV学习C++接口 Mat像素遍历详解
- OpenCV学习:Mat矩阵合并两张图像
- OpenCV学习笔记(三)——Mat,图像的新容器
- [原]opencv学习之QT,Mat 2 QImage
- 基础学习笔记之opencv(8):Mat - 基本图像容器
- OpenCV深入学习(7)--Mat的元素分布图示详解
- OpenCV学习:Mat类详细解析+源码剖析(三)遍历矩阵中元素
- 【OpenCV学习笔记】之二:Mat使用的潜规则----对数据类型敏感
- 【OpenCV学习】错误的案例:矩阵的遍历赋值和取值
- OpenCv学习笔记(二)—cv::Mat学习
- OpenCV学习——错误的案例:矩阵的遍历赋值和取值
- oencv学习(7)--Mat学习遍历以及赋值
- OpenCV学习笔记(三)——Mat,图像的新容器
- 我的OpenCV学习笔记(23):Mat中实际数据是如何保存的
- OpenCV深入学习(4)--Mat元素的获取方法
- OpenCV深入学习(2)-Mat构造初始化等
- openCv学习笔记(二)—cv::Mat学习
- OpenCV学习笔记 cv.Mat 与 .txt 文件数据的读写操作