插值算法

您所在的位置:网站首页 图像放大插值方法 插值算法

插值算法

2024-04-17 06:27| 来源: 网络整理| 查看: 265

大家应该对插值运算并不陌生,有最近邻插值、线性插值、双线性插值、高阶插值等算法. 本文针对的对象是图像,从图像缩放的角度去理解插值算法.

首先问大家一个问题,什么是插值 ?

1.什么是插值 Interpolation is a method of constructing new data points within the range of a discrete set of known data points. Image interpolation refers to the "guess" of intensity values at missing locations.

图像的缩放是一张图像处理的基础操作,比如我们下了一张图像,可是它的尺寸并不能满足我们的需求,如果小了,我就想放大,大了,就想放小.

Q1:那它到底是怎么做的呢?

A1:一般采用:插值运算,通过上面的插值解释,我们知道,插值就是通过一系列已知的数据点,来"猜测"未知点". 在图像领域上,修改图像尺寸时常用到插值运算. 由原图像矩阵中的点计算新图像矩阵中的点,不同的计算过程,就有不同的插值算法.

图1 图像放大

Q2:它背后的原理又是什么?

至于原理,主要讲最近邻、单线性插值双线性插值三种算法的原理.

2.最近邻法 (Nearest Interpolation)

"近邻",顾名思义就是从原图像矩阵中找到与它(目标图像的像素点)距离最近的点,然后将最近点的像素值,赋给它就行了.

那么问题来了,该怎么找到最近的点?

假设目标图像与原图像的坐标点的对应关系如下:

\begin{cases} src\_x = des\_x * src\_w / des\_w \\ src\_y = des\_y * src\_h / des\_h \end{cases} \tag{1}

其中:

src\_x : 原图像中像素点 x 坐标src\_y : 原图像中像素点 y 坐标des\_x : 目标图像中像素点 x 坐标des\_y : 目标图像中像素点 y 坐标src\_w : 原图像宽度(width)src\_h : 原图像高度(high)des\_w : 目标图像宽度(width)des\_h : 目标图像高度(high)图2 最近邻插值

虽然简单,我们还是来计算一下:

目标像素坐标 → 原图像像素坐标

注:如果坐标为小数,四舍五入即可.

\begin{cases} \color{Maroon}{des\_x = 0, des\_y = 0} \\ src\_x = des\_x * src\_w / des\_w = 0 * 3 / 4 = 0 \\ src\_y = des\_y * src\_h / des\_h = 0 * 3 / 4 = 0 \end{cases}

\begin{cases} \color{Maroon}{des\_x = 1, des\_y = 0} \\ src\_x = des\_x * src\_w / des\_w = 1 * 3 / 4 = 0.75 \approx 1 \\ src\_y = des\_y * src\_h / des\_h = 0 * 3 / 4 = 0 \end{cases}

\begin{cases} \color{Maroon}{des\_x = 2,des\_y = 0} \\ src\_x = des\_x * src\_w / des\_w = 2 * 3 / 4 = 1.5 \approx 2\\ src\_y = des\_y * src\_h / des\_h = 0 * 3 / 4 = 0 \end{cases}

\begin{cases} \color{Maroon}{des\_x = 3,des\_y = 0} \\ src\_x = des\_x * src\_w / des\_w = 3* 3 / 4 = 2.25 \approx 2 \\ src\_y = des\_y * src\_h / des\_h = 0 * 3 / 4 = 0 \end{cases}

上面已计算出目标图像的第一行像素点坐标对应于原图像的坐标. 其余的坐标对应关系也可上述方法依次计算.

分析:最邻近算法计算量较小,但可能会造成插值生成的灰度上的不连续,在灰度变化的位置处,可能会产生明显的锯齿现象.

我们既然发现了最近邻插值算法的缺陷,它只是在原图像中找离它最近的像素点,这样不太好,那我们能否找两个离它最近的点呢 ?请看下面的单线性插值.

3.线性插值(Linear Interpolation)

① 单线性插值(Single Linear Interpolation)

最近邻插值只需要在原图像矩阵找到离它最近的像素点,然后进行赋值即可. 单线性插值需要找到周围最近的两个点进行插值运算.

它的数学原理如下:首先,开局一张图,哈哈...

图3 单线性插值图例

如图3所示:已知点 (x_{0}, y_{0}) , (x_{1}, y_{1}) ,要得到区间 [x, y] 中某一位置x 在直线上的 y 值. 根据图3,我们可以得到:

\frac{y-y_{0}}{x-x_{0}} = \frac{y_{1}-y_{0}}{x_{1}-x_{0}} \tag{2}

上式(2),我们整理得: y = \frac{x_{1}-x}{x_{1}-x_{0}}y_{0}+\frac{x-x_{0}}{x_{1}-x_{0}}y_{1} \tag{3}

上式(3),首先看分子,分子可以看成 x 分别到 x_{1} 和 x_{2} 的距离. 把整个分式分别看成 y_{0} 与 y_{1} 的加权系数. (离哪个点近,权重就高)

回到我们的研究目的:我们要根据原图像中2个点的像素值未知点的像素值. 因此我们可以这样做,将上式(3)中的 y_{1} 与 y_{2} 分别代表原图像中的像素值,上面的公式可写成如下形式:

f(p) = \frac{x_{1} - x}{x_{1} - x_{0}} f(p_{0}) + \frac{x-x_{0}}{x_{1} - x_0{}} f(p_{1}) \tag{4}

其本质就是在 x 方向进行了一次线性插值.

我在网上没有找到用单线性插值进行图像尺寸变换,一般用的是双线性插值,下面,我自己根据其原理,推测单线性插值进行图像缩放的过程,如下:(这都是我自己的推测,不一定正确)

同理运用上面的坐标转换公式(1):

目标图像坐标 → 原图像坐标 (注:目标图像4 × 4,原图像 3 × 3 )

(desx, desy) (srcx, src_y) y坐标四舍五入 (0, 0) → (0, 0) → (0, 0) (1, 0) → (0.75, 0) → (0.75, 0) (2, 0) → (1.5, 0) → (1.5, 0) (3, 0) → (2.25, 0) → (2.25, 0) (0, 1) → (0, 0.75) → (0, 1) (1, 1) → (0.75, 0.75) → (0.75, 1) (2, 1) → (1.5, 0.75) → (1.5, 1) (3, 1) → (2.25, 0.75) → (2.25, 1) (0, 2) → (0, 1.5) → (0, 2) (1, 2) → (0.75, 1.5) → (0.75, 2) (2, 2) → (1.5, 1.5) → (1.5, 2) (3, 2) → (2.25, 1.5) → (2.25, 2) (0, 3) → (0, 2.25) → (0, 2) (1, 3) → (0.75, 2.25) → (0.75, 2) (2, 3) → (1.5, 2.25) → (1.5, 2) (3, 3) → (2.25, 2.25) → (2.25, 2)

运用式(4)便可求目标图像的像素值,如下图4所示:

图4 图像的单线性插值

对于边界点,比如目标图像的坐标(3, 0)对应于原图像的(2.25, 0),它周围的点就只有(2, 0),我是直接把原图像坐标(2, 0)的像素值赋给目标图像坐标(3, 0).

但如果直接赋值,对边界点是不公平的. (如果不太懂,不要紧,后面还会详细说明)

Q3:目标图像的坐标(3, 0)对应于原图像的(2.25, 0),它周围的点除了(2, 0),那(1, 0)算不算?如果算的话,那么(2.25,0)就不是夹在两个已知点中间,而是在已知点的延长线上,与我们的原理好像不太符合. (这也是我有点纠结的地方).

猜测:这可能是坐标转换公式本身所带来的问题,式(1)默认:目标图像与原图像的左上角点重合,也就是坐标点(0, 0).

② 双线性插值(Bilinear Interpolation)

双线性插值中的"双",指的是对 x方向与 y 方向分别进行插值,其实共进行了三次单线性插值,所以这个"双"应该理解成两个方向的插值,而非插值的次数.

明白了单线性插值原理,其实应该也能懂双线性插值,其原理如下图5所示:

图5 双线性插值

双线性插值:影响目标点的是周围四个点.

已知 Q_{11} (x_{1}, y_{1}) , Q_{12} (x_{1}, y_{2}) , Q_{21} (x_{2}, y_{1}) , Q_{22} (x_{2}, y_{2}) ,未知点 P(x, y) . 函数 f 为点的像素值,如:f(Q_{11}),f(Q_{12}),f(Q_{21}),f(Q_{22}) 分别为 Q_{11}, Q_{12}, Q_{21}, Q_{22} 的像素值.

如何求未知点的 f(P) ?

第一步:利用单线性插值在 x 方向求 f(R_{1}) :

f(R_{1}) = \frac{x_{2} - x}{x_{2}-x_{1}} f(Q_{11})+\frac{x-x_{1}}{x_{2}-x_{1}} f{Q_{21}} \tag{5}

第二步:利用单线性插值在 x 方向求 f(R_{2}) :

f(R_2) = \frac{x_{2}-x}{x_{2}-x_{1}} f(Q_{12}) + \frac{x-x_{1}}{x_{2}-x_{1}} f(Q_{22}) \tag{6}

第三步:利用单线性插值在 y 方向求 f(P) :

f(P)=\frac{y_{2}-y}{y_{2}-y_{1}}f(R_{1}) + \frac{y-y_{1}}{y_{2}-y_{1}}f(R_{2}) \tag{7}

联合(5)、(6)、(7)三式,可求得:

f(P)=\frac{y_{2}-y}{y_{2}-y_{1}}\left(\frac{x_{2} - x}{x_{2}-x_{1}} f(Q_{11})+\frac{x-x_{1}}{x_{2}-x_{1}} f(Q_{21})\right) \\+ \frac{y-y_{1}}{y_{2}-y_{1}} \left(\frac{x_{2}-x}{x_{2}-x_{1}} f(Q_{12}) + \frac{x-x_{1}}{x_{2}-x_{1}} f(Q_{22})\right) \tag{8}

在图像中,其实不难发现,在计算中有这位的关系:

\begin{cases} x_{2} - x_{1} = 1 \\ y_{2} - y_{1} = 1 \end{cases} \tag{9}

所以式(8)可简化成:

f(P)=(x_{2}-x)(y_{2}-y)f(Q_{11})+(x_{2}-x)(y-y_{1})f(Q_{12}) +\\ (x-x_{1})(y_{2}-y)f(Q_{21}) + (x-x_{1})(y-y_{1}) f(Q_{22}) \tag{10}

在有些资料中会写成权重的形式,如下:

f(P)=f(Q_{11})w_{11} + f(Q_{12})w_{12} +f(Q_{21})w_{21} + f(Q_{22} )w_{22} \tag{11}

观察一下,就会发现每个点的权重和待求点与对角线的距离有关.

Q4:如果目标图像的某一像素点的坐标通过式(1)的转换公式与原图像的坐标重合,会出现什么情况呢?

A4:直接说,不太好说,举例:

假设目标图像的某一点 通过转换 变成目标图像的坐标点为 (x, y)=(x_{2}, y_{2}) .

与 Q_{22}重合(原图像某一点坐标). 代入上式(10)得:

f(P)=(x-x_{1})(y-y_{1})f(Q_{22}) \tag{12}=(x_{2} - x_{1})(y_{2}-y_{1})f(Q_{22}) = f(Q_{12})

其实,当目标图像坐标点映射之后与原图像坐标点重合时,其余3个点的权重至少有一项为0,那么重合两点的像素是相等的.

到此,双线性插值的计算勉强完成了,为什么这么说呢,现在的计算方式,还存在较大的问题.

请继续往下看...

通过式(1),我们可以知道目标图像坐标位置映射到原图像中的位置,其实,这样的对应关系是存在问题的,在讲解单线性插值,就提到过.

第一个问题:如果我们是以式(1)作为目标图像与原图像坐标之间的对应关系,那我们的原点就是坐标(0, 0),目标图像与原图像在此点重合,这样会产生一个问题,最上边 x=0 的点像素会有概率直接复制到目标图像中(到少原点是这样的),而且就算不和原图像中的点重合,但也只进行了1次单线性插值.

可能大家对这个问题,还是有点不太明白,我们还是举例说明:

假设原图像大小是 5×5,目标图像大小是3×3,根据式(1)的坐标对应关系,我们可以求得目标第一行的坐标在原图像中的对应关系,如下:

(desx, desy) (srcx, src_y)(0, 0) → (0, 0)(1, 0) → (5/3, 0)(2, 0) → (10/3, 0)

由式(10)可计算目标图像像素值:

\begin{cases} f(0, 0) = f(0, 0) \\ f(5/3, 0) = (2-5/3)(1-0)f(1, 0) + (5/3-1)(1-0)f(2, 0) + (2-5/3)(0-0)f(1, 1) + (5/3-1)(0-0)f(2, 1) \\ f(10/3, 0) = (4-10/3)(1-0)f(3, 0) + (10/3-3)(1-0)f(4, 0) + (4-10/3)(0-0)f(3, 1) + (10/3-3)(0-0)f(4, 1) \tag{13} \end{cases}

观察式(13)可发现,重合点的像素值相等, 对于f(5/3, 0),其实只有f(1, 0)与f(2, 0)起到了作用,它们的权重分别为1/3与2/3,而f(1, 1)与f(2, 1)的权重为0,所以对f(5/3, 0)起到影响的只有f(1, 0)与f(2, 0).

同理:f(10/3, 0)亦是如此.

所以说这对边界点是"不公平"的,相当于只进行了单线性插值.

对于上面的过程,可用下图6表示:

图6 目标图像第一行映射到原图像注:图中红色方块是表示目标图像第一行的像素点映射到原图像中的位置.

第二个问题:

我们再来看一看几何中心点的坐标:

目标图像几何中心点坐标:(1, 1) 映射到 原图像坐标:(5/3, 5/3)

那么问题来了,目标图像的原点(0, 0)与原始图像的原点是重合的,但是,目标图像的几何中心相对于原图像的几何中心(2, 2)偏左上,那么整体图像的位置会发生偏移,其实图像由1个个像素组成,单纯说一个像素点没有多大意义,1个像素点跟相邻像素的值的渐变或突变形成图像颜色的渐变或边界,所以参与计算的像素点相对都往左上偏,这样会产生相对的位置信息损失.

注:最右边和最下边的像素实际没有参与计算

其实上面的问题对于我们人眼不会有什么太大的影响,但对于现在的卷积神经网络提取图像的深层信息,在这个过程中,我们人眼难以发现的变化也许会发生意料之外的变化.

上面的两个问题,都是由于坐标转换公式造成的,现在我们对坐标稍微做一些修改,将左上角(0, 0)重合,修改为几何中心的重合,修改公式如下:

\begin{cases} src_x = (des_x + \color{brown}{0.5}) * src_w/des_w - \color{brown}{0.5}\\ src_y = (des_y +\color{brown}{0.5}) * src_h/des_h - \color{brown}{0.5} \end{cases} \tag{14}

那上图6,由式(14),可变换下图7:

图7 目标第一行映射到原图像

你仔细观察就会发现,边界像素点还是存在有的像素只是进行了单线性插值,如图7:目标图像一行第二个像素点,可能这是双线性插值算法本身的缺陷,并不能保证每一个像素都是双线性插值,但通过修改转换公式已经比先前好多了.

参考:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3