前言
图像处理中有三种常用的插值算法:
最邻近插值
双线性插值
双立方(三次卷积)插值
其中效果最好的是双立方(三次卷积)插值
,本文介绍它的原理以及使用
如果想先看效果和源码,可以拉到最底部
本文的契机是某次基于canvas
做图像处理时,发现canvas
自带的缩放功能不尽人意,于是重温了下几种图像插值算法,并整理出来。
为何要进行双立方插值
对图像进行插值的目的是为了获取缩小或放大后的图片
常用的插值算法中,双立方插值效果最好
本文中介绍双立方插值的一些数学理论以及实现
双立方
和三次卷积
只是这个插值算法的两种不同叫法而已,可以自行推导,会发现最终可以将求值转化为卷积公式
另外,像Photoshop
等图像处理软件中也有这三种算法的实现
数学理论
双立方插值计算涉及到16
个像素点,如下图
简单分析如下:
其中
P00
代表目标插值图中的某像素点(x, y)
在原图中最接近的映射点- 譬如映射到原图中的坐标为
(1.1, 1.1)
,那么P00
就是(1, 1)
- 譬如映射到原图中的坐标为
而最终插值后的图像中的
(x, y)
处的值即为以上16
个像素点的权重卷积之和
下图进一步分析
如下是对图的一些简单分析
譬如计算插值图中
(distI, distJ)
处像素的值首先计算它映射到原图中的坐标
(i + v, j + u)
也就是说,卷积计算时,
p00
点对应(i, j)
坐标最终,
插值后的图
中(distI, distJ)
坐标点对应的值是原图中(i, j)
处邻近16
个像素点的权重卷积之和i, j
的范围是[i - 1, i + 2]
,[j - 1, j + 2]
卷积公式
设采样公式为
S(x)
原图中每一个
(i, j)
坐标点的值得表达式为f(i, j)
插值后对应坐标的值为
F(i + v, j + u)
(这个值会作为(distI, distJ)
坐标点的值)
那么公式为:
等价于(可自行推导)
提示
一定要区分本文中v, u
和row, col
的对应关系,v
代表行数偏差,u
代表列数偏差(如果混淆了,会造成最终的图像偏差很大)
如何理解卷积?
这是大学数学内容,推荐看看这个答案如何通俗易懂的解释卷积-知乎
采样公式
在卷积公式中有一个S(x)
,它就是关键的卷积插值公式
不同的公式,插值效果会有所差异(会导致加权值不一样)
本文中采用WIKI-Bicubic interpolation中给出的插值公式:
公式中的特点是:
S(0) = 1
S(n) = 0
(当n为整数时)当x超出范围时,S(x)为0
当
a
取不同值时可以用来逼近不同的样条函数(常用值-0.5, -0.75
)
当a取值为-1
公式如下:
此时,逼近的函数是y = sin(x*PI)/(x*PI)