opencv学习之------编写高效的图像遍历循环

OpenCV有一个非常实用的函数,即cv::getTickCount(),可以用来测量一段代码的运行时间,该函数返回从最近一次电脑开机到当前的时钟周期数。如希望得到以秒为单位的代码运行时间,要使用另一个方法,即cv::getTickFrequency(),返回每秒的时钟周期数。

double duration;
duration = static_cast<double>(cv::getTickCount());  //强制转化为double
colorReduce(image); // 被测试的函数
duration = static_cast<double>(cv::getTickCount())-duration;
duration /= cv::getTickFrequency(); //运行时间,以ms为单位

四种存取像素方式效率对比

查看.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("8.jpg");
	imageClone = image.clone();
	calrunTime(2, image);
	image = imread("8.jpg");
	imageClone = image.clone();
	calrunTime(3, image);
	image = imread("8.jpg");
	imageClone = image.clone();
	calrunTime(4, image);

	namedWindow("Image Result");
	imshow("Image Result", imageClone);
	waitKey();
	return 0;
}

运行比较结果如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值