Opencv中三种操作像素的方法
来源:互联网 发布:电脑挂机赚钱软件 编辑:程序博客网 时间:2024/06/04 23:23
测试环境:opencv3.1.0 + Visual Studio 2015 + win7 64位
opencv中有3中方法可以访问/修改图像的像素值,分别为:
1. 指针访问
2. 迭代器iterator
3. 动态地址计算
测试程序如下:
#include "opencv2/opencv.hpp"#include "iostream"using namespace std;using namespace cv;int main(){//原始图像初始化Mat image(240, 320, CV_8UC3, Scalar(0, 0, 0));imshow("原始图像", image);//------------------指针操作-------------------------double start = static_cast<double>(getTickCount());int rowNumber = image.rows;//行数int colNumber = image.cols * image.channels();//每一行元素个数 = 列数 x 通道数for (int i = 0; i < rowNumber; i++)//行循环{uchar* data = image.ptr<uchar>(i);//获取第i行的首地址for (int j = 0; j < colNumber; j++)//列循环{//开始处理data[j] = 255;}}double end = static_cast<double>(getTickCount());double time = (end - start) / getTickFrequency();cout << "指针操作运行时间为:" << time << "秒" << endl;imshow("指针操作", image);//---------------------------------------------------//-----------------迭代器操作------------------------start = static_cast<double>(getTickCount());Mat_<Vec3b>::iterator it = image.begin<Vec3b>();//初始位置的迭代器Mat_<Vec3b>::iterator itend = image.end<Vec3b>();//终止位置的迭代器for (; it != itend; it++){//处理BGR三个通道(*it)[0] = 255;//B(*it)[1] = 255;//G(*it)[2] = 0;//R}end = static_cast<double>(getTickCount());time = (end - start) / getTickFrequency();//计算时间cout << "迭代器操作运行时间为:" << time << "秒" << endl;imshow("迭代器操作", image);//---------------------------------------------------//----------------动态地址计算-----------------------start = static_cast<double>(getTickCount());rowNumber = image.rows;colNumber = image.cols;for (int i = 0; i < rowNumber; i++)for (int j = 0; j < colNumber; j++){//处理BGR三个通道image.at<Vec3b>(i, j)[0] = 0;//Bimage.at<Vec3b>(i, j)[1] = 255;//Gimage.at<Vec3b>(i, j)[2] = 0;//R}end = static_cast<double>(getTickCount());time = (end - start) / getTickFrequency();//计算时间cout << "动态地址操作运行时间为:" << time << "秒" << endl;imshow("动态地址操作", image);//---------------------------------------------------cvWaitKey(0);return 1;}
运行结果如下:
Debug模式下运行时间如下:
Release模式下运行时间如下:
可以看到指针操作在Debug模式和Release模式下均是最快的,动态地址和迭代器操作稍微慢点。
一些说明:
1. RGB颜色模型的矩阵如下(opencv中通道顺序为BGR):
因此,指针操作的时候,每行的元素个数为:列数x通道数。
Mat类提供了ptr函数可以得到图像任意行的首地址。
2. 在迭代法中,我们所需要做的仅仅是获得图像矩阵的begin和end,然后迭代从begin到end。将*操作符添加在迭代指针前,即可以访问当前指向的内容。相比于指针直接访问可能出现越界问题,迭代器绝对是非常安全的方法。
3. 成员函数at(int y, int x)可以用来存取图像元素,但是必须在编译期知道图像的数据类型。对于彩色图像,每个像素由三个部分构成:蓝色通道、绿色通道和红色通道(BGR)。因此,对于一个包含彩色图像的Mat,会返回一个由三个8位数组成的向量。Opencv将此类型的向量定义为Vec3b,即由三个unsigned char组成的向量。这也解释了为什么存取彩色图像像素的代码可以写出如下形式
image.at<Vec3b>(j, i)[channel] = value;
另外:
而对于单通道的灰度图像就简单很多了:
image.at<uchar>(i,j);
这里要注意at中(i,j)的顺序表示的是第i行第j列,跟Point(i,j)和Rect(i,j)中表示第j行第i列是相反的,如果把这个搞混了,很容易导致内存异常,还不容易发现错误。
补充说明一下:OpenCV中坐标体系中的零点坐标定义为图片的左上角,X轴为图像矩形的上面那条水平线,从左往右;Y轴为图像矩形左边的那条垂直线,从上往下。在Point(x,y)和Rect(x,y)中,第一个参数x代表的是元素所在图像的列数,第二个参数y代表的是元素所在图像的行数,而在at(x,y)中是相反的。
参考文献
OpenCV3编程入门
OpenCV坐标系与操作像素的四种方法
- Opencv中三种操作像素的方法
- OpenCV坐标系与操作像素的四种方法
- OpenCV坐标系与操作像素的四种方法
- OpenCV中坐标系与操作像素的四种方法
- OpenCV坐标系与操作像素的四种方法
- OpenCV对像素的操作
- OpenCV对像素的操作
- Opencv中Mat对于像素的操作
- 初学opencv小记-对像素的操作
- 【OpenCV】Mat对于像素的操作
- opencv关于像素操作的汇总2
- OpenCV-005:图片的基本像素操作
- opencv 操作像素
- opencv Mat 像素操作
- OpenCV操作像素
- opencv mat像素操作
- opencv操作每个像素
- openCV 操作像素矩阵
- nat123的自启动
- HHU 1015 圆上的点点点点点点点点点点点点点点(浮点数精度处理)
- 简单工厂模式、工厂模式、抽象工厂模式
- 优雅编程之这样重构代码,你就“正常”了(十八)
- 缓存LruCache的使用步骤
- Opencv中三种操作像素的方法
- PAT 1027. Colors in Mars (20)(转化为13进制)
- JavaScript实现拖拽预览,AJAX小文件上传
- HTML基础复习笔记
- Linux device tree设备树
- find ./ -name "hardware.*" 查找文件
- 优雅编程之这样重构函数,你就“正常”了(十九)
- NOI题解(1.7编程基础之字符串)(待补全)
- Win 10 无法打开内核设备“\\.\Global\vmx86”