gpt4 book ai didi

c++ - 访问图像像素; MatIterator_<> 和 Mat::at 运算符的比较

转载 作者:行者123 更新时间:2023-11-28 05:23:20 26 4
gpt4 key购买 nike

我正在尝试比较 OpenCV 3.0 版中扫描图像像素以获得灰度图像的运行时间。我已经阅读了 OpenCV 文档 how_to_scan_images

我明白 cv::convertTo由于各种优化,将是最快的。我也明白 cpointer样式方法将是第二好的。然而,我对 MatIterator 之间的区别感到惊讶。 (方法 3)和 Mat::at运算符(方法 2)。文档 how_to_scan_images提到 MatIterator应该比 Mat::at<> 相对更快运算符(operator),但我收到的结果不同。我在这里错过了什么吗?这个结果是预期的吗?在算法开发的初始阶段,我想使用 MatIterator,因为它与 STL 迭代器相似,并且通常被认为是一种更安全的方法。

对我做错了什么有什么想法吗?我在 Ubuntu 上使用 OpenCV 3.0。对于多次运行,下面显示的输出在 +- 0.5 毫秒内大致一致。

在下面的代码中,我有效地计算了 ( newImage = alpha*oldImage +beta) 并比较了以下方法的性能

方法一:使用cv:: convertTo , 以毫秒为单位的时间 = 0.709923

方法二:使用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 convertTo
Mat 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 point
Mat 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 end
Mat 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;

}

最佳答案

在我自己挖掘之后,这是我的结论:基于性能的图像扫描方法比较(从最高到最低)

  1. 尽可能使用库函数。
  2. 首选 C 指针以加快扫描速度(可以使用 img.data() 获得几毫秒的增益,但要小心!)
  3. img.at<> 次之
  4. MatIterator 是最慢的。

只有在 Release模式下,“Mat::at”才比“MatIterator”快。 MatIterator 通过额外检查带来安全系数。但是,在 Debug模式下,“MatIterator”比“Mat::at”运算符更快

关于c++ - 访问图像像素; MatIterator_<> 和 Mat::at 运算符的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41033135/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com