opencv中遍历图像是个问题,因为opencv有时候是要求速度的,特别是目标跟踪的时候。在这里大概可以分。。。。。。就4种吧。
测试图片是100×100的rgb图像,从srcImg图像拷贝到dstImg图像,使用了三种方法,iterator、at、指针ptr方法。依次速度加快。
我的机器上iterator方法跑了个50+ms,at方法跑了3ms,二维方法跑了0ms,一维数组方法也是0ms,大家看相对就行了,以后想快点的话,iterator就不要考虑了,直接用指针方法就行了。
其中二维数组和一维数组方法分别是对每一行看作一个一维数组,和对整幅图像看作一个一维数组。
但是注意一维数组方法需要图像是iscontinuous()的,每次遍历之前都需要判断是不是连续的,如果一定想要用一维数组方法,可以将图像使用create方法创建,这样就可以保证图像是iscontinuous()的了。
下边是源码测试。
#include <opencv2/opencv.hpp>
#include <iostream>
#include <ctime>
using namespace cv;
using namespace std;
int main()
{
Mat srcImg=imread("F:\\0.jpg");
Mat dstImg(srcImg.size(),srcImg.type());
int start=clock();
for(int i=0;i<srcImg.rows;i++)
{
for(int j=0;j<srcImg.cols;j++)
{
dstImg.at<Vec3b>(i,j)=srcImg.at<Vec3b>(i,j);
}
}
int end=clock();
cout<<"at 方法:"<<end-start<<endl;
imshow("dst",dstImg);
waitKey(0);
Mat ptrSrcImg=imread("F:\\0.jpg");
Mat ptrDstImg(ptrSrcImg.size(),ptrSrcImg.type());
int ptrStart=clock();
Vec3b* srcData;
Vec3b* dstData;
for(int i=0;i<ptrSrcImg.rows;i++)
{
srcData=ptrSrcImg.ptr<Vec3b>(i);
dstData=ptrDstImg.ptr<Vec3b>(i);
for(int j=0;j<ptrSrcImg.cols;j++)
{
dstData[j]=srcData[j];
}
}
int ptrEnd=clock();
cout<<"二维数组 方法:"<<ptrEnd-ptrStart<<endl;
imshow("ptrdstImg",ptrDstImg);
waitKey(0);
Mat iteSrcImg=imread("F:\\0.jpg");
Mat iteDstImg(iteSrcImg.size(),iteSrcImg.type());
int iteStart=clock();
MatIterator_<Vec3b> itSrc=iteSrcImg.begin<Vec3b>();
MatIterator_<Vec3b> itDst=iteDstImg.begin<Vec3b>();
for(;itSrc!=iteSrcImg.end<Vec3b>();itSrc++,itDst++)\
{
itDst[0]=itSrc[0];
itDst[1]=itSrc[1];
itDst[2]=itSrc[2];
}
int iteEnd=clock();
cout<<"iterator 方法: "<<iteEnd-iteStart<<endl;
imshow("iteDstImg",iteDstImg);
waitKey(0);
Mat secPtrSrcImg=imread("F:\\0.jpg");
Mat secPtrDstImg(secPtrSrcImg.size(),secPtrSrcImg.type());
int secPtrStart=clock();
if(secPtrSrcImg.isContinuous())
{
Vec3b* secDstData=secPtrDstImg.ptr<Vec3b>(0);
Vec3b* secSrcData=secPtrSrcImg.ptr<Vec3b>(0);
for(int i=0;i<secPtrDstImg.rows*secPtrDstImg.cols;i++)
{
secDstData[i]=secSrcData[i];
}
}
int secPtrEnd=clock();
cout<<"一维数组方法:"<<secPtrEnd-secPtrStart<<endl;
imshow("secPtrImg",secPtrDstImg);
waitKey(0);
return 0;
}