Lecture 3 opencv2系列之遍历Mat
来源:互联网 发布:成都专业seo外包 编辑:程序博客网 时间:2024/06/05 05:13
阅读本节内容,建议先阅读Lecture 2 opencv2系列之初识Mat,了解图像像素数据在Mat
中的存储方式。
《The OpenCV Tutorials》给出3种遍历Mat中图像像素矩阵的方法,分别是指针遍历(ptr)、迭代器(MatIterator)、
at函数,前两者亦分别称作高效方法、安全方法。其中最为高效的是指针方法。
本文只介绍指针方法。
以下代码实现对图像像素数据的遍历,我们打印图像的红色分量。
代码
#include <iostream>#include "opencv2/core/core.hpp"#include "opencv2/highgui/highgui.hpp"using namespace std;using namespace cv;int main(int argc, const char *argv[]){ if (argc != 2) { cout<<"Number of Parameters is Wrong!"<<endl; return -1; } Mat src = imread(argv[1],IMREAD_COLOR); int channels = src.channels(); int nRows = src.rows; //图像数据列需要考虑通道数的影响; int nCols = src.cols * channels; if (src.isContinuous())//连续存储的数据,按一行处理 { nCols *= nRows; nRows = 1; } int i,j; uchar* p; for( i = 0; i < nRows; ++i) { p = src.ptr<uchar>(i); for ( j = 2; j < nCols; j+=3)//注意通道顺序为BGR,红色为第三个数据; { cout<<int(p[j])<<" "; } cout<<endl; } return 0;}
释义
- 如果只是单纯打印图像数据的话,可以直接用
cout<<src
来实现,OpenCV2重定义了<<
运算符,实现
了矩阵的格式化输出。
详细内容参见The OpenCV Tutorials Release 2.4.9.0,p.148。 - 图像坐标系和像素矩阵。
图像左上角作为原点,按行和列展开。故图像左上角像素对应矩阵的0行0列数据,这里列不计通道。 - OpenCV默认使用BGR的通道顺序。
- 行数据的填补。
宽W高H的真彩色图像,像素数据存储需要WxHx3个uchar
构成的内存块,但是出于效率考虑,每行可能
会填补一些额外像素,亦即存储像素数据的宽度不一定是W,往往填补为4或8的倍数,因为这样一些多
媒体处理芯片可以更高效的处理图像。
图像的宽高分别由cols
、rows
给出,行像素个数由cols*channels()
给出,实际行的字节数由step[0]
给出。对于有额外填补的行数据,cols!= step[0]/elemSize()
,反之,cols==step[0]/elemSize()
。
我们可以用成员函数isContinuous()
判断图像是否对行进行了填补,对于没有进行填补的图像,我们视其
像素数据为一个长为WxHxchannels()
的一维数组,加快循环速度。 - 行首地址。
Mat的成员函数ptr(int j)
返回第j
行的首地址。 - 如果仔细阅读过Lecture 2 opencv2系列之初识Mat,对于遍历
Mat
,自然想到用data+step+elemSize()
来
实现,这也是基于指针的方法。
核心循环代码为:
int i,j; uchar *p; for (i = 0; i < nRows; i++) { p = src.<uchar>data + i * src.step[0]; for (j = 2; j < nCols; j += 3) { cout<<int(p[j*src.elemSize1()])<<" ";//本例中,src.elemSize1()=1;故可简写为p[j]。 } }
本质上是因为src.ptr(i) == src.data + i * src.step[0]
。
在《OpenCV2 计算机视觉编程手册》一书中,Laganiere不建议用这种方法,原因是:容易出错,并且不适用于带“感兴趣
区域”的图像。
参考文献
- The OpenCV Reference Manual Release 2.4.9.0。
- The OpenCV Tutorials Release 2.4.9.0。
- 加拿大, Laganiere, R., & 张静. OpenCV2 计算机视觉编程手册.
0 0
- Lecture 3 opencv2系列之遍历Mat
- Lecture 2 opencv2系列之初识Mat
- Lecture 1 opencv2系列之读取图像
- OpenCV2之Mat简介
- opencv2系列图像的遍历
- OpenCV2:Mat
- OpenCV2:Mat
- OpenCV2:Mat
- OpenCV2:Mat
- OpenCV2:Mat
- OpenCV2:Mat
- 学习OpenCV2——Mat之数据结构
- courseras NN_for_ml系列(lecture 3)
- 学习OpenCV2——Mat之通道的理解
- OpenCV2入门——core组件之Mat详解
- opencv2 Mat详解
- opencv2-mat的特点
- opencv2:Mat基础 转
- Lecture 2 opencv2系列之初识Mat
- Emacs中c/c++环境配置时出现问题 Debugger entered--Lisp error: (error "not support.")
- 安卓andbase框架源码解读( 一)
- MFC绘制坐标刻度和自定义线条以及带有箭头的直线
- shared jedis 在spring中的配置
- Lecture 3 opencv2系列之遍历Mat
- 2014秋C++第16周 项目 指针和数组、函数
- cocos2d-x-3.2塔防游戏开发1:背景,地图,obj,产生移动NPC的实现
- cocos2d-x编译Andorid报错make: *** No rule to make target
- 日语学习之沪江N3基础 20141207
- C语言程序编译的内存分配
- 循环赛日程表
- 安卓开发问题记录
- DumpEnvStrings.cpp(获取环境变量)