When you write an image-processing function, efficiency is often a concern(涉及). When you design your function, you will frequently need to check the computational efficiency of your code in order to detect(发现) any bottleneck(瓶颈) in your processing that might slow down(变慢) your program.
1.1 实现方法
为了衡量函数或代码段的运行时间,OpenCV有一个非常实用的函数,即cv::getTickCount(),该函数返回从最近一次电脑开机到当前的时钟周期数。如希望得到以秒为单位的代码运行时间,要使用另一个方法,即cv::getTickFrequency(),返回每秒的时钟周期数。
const int64 start = cv::getTickCount();
colorReduce(image);
// elapsed (经过的时间) time in seconds
double duration = (cv::getTickCount() - start) /
cv::getTickFrequency();
1.2 四种存取像素方式效率对比
查看.at、pointers、reshape及iterators四种遍历图像方式所消耗时间
//Test running time,edited by yunfung #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; void colorReduce1(Mat& image, int div = 64) { for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { image.at<Vec3b>(i, j)[0] = image.at<Vec3b>(i, j)[0] / div*div + div / 2; image.at<Vec3b>(i, j)[1] = image.at<Vec3b>(i, j)[1] / div*div + div / 2; image.at<Vec3b>(i, j)[2] = image.at<Vec3b>(i, j)[2] / div*div + div / 2; } } } void colorReduce2(cv::Mat image, int div = 64) { int nl = image.rows; int nc = image.cols * image.channels(); for (int j = 0; j < nl; j++) { uchar* data = image.ptr<uchar>(j); for (int i = 0; i < nc; i++) { data[i] = data[i] / div*div + div / 2; } } } void colorReduce3(cv::Mat &image, int div = 64) { if (image.isContinuous()){ image.reshape(1, 1); } int nl = image.rows; int nc = image.cols * image.channels(); for (int j = 0; j < nl; j++) { uchar* data = image.ptr<uchar>(j); for (int i = 0; i < nc; i++) { data[i] = data[i] / div*div + div / 2; } } } void colorReduce4(cv::Mat &image, int div = 64) { cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>(); cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>(); for (; it != itend; ++it) { (*it)[0] = (*it)[0] / div * div + div / 2; (*it)[1] = (*it)[1] / div * div + div / 2; (*it)[2] = (*it)[2] / div * div + div / 2; } } void calrunTime(int v, Mat&image) { double duration; duration = static_cast<double>(getTickCount()); //强制转化为double for (int i = 0; i < 10; i++) { switch (v) { case 1: colorReduce1(image); //at break; case 2: colorReduce2(image); //pointers break; case 3: colorReduce3(image); //reshape(continuous) break; case 4: colorReduce4(image); //iterators break; default: break; } } duration = static_cast<double>(getTickCount()) - duration; duration /= getTickFrequency(); duration *= (1000/10); //average cout << "duration" << v << " : " << duration << "mS"<< endl; } int main() { Mat image = imread("test.jpg"); Mat imageClone = image.clone(); cout << "yunfung_opencv_learn_test:" <<"\n\n"; calrunTime(1, image); image = imread("test.jpg"); imageClone = image.clone(); calrunTime(2, image); image = imread("test.jpg"); imageClone = image.clone(); calrunTime(3, image); image = imread("test.jpg"); imageClone = image.clone(); calrunTime(4, image); namedWindow("Image Result"); imshow("Image Result", imageClone); waitKey(); return 0; }
可见用at的方式读取像素效率最低,用迭代器速度也比较慢,效率最高的方式还是使用指针读取。
时间: 2024-10-15 04:51:10