opencv之图像采样

opencv中提供了3个将浮点数转换为整数的方法;

cvRound()函数返回和参数最接近的整数值; 

cvFloor()返回不大于参数的最大整数值;

cvCeil()返回小于参数的最小整数值;

1. 最近邻插值

 关键点事找到缩放倍数,然后邻域向上取整完成坐标映射;

cv::Mat nNeighbourInterpolation(cv::Mat srcImage)
{
	CV_Assert(srcImage.data != NULL);

	int rows = srcImage.rows;
	int cols = srcImage.cols;

	//构建目标图像
	cv::Mat dstImage = cv::Mat(cv::Size(150,150), srcImage.type(), cv::Scalar::all(0));
	int dstRows = dstImage.rows;
	int dstCols = dstImage.cols;

	//坐标转换,求取缩放倍数
	float cx = (float)cols / dstCols;
	float ry = (float)rows / dstRows;

	//遍历图像,完成缩放操作
	for(int i = 0; i < dstCols; i++){
		int ix = cvFloor(i * cx);

		for(int j = 0; j < dstRows; j++){
			int jy = cvFloor(j * ry);

			//边界处理
			if(ix > cols -1)
				ix = cols - 1;
			if(jy > rows - 1)
				jy = rows - 1;

			//映射矩阵
			dstImage.at<cv::Vec3b>(j, i) = srcImage.at<Vec3b>(jy, ix);
		}
	}

	return dstImage;
}

2. 双线性插值 

 无

3. resize()函数实现图像大小变换

函数原型如下: 

/*
	实现图像尺寸大小变换功能;
	_src:源图像  		
	_dst:目的图像        
	dsize:输出图像的尺寸,若为0,尺寸将被计算为Size(round(fx*src.cols),round(fy*src.rows));
	inv_scale_x:水平缩放因子; 		
	inv_scale_y:垂直缩放因子; 
	interpolation:插值方法;
*/
void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
                 double inv_scale_x, double inv_scale_y, int interpolation )

提供了5中插值方法:最近邻,双线性,像素区域,立方插值,兰索斯插值;

void ResizeExample(cv::Mat srcImage)
{
	CV_Assert(srcImage.data != NULL);

	cv::Mat dstImage(256,256,CV_8UC3);

	//默认参数为双线性插值
	double tTime;
	tTime = (double)getTickCount();
	const int nTimes = 100;
	for(int i = 0 ;i < nTimes ; i++){
		resize(srcImage,dstImage,Size(dstImage.rows,dstImage.cols),0,0);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	std::cout << "test1 = " << tTime << endl;
	cv::imwrite("./lena_resize1.jpg", dstImage);

	//最近邻插值
	tTime = (double)getTickCount();
	for(int i = 0 ;i < nTimes ; i++){
		resize(srcImage,dstImage,Size(dstImage.rows,dstImage.cols),0,0,cv::INTER_NEAREST);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	std::cout << "test2 = " << tTime << endl;
	cv::imwrite("./lena_resize2.jpg", dstImage);	

	//像素区域插值
	tTime = (double)getTickCount();
	for(int i = 0 ;i < nTimes ; i++){
		resize(srcImage,dstImage,Size(dstImage.rows,dstImage.cols),0.5,0.5,cv::INTER_AREA);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	std::cout << "test3 = " << tTime << endl;
	cv::imwrite("./lena_resize3.jpg", dstImage);	

	//立方插值
	tTime = (double)getTickCount();
	for(int i = 0 ;i < nTimes ; i++){
		resize(srcImage,dstImage,Size(dstImage.rows,dstImage.cols),0.5,0.5,cv::INTER_CUBIC);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	std::cout << "test4 = " << tTime << endl;
	cv::imwrite("./lena_resize4.jpg", dstImage);

	//兰索斯插值
	tTime = (double)getTickCount();
	for(int i = 0 ;i < nTimes ; i++){
		resize(srcImage,dstImage,Size(dstImage.rows,dstImage.cols),0.5,0.5,cv::INTER_LANCZOS4);
	}
	tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
	tTime /= nTimes;
	std::cout << "test5 = " << tTime << endl;
	cv::imwrite("./lena_resize5.jpg", dstImage);	

	/*
		test1 = 0.076032
		test2 = 0.0625323
		test3 = 0.103261
		test4 = 1.16022
		test5 = 2.11283
	*/
}

4. 图像金字塔

向下采样采用的是高斯金字塔,向上重建技术采用拉普拉斯金字塔; 

 void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )

 void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )

int main()
{	
	cv::Mat srcImage = cv::imread("./lena.jpg");
	if(srcImage.empty()){
		std::cout << "imread failed" << endl;
		return -1;
	}

	//下采样
	cv::Mat dstImage;
	pyrDown(srcImage, dstImage, Size(srcImage.rows/2,srcImage.cols/2));

	//上采样,对下采样进行重构;
	cv::Mat buildImage;
	pyrUp(dstImage, buildImage, Size(dstImage.rows*2,dstImage.cols*2));

	//源图像与重构图像作差
	cv::Mat diffImage;
	cv::absdiff(srcImage, buildImage, diffImage);
	
	
	cv::imwrite("./lena_diff.jpg", diffImage);

	return  0;
}

            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天未及海宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值