图像处理基础--图像缩放(原理、C++代码)

1、最近邻插值(最最基础的方法了)

举个栗子:

假设我们有一张原始图(源图,source),大小为3*3。

225 46 77
56 88 77
45 125 35

想要放大为4*4的目标图(destination)。

? ? ? ?
? ? ? ?
? ? ? ?
? ? ? ?

 接着就该考虑怎么由源图填充目标图的像素了。

以左上角(0,0)为例,由公式

srcX=dstX*(srcWidth/dstWidth) ;

srcY=dstY*(srcHeight/dstHeight)

得到应该由源图中的(0,0)点像素值进行填充。以此类推目标图片中(1,0)点由源图中(1*(3/4),0*(3/4))=>(0.75,0)=>(1,0)填充(四舍五入),其它点类推可得到放大的图。

这种放大图像的方法会引起严重的失真,根源在于当坐标是浮点数时直接四舍五入取最近的整数。

代码:

# include<iostream>
# include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

Mat NearInter(Mat &srcImage, double kx, double ky)
{
	int rows = cvRound(srcImage.rows*kx);
	int cols = cvRound(srcImage.cols*ky);
	Mat resultImg(rows, cols, srcImage.type());
	int i, j, x, y;
	for (i = 0; i < rows; i++)
	{
		x = static_cast<int>((i + 1) / kx + 0.5) - 1;
		for (j = 0; j < cols; j++)
		{
			y = static_cast<int>((j + 1) / ky + 0.5) - 1;
			resultImg.at<Vec3b>(i, j) = srcImage.at<Vec3b>(x, y);
		}
	}
	return resultImg;
}

int main()
{
	Mat srcImg = imread("文件路径");
	Mat resultImg = NearInter(srcImg, 0.6, 1.2);
	imshow("src", srcImg);
	imshow("0.6,1.2", resultImg);
	waitKey(0);
	return 0;
}

2、 双线性插值
在最近邻插值时,对于源图中坐标为浮点数的点,直接四舍五入取整带来了严重的失真。比如0.75直接取1,更科学的方法是,0.75距离1为0.25,距离0为0.75,按照距离的占比取相应点像素值的找比。

对于目标图通过反向变换得到的源图中浮点坐标为(i+u,j+v)(其中i,j为浮点数的整数部分,u,v为浮点数的小数部分);

这个点的像素值f(i+u,j+v)=(1-u)(1-v)f(i,j)+(1-u)vf(i,j+1

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值