双线性插值实现

#include <opencv2/imgproc/imgproc.hpp>  
#include <opencv2/core/core.hpp>        
#include <opencv2/highgui/highgui.hpp> 
#include <iostream> 
// 实现双线性插值图像缩放
cv::Mat BilinearInterpolation(cv::Mat srcImage)
{
	CV_Assert(srcImage.data != NULL);
	int srcRows = srcImage.rows;
	int srcCols = srcImage.cols;
	int srcStep = srcImage.step;
	// 构建目标图像
	cv::Mat dstImage = cv::Mat(
		cv::Size(640, 480), srcImage.type(),
		cv::Scalar::all(0));
	int dstRows = dstImage.rows;
	int dstCols = dstImage.cols;
	int dstStep = dstImage.step;
	// 数据定义及转换
	IplImage src = srcImage;
	IplImage dst = dstImage;
	std::cout << "srcCols:" << srcCols << " srcRows:" <<
		srcRows << "srcStep:" << srcStep << std::endl;
	std::cout << "dstCols:" << dstCols << " dstRows:" <<
		dstRows << "dstStep:" << dstStep << std::endl;
	// 坐标定义
	float srcX = 0, srcY = 0;
	float t1X = 0, t1Y = 0, t1Z = 0;
	float t2X = 0, t2Y = 0, t2Z = 0;
	for (int j = 0; j < dstRows - 1; j++)
	{
		for (int i = 0; i < dstCols - 1; i++)
		{
			// 缩放映射关系 
			srcX = (i + 0.5)*((float)srcCols) / (dstCols)-0.5;
			srcY = (j + 0.5)*((float)srcRows) / (dstRows)-0.5;
			int iSrcX = (int)srcX;
			int iSrcY = (int)srcY;
			// 三通道求邻域加权值1
			t1X = ((uchar*)(src.imageData + srcStep*iSrcY))[
				iSrcX * 3 + 0] * (1 - std::abs(srcX - iSrcX)) +
					((uchar*)(src.imageData + srcStep*iSrcY))[
						(iSrcX + 1) * 3 + 0] * (srcX - iSrcX);
						t1Y = ((uchar*)(src.imageData + srcStep*iSrcY))[
							iSrcX * 3 + 1] * (1 - std::abs(srcX - iSrcX)) +
								((uchar*)(src.imageData + srcStep*iSrcY))[
									(iSrcX + 1) * 3 + 1] * (srcX - iSrcX);
									t1Z = ((uchar*)(src.imageData + srcStep*iSrcY))[
										iSrcX * 3 + 2] * (1 - std::abs(srcX - iSrcX)) +
											((uchar*)(src.imageData + srcStep*iSrcY))[
												(iSrcX + 1) * 3 + 2] * (srcX - iSrcX);
												// 三通道求邻域加权值2
												t2X = ((uchar*)(src.imageData + srcStep*(
													iSrcY + 1)))[iSrcX * 3] * (1 - std::abs(srcX - iSrcX))
													+ ((uchar*)(src.imageData + srcStep*(
														iSrcY + 1)))[(iSrcX + 1) * 3] * (srcX - iSrcX);
												t2Y = ((uchar*)(src.imageData + srcStep*(
													iSrcY + 1)))[iSrcX * 3 + 1] * (1 - std::abs(srcX - iSrcX))
													+ ((uchar*)(src.imageData + srcStep*(
														iSrcY + 1)))[(iSrcX + 1) * 3 + 1] * (srcX - iSrcX);
												t2Z = ((uchar*)(src.imageData + srcStep*(
													iSrcY + 1)))[iSrcX * 3 + 2] * (1 - std::abs(srcX - iSrcX))
													+ ((uchar*)(src.imageData + srcStep*(iSrcY + 1)))[(
														iSrcX + 1) * 3 + 2] * (srcX - iSrcX);
												// 根据公式求解目标图像加权
												((uchar*)(dst.imageData + dstStep*j))[i * 3] =
													t1X*(1 - std::abs(srcY - iSrcY)) + t2X*(
														std::abs(srcY - iSrcY));
												((uchar*)(dst.imageData + dstStep*j))[i * 3 + 1] =
													t1Y*(1 - std::abs(srcY - iSrcY)) + t2Y*(
														std::abs(srcY - iSrcY));
												((uchar*)(dst.imageData + dstStep*j))[i * 3 + 2] =
													t1Z*(1 - std::abs(srcY - iSrcY)) + t2Z*(
														std::abs(srcY - iSrcY));
		}
		// 列操作
		((uchar*)(dst.imageData + dstStep*j))[(dstCols - 1) * 3] =
			((uchar*)(dst.imageData + dstStep*j))[(dstCols - 2) * 3];
		((uchar*)(dst.imageData + dstStep*j))[(dstCols - 1) * 3 +
			1] = ((uchar*)(dst.imageData + dstStep*j))[(
				dstCols - 2) * 3 + 1];
		((uchar*)(dst.imageData + dstStep*j))[(dstCols - 1) * 3
			+ 2] = ((uchar*)(dst.imageData + dstStep*j))[(
				dstCols - 2) * 3 + 2];
	}
	// 行操作
	for (int i = 0; i < dstCols * 3; i++)
	{
		((uchar*)(dst.imageData + dstStep*(dstRows - 1)))[i] =
			((uchar*)(dst.imageData + dstStep*(dstRows - 2)))[i];
	}
	return  dstImage;
}
int main()
{
	cv::Mat srcImage = cv::imread("..\\images\\flower3.jpg");
	if (!srcImage.data)
		return -1;
	cv::Mat dstImage = BilinearInterpolation(srcImage);
	cv::imshow("srcImage", srcImage);
	cv::imshow("dstImage", dstImage);
	cv::waitKey(0);
	return 0;
}

转载:http://blog.csdn.net/zhuwei1988


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值