我正在尝试比较在OpenCV 3.0版中扫描图像像素以获取灰度图像的运行时间。我已经阅读过OpenCV文档how_to_scan_images我知道cv::convertTo会因为各种优化而最快。我也知道cpointer样式方法是第二好的方法。但是,我对MatIterator(method3)和Mat::at运算符(方法2)之间的差异感到惊讶。文档how_to_scan_images提到MatIterator应该比Mat::at<>运算符相对更快,但是我收到的结果却不同。我在这里想念什么吗?这是预期结果吗?在算法开发的初始阶段,我想使用MatIterator,因为它与STL迭代器相似,通常被认为是一种更安全的方法。关于我在做什么错的任何想法吗?我在Ubuntu上使用OpenCV 3.0。对于多个运行,下面显示的输出在+-0.5 ms内大致保持一致。在下面的代码中,我有效地计算了(newImage = alpha*oldImage +beta)并比较了以下方法的性能方法1:使用cv:: convertTo,以毫秒为单位的时间= 0.709923方法2:使用img.at<uchar>(row,col),以毫秒为单位的时间= 5.09625方法3:使用MatIterator_<uchar> it,以毫秒为单位的时间= 18.277方法4:cpointer uchar * p = img.ptr<uchar>(row),以毫秒为单位的时间= 3.49983方法5:cpointer uchar * src = img.data,以毫秒为单位的时间= 3.28267#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/core/utility.hpp>#include <iostream>#include <string>using namespace std;using namespace cv;int main(int argc, char ** argv){string imgname("baboon.jpg");if (argc>1) imgname = argv[1];Mat im = imread(imgname.c_str(), IMREAD_COLOR);if (im.empty()){ cout<<" Invalid image read, imgname =argv[1] = "<<imgname<<endl; return -1;}Mat img;cvtColor(im, img,COLOR_BGR2GRAY);// method 1: using convertToMat img1;double alpha =1, beta =50;double t = (double)(getTickCount());img.convertTo(img1, img.type(),alpha, beta);t = ((double)getTickCount() - t)/getTickFrequency();cout<<"Method 1: using convertTo, Time elasped in ms = "<<t*1000<<endl;namedWindow("img1", WINDOW_AUTOSIZE);imshow("img1", img1);// Method2: using img.at<>(row, col) index Mat img2 = Mat::zeros(img.size(), img.type());t = (double)(getTickCount()); for (int row=0; row<img.rows; row++){ for (int col =0; col<img.cols; col++) { img2.at<uchar>(row,col) = (saturate_cast<uchar>) (alpha*img.at<uchar> (row,col) + beta); }}t = ((double)getTickCount() - t)/getTickFrequency();cout<<"Method2: using img.at<uchar>(row,col), Time in ms = "<<t*1000<<endl;//Method3: using Matiterator for each image pointMat img3 = Mat::zeros(img.size(),img.type());t = (double)(getTickCount());MatIterator_<uchar> it, itDest, end; itDest= img3.begin<uchar>(); end =img.end<uchar>();for (it = img.begin<uchar>(); it!= end; it++,itDest++){ *itDest = (saturate_cast<uchar>)((*it)*alpha + beta);}t = ((double)getTickCount() - t)/getTickFrequency();cout<<"Method3: using MatIterator_<uchar> it, Time in ms = "<<t*1000<<endl;//Method4: using c-style pointer, char * p = img.ptr<uchar>(rowNum) Mat img4 = Mat::zeros(img.size(), img.type());t = (double)(getTickCount());for (int row =0; row<img.rows; row++){ uchar * srcPtr = img.ptr<uchar>(row); uchar * destPtr = img4.ptr<uchar>(row); for (int col =0; col<img.cols; col++) { destPtr[col] = (saturate_cast<uchar>) (alpha* srcPtr[col] + beta); }}t = ((double)getTickCount() - t)/getTickFrequency();cout<<"Method4: cpointer uchar * p = img.ptr<uchar>(row), Time in ms = "<<t*1000<<endl;// method 5: using the address given by img.data() and iterating untill the endMat img5 = Mat::zeros(img.size(), img.type());t = (double)(getTickCount());uchar * src = img.data;uchar * dest =img5.data;for (int i=0; i<img.rows*img.cols; i++) *(dest++) = (saturate_cast<uchar>)(alpha * (*(src++)) + beta);t = ((double)getTickCount() - t)/getTickFrequency();cout<<"Method5: cpointer uchar * src = img.data, Time in ms = "<<t*1000<<endl;return 0;} 最佳答案 在我自己挖掘之后,这里是我的结论:基于性能的图像扫描方法比较(从最高到最低)尽可能使用库函数。 首选C指针进行更快的扫描(一个人可以使用img.data()获得几毫秒的增益,但要小心!) img.at 是次佳的 MatIterator最快。 仅在 Release模式下'Mat::at'比'MatIterator'更快。 MatIterator通过额外的检查带来了安全系数。但是,在 Debug模式下,“MatIterator”比“Mat::at”运算符快
08-27 01:55