从Nearest插值到Bilinear插值的分析与python实现
从Nearest插值到Bilinear插值的分析与python实现
这篇主要是想分析一下Nearest差值和Bilinear差值的计算细节,然后附上对应的Python实现代码,希望对你有帮助:https://github.com/LonglongaaaGo/ComputerVision
效果
先给出实现效果。
首先我们有一张小狗狗:
然后用Nearest 上采样,能够得到:
可以看到,有很多的锯齿,看起来不是很完美。
然后试试这个实现的Bilinear 上采样:
能够看到整体上柔和很多~虽然有点模糊,但是比Nearest好了很多。
正文
图像在计算机当中进行表示的话,是离散的,形式如下:
就是
x
,
y
x,y
x,y能够表示对应在图像中的坐标,而
F
F
F看成对应的函数。
F
[
x
,
y
]
F[x,y]
F[x,y]表示的就是对应的像素信息。为了方便 讨论,就从1通道进行解释。
但是如果我们想做变换的话,如果直接用离散的点进行变换,肯定会丢失很多信息,所以我们就要考虑在连续的空间里进行变换。对应的,表现形式可以如下:
如果我们将
F
[
0
,
0
]
F[0,0]
F[0,0]的中心点作为坐标
(
0
,
0
)
(0,0)
(0,0)的话,那么对应的左对角的点就是
(
−
0.5
,
−
0.5
)
(-0.5,-0.5)
(−0.5,−0.5)。这种做法比较常见,也是比较推荐的一种形式。接下来就是要对图像进行缩放,缩放的公式就是:
(srcX+0.5)
=
(
d
s
t
X
+
0.5
)
∗
(
s
r
c
W
i
d
t
h
/
d
s
t
W
i
d
t
h
)
\operatorname{(srcX+0.5)}=\mathrm{(dstX+0.5)} *(\mathrm{srcWidth} / \mathrm{dstWidth})
(srcX+0.5)=(dstX+0.5)∗(srcWidth/dstWidth)
(srcY+0.5)
=
(
d
s
t
Y
+
0.5
)
∗
(
s
r
c
H
e
i
g
h
t
/
d
s
t
H
e
i
g
h
t
)
\operatorname{(srcY+0.5)}=\mathrm{(dstY+0.5)} *(\mathrm{srcHeight} / \mathrm{dstHeight})
(srcY+0.5)=(dstY+0.5)∗(srcHeight/dstHeight)
这里定义
(srcX,srcY)
\operatorname{(srcX,srcY)}
(srcX,srcY)就是对应的原始图像的坐标
(dstX,dstY)
\operatorname{(dstX,dstY)}
(dstX,dstY)就是对应的缩放后的图像的坐标
s
r
c
W
i
d
t
h
,
s
r
c
H
e
i
g
h
t
\mathrm{srcWidth,srcHeight}
srcWidth,srcHeight就是原始图像的宽和高
d
s
t
W
i
d
t
h
,
d
s
t
H
e
i
g
h
t
\mathrm{dstWidth,dstHeight}
dstWidth,dstHeight就是缩放后的图像的宽和高
通过上述公式和定义,我们可以很快地计算出缩放后的图片和原图之间的关系。根据上面公式得到各个点的位置之后,就需要将连续点转化成离散的点。而Nearest差值和Bilinear差值方法的区别,也主要在这一步:
Nearest 插值方法就比较简单,就是直接四舍五入将连续地点变成离散的整数。这样的做法存在的问题上面也看到了,就是会产生明显的锯齿。如果还不明白的话,看一眼代码会更加直观。形式如下图所示:
就是说,假设灰色的点代表是插值的点,那么就是取其最近的颜色,作为插值后的颜色。所以在这里表示就是亮黄色。直接赋值。
双线性插值 Bilinear Interpolation,直观理解如下图所示:
我们还是建立在上述情况,这个时候,灰色的点
q
q
q位于
(
x
,
y
)
(x,y)
(x,y),不再是直接考虑最近的点,而是和其相近的四个点,然后通过面积的比重,来分配权重。所以公式可以表示成:
q
=
V
1
∗
A
1
+
V
2
∗
A
2
+
V
3
∗
A
3
+
V
4
∗
A
4
q=V 1* A 1+V 2 * A 2+V 3*A 3+V 4* A 4
q=V1∗A1+V2∗A2+V3∗A3+V4∗A4
对应的计算就可以这么写(请参照图上的坐标进行一一对应):
f
(
x
,
y
)
≈
f
(
V
1
)
(
x
2
−
x
1
)
(
y
2
−
y
1
)
(
x
2
−
x
)
(
y
2
−
y
)
+
f
(
V
2
)
(
x
2
−
x
1
)
(
y
2
−
y
1
)
(
x
−
x
1
)
(
y
2
−
y
)
+
f
(
V
3
)
(
x
2
−
x
1
)
(
y
2
−
y
1
)
(
x
2
−
x
)
(
y
−
y
1
)
+
f
(
V
4
)
(
x
2
−
x
1
)
(
y
2
−
y
1
)
(
x
−
x
1
)
(
y
−
y
1
)
.
\begin{aligned} &f(x, y) \approx \frac{f\left(V_{1}\right)}{\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)}\left(x_{2}-x\right)\left(y_{2}-y\right)+\frac{f\left(V_{2}\right)}{\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)}\left(x-x_{1}\right)\left(y_{2}-y\right) \\ &+\frac{f\left(V_{3}\right)}{\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)}\left(x_{2}-x\right)\left(y-y_{1}\right)+\frac{f\left(V_{4}\right)}{\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)}\left(x-x_{1}\right)\left(y-y_{1}\right) . \end{aligned}
f(x,y)≈(x2−x1)(y2−y1)f(V1)(x2−x)(y2−y)+(x2−x1)(y2−y1)f(V2)(x−x1)(y2−y)+(x2−x1)(y2−y1)f(V3)(x2−x)(y−y1)+(x2−x1)(y2−y1)f(V4)(x−x1)(y−y1).
这样就能直接得到当前点
f
(
x
,
y
)
f(x,y)
f(x,y)的值。
注意,
f
(
x
,
y
)
f(x,y)
f(x,y)表示的就是像素,以函数的形式来进行表示。
(
x
2
−
x
1
)
(
y
2
−
y
1
)
\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)
(x2−x1)(y2−y1)表示的就是总面积。
至此,Nearest差值和Bilinear差值讲解就结束了,可以看一下代码,更能够容易理解一点。
如果觉得不错,记得关注哟!一起来学习深度学习,机器学习等前沿算法!!
欢迎转载!
参考:https://www.cnblogs.com/wojianxin/p/12516029.html
更多推荐
所有评论(0)