加载图像时经常会遇见要缩放图像的情况,这种时候如何决定缩放后图像对应像素点的像素值,这时候就需要用到插值算法
1.最邻近插值算法
首先假设原图是一个像素大小为W*H的图片,缩放后的图片是一个像素大小为w*h的图片,这时候我们是已知原图中每个像素点上的像素值(即灰度值等)的(⚠️像素点对应像素值的坐标都是整数)。这个时候已知缩放后有一个像素点为(x,y),想要得到该像素点的像素值,那么就要根据缩放比例去查看其对应的原图的像素点的像素值,然后将该像素值赋值给该缩放后图片的像素点(x,y)
缩放公式为:
- 根据横轴,即宽可得:X/x = W/w
- 根据纵轴,即高可得:Y/y = H/h
- 那么能够得到 f(X,Y)= f( W/w * x, H/h *y)
因此这个时候缩放后的图片像素点(x,y)的像素值就对应着原图像素点( W/w * x, H/h *y)的像素值
但是这个时候会出现一个问题就是因为缩放比例的原因,会导致像素点( W/w * x, H/h *y)中的值不是整数,那么就不知道应该对应的是哪个像素点的像素值
这个时候最邻近插值算法使用的方法就是四舍五入法,表示为[.],所以像素值f(x,y) = f( [W/w * x], [H/h *y])
举个例子,如果原图为5*5,缩放后的图为3*3,那么缩放后的图的像素点(1,1)对应的就是原图中([5/3 * 1], [5/3 * 1]) = ([0.6], [0.6]) = (1,1) 像素点对应的像素值
这种方法的好处就是简单,但是坏处就是太过粗暴,会缺失精度,造成缩放后的图像灰度上的不连续,在变化地方可能出现明显锯齿状,如下图所示:(左原图,右缩放后)
生成图片应用:https://dailc.github.io/image-process/examples/scale.html
2.双线性插值算法
假如我们想得到缩放图像素点对应在原图中的像素点P= (x,y) 的值,假设我们原图在Q11 = (x1,y1)、Q12 = (x1,y2), Q21 = (x2,y1) 以及Q22 = (x2,y2) 四个像素点的像素值。如上面最近邻插值算法的例子,P= (0.6,0.6),那么这时候对应的最近的四个像素点为Q11 = (0,1)、Q12 = (0,0), Q21 = (1,1) 以及Q22 = (1,0),那么P= (0.6,0.6)点的像素值就是根据其与这些点的距离相关,距离越近的点的像素值影响越大,计算过程如下:
- 首先是先根据Q11 = (0,1)和Q21 = (1,1)这两个像素点的像素值计算得到R1=(x,y1)像素点的像素值,然后根据Q12 = (0,0)和Q22 = (1,0)这两个像素点的像素值计算得到R2=(x,y2)像素点的像素值
⚠️从上面的例子可以看出,但像素点P= (x,y)离x轴的x1点越近时,像素点Q11 = (0,1)和Q12 = (0,0)对应的像素值多占的比重更重;反之则是Q21 = (1,1)和Q22 = (1,0)对应的像素值多占的比重更重
- 接下来就是根据上一步得到的R1=(x,y1)和R2=(x,y2)这两个像素点的像素值计算得到最终结果P= (x,y)像素点的像素值
⚠️从该式子可见在y轴上,如果P= (x,y)离y轴的y1点越近时,则由Q11 = (0,1)和Q21 = (1,1)得到的R1=(x,y1)像素点的像素值所占的比重更重;反之则是R2=(x,y2)像素点的像素值所占的比重更重
这样就能够得到相应的P= (x,y)的像素值了,例子可见:
很明显看出效果更好点