本文目的:
在opencv中有三种方式可以读写图像的像素,分别为:指针读写、迭代器读写、动态地址计算读写。虽然三种方式都可以完成同样的目的,但是运行速度却有快有慢,尤其是在实现一些复杂算法的时候,效率非常关键,下面就来比较一下这三种方式的运行速度。
实现代码:
代码工程下载地址:http://download.csdn.net/detail/u013752202/9230389
下面代码实现的功能:分别使用三种方法实现图像像素的读写,并改变图像的亮度和对比度,然后对三种方法的运行速度进行比较。
#include <QtCore/QCoreApplication>
#include <opencv2/opencv.hpp>
using namespace cv;
/***********************************
*通过.ptr指针访问像素
************************************/
void lightAdjustPTR(Mat &image,int contrast,int bright)
{
for(int i=0;i<image.rows;i++){
for(int j=0;j<image.cols;j++){
for(int ch=0;ch<image.channels();ch++){
uchar curVal=image.ptr<Vec3b>(i)[j][ch];
image.ptr<Vec3b>(i)[j][ch]=saturate_cast<uchar>(0.01*contrast*curVal+bright);
}
}
}
}
/***********************************
*通过.at动态地址访问像素
************************************/
void lightAdjustAT(Mat &image,int contrast,int bright)
{
for(int i=0;i<image.rows;i++){
for(int j=0;j<image.cols;j++){
for(int ch=0;ch<image.channels();ch++){
uchar curVal=image.at<Vec3b>(i,j)[ch];
image.at<Vec3b>(i,j)[ch]=saturate_cast<uchar>(0.01*contrast*curVal+bright);
}
}
}
}
/***********************************
*通过it迭代器访问像素
************************************/
void lightAdjustIT(Mat &image,int contrast,int bright)
{
MatIterator_<Vec3b> it=image.begin<Vec3b>();
MatIterator_<Vec3b> itend=image.end<Vec3b>();
while(it!=itend){
for(int ch=0;ch<image.channels();ch++){
uchar curVal=(*it)[ch];
(*it)[ch]=saturate_cast<uchar>(0.01*contrast*curVal+bright);
}
it++;
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Mat srcPTR=imread("1.jpg");
Mat srcAT=srcPTR.clone();
Mat srcIT=srcPTR.clone();
imshow("ShuiTan",srcPTR);
//通过.ptr指针访问
double timePTRS=static_cast<double>(getTickCount());//获取当前心跳数
lightAdjustPTR(srcPTR,130,100);
double timePTRT=((double)getTickCount()-timePTRS)/getTickFrequency();//求运行时间
cout<<".ptr spent: "<<timePTRT<<"s"<<endl;//打印时间
//通过.at动态地址访问
double timeATS=static_cast<double>(getTickCount());//获取当前心跳数
lightAdjustAT(srcAT,130,100);
double timeATT=((double)getTickCount()-timeATS)/getTickFrequency();//求运行时间
cout<<".at spent: "<<timeATT<<"s"<<endl;//打印时间
//通过it迭代器访问
double timeITS=static_cast<double>(getTickCount());//获取当前心跳数
lightAdjustIT(srcIT,130,100);
double timeITT=((double)getTickCount()-timeITS)/getTickFrequency();//求运行时间
cout<<"*it spent: "<<timeITT<<"s"<<endl;//打印时间
imshow("ShuiTanPTR",srcPTR);
imshow("ShuiTanAT",srcAT);
imshow("ShuiTanIT",srcIT);
waitKey(0);
return a.exec();
}
运行结果:
从下面的运行结果可以看出,三种方法的运行速度从快到慢依次是:指针读写 < 迭代器读写 < 动态地址计算,指针读写的方式是最快的,所以在算法中尽量使用指针读写的方式来访问图像像素或矩阵元素。