欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV计算机视觉编程记录(06)---------减色方法进行测试,比较其运行时间。

程序员文章站 2024-03-25 11:07:52
...

对以下减色方法进行测试,比较其运行时间。

方法1:使用整数除法

方法2:使用取模运算符方法

方法3:使用位运算符方法

方法4:使用整数除法和迭代器方法

方法5:使用整数除法和at方法

要求:

1、为每一种方法封装1个函数

2、不要求输出图像,但要输出每种方法的处理时间

源码:

#include<opencv2\highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
void colorReduce(cv::Mat image);
void getMo(Mat image);
void weiMeth(Mat image,int n=6){
	uchar div=pow(2,n);
	uchar div2=div>>1;
	uchar mask = uchar(0xFF) << n; 
	int nr=image.rows;
	int nc = image.cols * image.channels();
	for (int j = 0; j < nr; j++) { // 遍历每一行
		// 取得行j的地址
		uchar* data = image.ptr<uchar>(j);
		// 遍历当前行每一个元素
		for (int i = 0; i < nc; i++) {
			// 处理每个元素---------------------
			*data &= mask;    		// 掩码,将后n位设为0
			*data++ += div2;
		} 
	}
}

void colorReduce2(cv::Mat image, int div = 64) {
	// 在初始位置获得迭代器
	cv::MatIterator_<cv::Vec3b> it =
		image.begin<cv::Vec3b>();
	// 获得结束位置
	cv::MatIterator_<cv::Vec3b> itend =
		image.end<cv::Vec3b>();

	// 遍历所有像素
	for (; it != itend; ++it) { 
		// 处理每个像素-------------------------
		(*it)[0] = cv::saturate_cast<uchar>(
			(*it)[0] / div * div + div / 2);
		(*it)[1] = cv::saturate_cast<uchar>(
			(*it)[1] / div * div + div / 2);
		(*it)[2] = cv::saturate_cast<uchar>(
			(*it)[2] / div * div + div / 2);		
		// 像素处理结束-------------------------
	}
}

void colorReduce3(Mat image,int div=64){
	int nr=image.rows;
	int nc=image.cols;
	for(int j=0;j<nr;j++){
		for(int i=0;i<nc;i++){
		image.at<Vec3b>(j,i)[0]=saturate_cast<uchar>(
			image.at<Vec3b>(j,i)[0]/div*div+div/2);
		image.at<Vec3b>(j,i)[1]=saturate_cast<uchar>(
			image.at<Vec3b>(j,i)[1]/div*div+div/2);
		image.at<Vec3b>(j,i)[2]=saturate_cast<uchar>(
			image.at<Vec3b>(j,i)[2]/div*div+div/2);
		}
	}
}
int main()
{
	Mat image=imread("原图.png");
	//imshow("原图",image);
	if(image.empty())
	{
		cout<<"empty image";
		getchar();
		return 0;
	}

	const int64 start = getTickCount();
	colorReduce(image);
	double duration = (getTickCount()-start) / getTickFrequency();
	cout<<"1.整除法时间为:"<<duration<<"s"<<endl;

	//imshow("整除法",image);
	
	//const int64 start = getTickCount();
	getMo(image);
	duration = (getTickCount()-start) / getTickFrequency();
	cout<<"2.取模运算法时间为:"<<duration<<"s"<<endl;
	//imshow("取模运算符",image);

	//const int64 start = getTickCount();
	weiMeth(image);
	duration = (getTickCount()-start) / getTickFrequency();
	cout<<"3.位运算时间为:"<<duration<<"s"<<endl;
	//imshow("位运算符",image);

	//const int64 start = getTickCount();
	colorReduce2(image);
	duration = (getTickCount()-start) / getTickFrequency();
	cout<<"4.迭代器时间为:"<<duration<<"s"<<endl;
	//imshow("迭代器",image);

	//const int64 start = getTickCount();
	colorReduce3(image);
	duration = (getTickCount()-start) / getTickFrequency();
	cout<<"5.at时间为:"<<duration<<"s"<<endl;
	//imshow("at",image);

	waitKey();
	




	return 0;
}

void colorReduce(cv::Mat image) {
	int div = 64;
	int nr = image.rows; // 行数
	// 每行的元素数量(注意不是像素数量)
	int nc = image.cols * image.channels();
	for (int j = 0; j < nr; j++) { // 遍历每一行
		// 取得行j的地址
		uchar* data = image.ptr<uchar>(j);
		// 遍历当前行每一个元素
		for (int i = 0; i < nc; i++) {
			// 处理每个元素---------------------
			data[i] = cv::saturate_cast<uchar>(
				data[i] / div * div + div / 2);
			// 元素处理结束---------------------
		} // 一行结束
	}
}

void getMo(Mat image){
	int div = 64;
	int nr = image.rows; // 行数
	// 每行的元素数量(注意不是像素数量)
	int nc = image.cols * image.channels();
	for (int j = 0; j < nr; j++) { // 遍历每一行
		// 取得行j的地址
		uchar* data = image.ptr<uchar>(j);
		// 遍历当前行每一个元素
		for (int i = 0; i < nc; i++) {
			// 处理每个元素---------------------
			data[i] = cv::saturate_cast<uchar>(data[i] - data[i] % div + div / 2);
		}
	}
}