opencv图像像素操作方法
2017-01-08 19:29
246 查看
图像容器Mat
Mat和Matlab里的数组格式有点像,但一般是二维向量,如果是灰度图,一般存放<uchar>类型;如果是RGB彩色图,存放<Vec3b>类型。单通道灰度图数据存放格式:
![](http://my.csdn.net/uploads/201207/22/1342908429_6672.png)
多通道的图像中,每列并列存放通道数量的子列,如RGB三通道彩色图:
![](http://my.csdn.net/uploads/201207/22/1342908517_7536.png)
有一点需要注意:图像的通道顺序是:BGR。通常情况内存足够大的话图像的每一行是连续存放的,也就是在内存上图像的所有数据存放成一行,这中情况在访问时可以提供很大方便。
好了,下面总结一下常见的访问图像像素的三种方法:使用at动态地址计算方式,使用iterator迭代器方式,使用ptr指针。先附代码:
#include <iostream> #include<core/core.hpp> #include<highgui/highgui.hpp> using namespace cv; using namespace std; void colorReduceAt(Mat& srcImage, Mat& dstImageAt, int div); void colorReduceIterator(Mat& srcImage, Mat& dstImageIterator, int div); void colorReducePtr(Mat& srcImage, Mat& dstImagePtr, int div); int main() { Mat image=imread("e:\\kobe.jpg"); Mat mv[3]; split(image,mv); if(!image.data) { cout<<"you idiot!where did you hide kobe!"<<endl; system("pause"); return -1; } //声明处理后图像变量 Mat dstImageAt, dstImageIterator, dstImagePtr; dstImageAt = image.clone(); dstImageIterator = image.clone(); dstImagePtr = image.clone(); int div = 4; //声明时间变量 double timeAt, timeIterator, timePtr; timeAt = static_cast<double>(getTickCount()); colorReduceAt(image, dstImageAt, div); timeAt = ((double)getTickCount() - timeAt) / getTickFrequency(); namedWindow("dstImageAt",CV_WINDOW_NORMAL); imshow("dstImageAt",dstImageAt); cout << "使用at()动态地址计算耗时:" << timeAt << endl << endl; timeIterator = static_cast<double>(getTickCount()); colorReduceIterator(image, dstImageIterator, div); timeIterator = ((double)getTickCount() - timeIterator) / getTickFrequency(); namedWindow("dstImageIterator",CV_WINDOW_NORMAL); imshow("dstImageIterator",dstImageIterator); cout << "使用iterator迭代器耗时:" << timeIterator << endl << endl; timePtr = static_cast<double>(getTickCount()); colorReducePtr(image, dstImagePtr, div); timePtr = ((double)getTickCount() - timePtr) / getTickFrequency(); namedWindow("dstImagePtr",CV_WINDOW_NORMAL); imshow("dstImagePtr",dstImagePtr); cout << "使用ptr指针耗时:" << timePtr << endl; //等待按键 waitKey(); return 0; } //使用at动态地址计算方式 void colorReduceAt(Mat& srcImage, Mat& dstImageAt, int div) { int rowNumber = dstImageAt.rows; //获取图像行数 int colNumber = dstImageAt.cols; //获取图像列数 //对每个像素进行处理 for(int i = 0; i < rowNumber; i++) { for(int j = 0; j < colNumber; j++) { dstImageAt.at<Vec3b>(i,j)[0] = dstImageAt.at<Vec3b>(i,j)[0]/div*div; //B通道 dstImageAt.at<Vec3b>(i,j)[1] = dstImageAt.at<Vec3b>(i,j)[1]/div*div; //G通道 dstImageAt.at<Vec3b>(i,j)[2] = dstImageAt.at<Vec3b>(i,j)[2]/div*div; //R通道 } } } //使用iterator迭代器方式 void colorReduceIterator(Mat& srcImage, Mat& dstImageIterator, int div) { MatIterator_<Vec3b> imageIt = dstImageIterator.begin<Vec3b>(); //获取迭代器初始位置 MatIterator_<Vec3b> imageEnd = dstImageIterator.end<Vec3b>(); //获取迭代器结束位置 //对每个像素进行处理 for(;imageIt != imageEnd; imageIt++) { (*imageIt)[0] = (*imageIt)[0]/div*div; //B通道 (*imageIt)[1] = (*imageIt)[1]/div*div; //G通道 (*imageIt)[2] = (*imageIt)[2]/div*div; //R通道 } } //使用ptr指针 void colorReducePtr(Mat& srcImage, Mat& dstImagePtr, int div) { int rowNumber = dstImagePtr.rows; //获取图像矩阵行数 int colNumber = dstImagePtr.cols*dstImagePtr.channels(); //三通道图像矩阵列树=图像列数x通道数 for(int i = 0; i < rowNumber; i++) { uchar* pixelPtr = dstImagePtr.ptr<uchar>(i); //获取矩阵每行首地址指针 for(int j = 0; j < colNumber; j++) pixelPtr[j] = pixelPtr[j] / div * div; } }运行结果如下:
并且发现,使用ptr方式访问像素用时最少。
参考:
https://yq.aliyun.com/articles/9300 http://www.cnblogs.com/zjgtan/archive/2013/04/06/3002962.html http://blog.csdn.net/keith_bb/article/details/53071133
后来新发现一篇比较全的博文介绍:http://blog.csdn.net/xiaowei_cqu/article/details/19839019
相关文章推荐
- OpenCV中用于读取图像像素点的值
- OpenCV访问图像像素, 数组元素等方法收集
- opencv2-遍历图像像素的14种方法
- 【OpenCV】访问图像中每个像素的值
- opencv技术访问图像中的像素
- 【OpenCV】访问Mat图像中每个像素的值
- opencv像素基本操作及图像遍历at
- opencv读取图像,并获得像素值,图像高度和宽度不是4的倍数
- opencv获得图像某点像素值等
- opencv学习(5)图像像素的访问、颜色通道的分离和融合
- opencv学习(三)之图像像素遍历(颜色空间缩减、查找表)
- OpenCv学习笔记(六)----图像空间缩减,OpenCv中的计时函数和OpenCv中操作图像单个像素点的方法
- opencv学习(十)颜色缩减 // 查表 // 计时 // 访问像素的三个方法(指针/STL迭代器(待详细了解)/动态地址)//历遍图像的14种方法
- OpenCv 如何对图像的像素进行操作(注意多通道图像在内存中的存储方式!!)
- Python-OpenCV 处理图像(二)(三):滤镜和图像运算 图像像素点操作
- 快速对图像的像素进行操作 opencv 实战
- 【OpenCV】访问Mat图像中每个像素的值
- OpenCv访问图像像素
- OpenCV Learning: 图像像素Mat操作方法2
- OpenCV访问Mat图像中每个像素的值