图像插值算法
简介
在图像处理中,有平移,旋转,缩放等常用操作。这些操作并不改变图像的像素值,只是在图像上进行像素的重新排列,图像变换常用到一些插值算法,本节主要介绍常见的最近邻插值、双线性插值
最近邻插值
最近邻插值,是将目标图像中的点,对应到源图像中后,找到最相邻的整数点,作为插值后的输出。
假设我们将一幅3X3的图像放大到4X4,用 f ( x , y ) f(x, y) f(x,y)表示目标图像, h ( x , y ) h(x, y) h(x,y)表示原图像,我们有如下公式:
f
(
d
s
t
x
,
d
s
t
y
)
=
h
(
d
s
t
x
s
r
c
w
i
d
t
h
d
s
t
w
i
d
t
h
,
d
s
t
y
s
r
c
h
e
i
g
h
t
d
s
t
h
e
i
g
h
t
)
\begin{array}{c}f(dst_{x}, dst_{y}) = h(\frac{dst_{x} src_{width}} {dst_{width}}, \frac{dst_{y} src_{height}} {dst_{height}})\end{array}
f(dstx,dsty)=h(dstwidthdstxsrcwidth,dstheightdstysrcheight)
f
(
0
,
0
)
=
h
(
0
,
0
)
f
(
0
,
1
)
=
h
(
0
,
0.75
)
=
h
(
0
,
1
)
f
(
0
,
2
)
=
h
(
0
,
1.50
)
=
h
(
0
,
2
)
f
(
0
,
3
)
=
h
(
0
,
2.25
)
=
h
(
0
,
2
)
.
.
.
\begin{array}{c}f(0,0)=h(0,0) \\f(0,1)=h(0,0.75)=h(0,1) \\f(0,2)=h(0,1.50)=h(0,2) \\f(0,3)=h(0,2.25)=h(0,2) \\...\\\end{array}
f(0,0)=h(0,0)f(0,1)=h(0,0.75)=h(0,1)f(0,2)=h(0,1.50)=h(0,2)f(0,3)=h(0,2.25)=h(0,2)...
最近邻插值缺点:*
使用该方法作图像放大处理时,易出现明显的块状效应。
双线性插值
在讲双线性插值之前先看以一下线性插值,线性插值多项式为:
f
(
x
)
=
a
1
x
+
a
0
f(x)=a_{1} x+a_{0}
f(x)=a1x+a0
y
=
y
0
+
(
x
−
x
0
)
y
1
−
y
0
x
1
−
x
0
=
y
0
+
(
x
−
x
0
)
y
1
−
(
x
−
x
0
)
y
0
x
1
−
x
0
y=y_{0}+\left(x-x_{0}\right) \frac{y_{1}-y_{0}}{x_{1}-x_{0}}=y_{0}+\frac{\left(x-x_{0}\right) y_{1}-\left(x-x_{0}\right) y_{0}}{x_{1}-x_{0}}
y=y0+(x−x0)x1−x0y1−y0=y0+x1−x0(x−x0)y1−(x−x0)y0
OpenCV缩放函数
cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
参数:
参数 | 描述 |
---|---|
src | 【必需】原图像 |
dsize | 【必需】输出图像所需大小 |
fx | 【可选】沿水平轴的比例因子 |
fy | 【可选】沿垂直轴的比例因子 |
interpolation | 【可选】插值方式 |
插值方式:
cv.INTER_NEAREST | 最近邻插值 |
cv.INTER_LINEAR | 双线性插值 |
cv.INTER_CUBIC | 基于4x4像素邻域的3次插值法 |
cv.INTER_AREA | 基于局部像素的重采样 |
通常,缩小使用cv.INTER_AREA,缩放使用cv.INTER_CUBIC(较慢)和cv.INTER_LINEAR(较快效果也不错)。默认情况下,缩放都使用cv.INTER_LINEAR。
python 实现
import cv2
if __name__ == "__main__":
img = cv2.imread('images/yuner.jpg', cv2.IMREAD_UNCHANGED)
print('Original Dimensions : ', img.shape)
# 按原始图像的30%缩小
scale_percent = 30
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
# resize image
resized = cv2.resize(img, dim, interpolation=cv2.INTER_LINEAR)
fx = 1.5
fy = 1.5
# 将前面缩小的图像按1.5倍放大 采用最近邻插值
resized1 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation=cv2.INTER_NEAREST)
# 将前面缩小的图像按1.5倍放大 采用双线性值
resized2 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation=cv2.INTER_LINEAR)
print('Resized Dimensions : ', resized.shape)
cv2.imshow("Resized image", resized)
cv2.imshow("INTER_NEAREST image", resized1)
cv2.imshow("INTER_LINEAR image", resized2)
cv2.waitKey(0)
cv2.destroyAllWindows()
0.3倍缩小
1.5倍放大 最近邻插值
1.5倍放大 双线性插值