OpenCV学习笔记二:操作像素
2017-03-08 19:26
232 查看
一、存取像素值
Mat的成员函数at(int x,int y)用于存取第x行,第y例的像素值。存取像素值时必须知道图像的数据类型,因此at函数实现为模板函数,调用时需指定类型,例如对单通道图和彩色图:
//注:指定的数据类型一定要与图像的实际类型吻合 //单通道 image.at< uchar >(x,y) = 255; //双通道 image.at<Vec3b>(x,y)[channel] = 255;
如果嫌调用函数时指定模板参数麻烦,可以使用Mat的模板子类Mat_,其重载了()操作符,可以直接存取像素值,像这样:
Mat_<uchar> image; image(x,y) = 255;
二、图像遍历
遍历图像前最好先了解Mat的一些成员的意义
data:Mat中的一个指针,指向存放图像数据的内存channels():图像的通道数,比如灰度图channels = 1
type():矩阵的数据类型,比如CV_8U,CV_8UC3等
depth():图像的深度,可以理解为矩阵中元素的一个通道的数据类型,这个值和type是相关的。例如 type为 CV_16SC2,一个2通道的16位的有符号整数。那么,depth则是CV_16S。Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;
rows:图像矩阵的行数
cols:图像矩阵的列数
step:每行的字节数
elemSize:每个像素的大小,对于short型三通道矩阵(CV_16SC3),elemSize = 6
ptr(int x):返回第x行的首地址
1、通过指针遍历图像
对于三通道的彩色图像,内存中前三个字节对左上角像素的三个通道值,接下来的三个字节对应第一行第二个像素(OpenCV采用BGR通道顺序)。因此可以以如下方式遍历图像:
int nl = image.rows;//行数 int nc = image.cols * image.channels(); for(int j=0;j<nl;j++) { //得到第j行首地址 uchar *data = image.ptr<uchar>(j); for(int i=0;i<nc;i++) { data[i] = 255;//处理每一个通道值 } }
2使用迭代器遍历图像
OpenCV为Mat提供了与STL迭代器兼容的迭代器。一个Mat实例的迭代器可以通过创建MatIterator_实例来得到。类似于Mat_,下划线表明其是一个模板类。
MatIterator_<Vec3b> it; MatConstIterator_<Vec3b> itc; //也可以使用定义在Mat_内部的迭代器类型 Mat_<Vec3b>::iterator it; Mat_<Vec3b>::const_iterator itc;
然后,可以像这样遍历图像:
Mat_<Vec3b>::iterator it = image.begin<Vec3b>(); Mat_<Vec3b>::iterator itend = image.end<Vec3b>(); //遍历 for(;it != itend;++it) { (*it)[channel] = 255;//处理每个channel }
*图像遍历的一些建议
图像原地处理更快指针处理更快,但迭代器更简单
at方法适合随机存取,不适合遍历
如果要对一个像素进行N种运算,那么在一次循环内完成要比分别用N个循环,每次循环只作一种运算高效得多
图像行与行之间往往存储是不连续的,但是有些图像可以是连续的,Mat提供了一个检测图像是否连续的函数isContinuous()。当图像连通时,我们就可以把图像完全展开,看成是一行。1中的两重循环可以简化为一层。
待补充
3、简单的图像运算
图像可以以不同的方式组合。因为它们只是一般的矩阵,所以它们可以做各种矩阵运算:加、减、乘、除、转置等。
以图像相加为例,当我们需要将一些图像叠加在一起时,就需要用到图像加法。通过调用add,更准确地说是addWeighted来完成。
addWeighted(image1,0.7,image2,0.9,0,result); //OpenCV重载了大多数算术操作符,因此上式也等价于 //result = 0.7*image1 + 0.9*image2 + 0;
图像加法只能用于两张图像大小一致的情况,对于大小不一致的情况,则需要定义感兴趣区域(ROI)。
//定义ROI为image1的大小,这样就可以用图像加法了 Mat imageROI = image(Rect(100,100,image1.cols,image1.rows); imageROI = addWeighted(imageROI,0。5,image1,0.7,0,imageROI); //imageROI = 0.5*imageROI + 0.7 * image1;
相关文章推荐
- OpenCv学习笔记(六)----图像空间缩减,OpenCv中的计时函数和OpenCv中操作图像单个像素点的方法
- 【opencv学习笔记.1】操作像素画圆
- Opencv学习笔记之二:操作像素
- 图像的像素点操作【OpenCV学习笔记3】
- 我的OpenCV学习笔记(三):利用操作像素完成简单的图像处理:加入椒盐噪声、图像翻转、改变对比度、图像锐化
- OpenCV学习笔记 存取像素值操作汇总core
- OpenCV学习笔记二-操作像素
- OpenCV学习笔记(四十一)——再看基础数据结构core OpenCV学习笔记(四十二)——Mat数据操作之普通青年、文艺青年、暴力青年 OpenCV学习笔记(四十三)——存取像素值操作汇总co
- opencv学习笔记 二 操作像素
- openCV学习笔记(四):图像遍历和像素操作
- 【OpenCV学习笔记 005】 操作像素
- OpenCV学习笔记——存取像素值操作汇总core
- c# opencvsharp学习笔记(3)兴趣区域ROI,图像叠加,操作像素点
- 【OpenCV学习笔记】三、操作像素
- 我的OpenCV学习笔记(二):操作每个像素
- 【OpenCV学习笔记】一.操作像素
- OpenCV学习笔记(1)——操作像素
- opencv2学习笔记4-操作图像(图像锐化-拉普拉斯算子)
- OpenCV 2 学习笔记(23): 开操作与闭操作
- opencv2学习笔记2-操作图像(椒盐噪声)