3.3 图像几何变换——缩小和放大
作者:互联网
1. 图片缩小
比例缩放前后两点 P 0 ( x 0 , y 0 ) P_0(x_0, y_0) P0(x0,y0)、 P ( x , y ) P(x,y) P(x,y) 之间的关系用矩阵形式可以表示为
[ x y 1 ] = [ f x 0 0 0 f y 0 0 0 1 ] [ x 0 y 0 1 ] \left[\begin{matrix} x \\ y \\ 1 \end{matrix}\right] =\left[\begin{matrix} f_x & 0 & 0\\ 0 & f_y & 0\\ 0 & 0 & 1 \end{matrix}\right] \left[\begin{matrix} x_0 \\ y_0 \\ 1 \end{matrix}\right] ⎣⎡xy1⎦⎤=⎣⎡fx000fy0001⎦⎤⎣⎡x0y01⎦⎤
在数字图像中,图像缩小是通过减少像素个数实现,关键在于怎么去掉一部分像素点,而尽可能保持原有图像的概貌特征。下面介绍两种简单的图像缩小技术。
为了理解算法,应该先把图像想成是连续的,然后再四舍五入取离散值。比如计算后得出,缩小后的图像点
(
2
,
2
)
(2,2)
(2,2) 的像素值与原图像
(
2.1
,
2.8
)
(2.1, 2.8)
(2.1,2.8) 处相等,就四舍五入取原图像
(
2
,
3
)
(2,3)
(2,3) 处的坐标。
为了便于叙述,放大或缩小前的图像为原图像
R
R
R,可理解为单词
r
a
w
raw
raw,放大或缩小后的图像为新图像
S
S
S,
R
R
R的后面一个字母。
-
最近邻采样
原图像为 R ( x , y ) R(x, y) R(x,y),新图像为 S ( x , y ) S(x, y) S(x,y),设原图像和新图像 x x x 方向和 y y y 方向比例分别为 r x , r y r_x, r_y rx,ry,这个 r x , r y r_x, r_y rx,ry 也可以看作是下采样的采样间隔。
为了方便理解缩小,把原图像看作是新图像的放大,则新图像在 ( x , y ) (x,y) (x,y) 处的灰度值 S ( x , y ) S(x,y) S(x,y),有
S ( x , y ) = R ( r x ⋅ x , r y ⋅ y ) S(x,y) = R(r_x\cdot x, r_y\cdot y) S(x,y)=R(rx⋅x,ry⋅y)
如果 r x ⋅ x r_x\cdot x rx⋅x 算出来是小数,四舍五入即可,其余同理。其实新图像的坐标 -
局部平均值采样
找出两次采样间的子块,然后求平均值为当前像素值。比如原图像大小为 4 × 4 4\times 4 4×4,要缩小为 2 × 2 2\times 2 2×2,则缩小后图像 ( 1 , 1 ) (1,1) (1,1) 的值就是原图像的左上角的 2 × 2 2\times 2 2×2 的局部单元像素的平均值。对于小数也差不多,四舍五入。在实际编程中,都是直接调用函数,不必为各种繁琐的四舍五入操心。
2. 图像放大
-
最近邻采样
和上面所述的差不多,举例说明。比如原来 10 × 10 10\times 10 10×10 的图片,放大到 15 × 15 15\times 15 15×15,即放大了 1.5 1.5 1.5 倍,要计算新图像在 ( 10 , 11 ) (10, 11) (10,11), 则对应原图像 ( 10 / 1.5 , 11 / 1.5 ) = ( 6.7 , 7.3 ) (10/1.5, 11/1.5)=(6.7, 7.3) (10/1.5,11/1.5)=(6.7,7.3) 处的像素值,四舍五入取整原图像 ( 7 , 7 ) (7, 7) (7,7) 处的像素值即可。 -
线性插值法
线性插值法就是找周围最近的几个点,线性组合取值。举个简单的例子说明。和刚刚的最近邻采样条件一样,也求 ( 10 , 11 ) (10,11) (10,11) 处的坐标。上面求处该坐标对应原图像 R ( 6.7 , 7.3 ) R(6.7, 7.3) R(6.7,7.3) 处的值,此时应找距离 R ( 6.7 , 7.3 ) R(6.7, 7.3) R(6.7,7.3) 最近的几个点,即 ( 6 , 7 ) , ( 6 , 8 ) , ( 7 , 7 ) , ( 7 , 8 ) (6,7), (6,8), (7,7), (7,8) (6,7),(6,8),(7,7),(7,8) 四点加权来算新图像的像素值,距离近则权值大。大家可以自己在纸上画个图,可以先看 x x x 方向,再看 y y y 方向。
x x x 方向,根据距离远的权值小,有:
R ( 6.7 , y ) = ( 1 − 0.7 ) R ( 6 , y ) + 0.7 R ( 7 , y ) R(6.7,y) = (1-0.7)R(6,y) + 0.7R(7,y) R(6.7,y)=(1−0.7)R(6,y)+0.7R(7,y)
则可以算出 R ( 6.7 , 7 ) R(6.7, 7) R(6.7,7), R ( 6.7 , 8 ) R(6.7, 8) R(6.7,8)。再次使用加权可求 R ( 6.7 , 7.3 ) R(6.7, 7.3) R(6.7,7.3)
即有:
R ( 6.7 , 7.3 ) = ( 1 − 0.3 ) R ( 6.7 , 7 ) + 0.3 R ( 6.7 , 8 ) R(6.7, 7.3) = (1-0.3)R(6.7, 7) + 0.3R(6.7, 8) R(6.7,7.3)=(1−0.3)R(6.7,7)+0.3R(6.7,8)
最终算出原图像 R ( 6.7 , 7.3 ) R(6.7, 7.3) R(6.7,7.3) 处的像素值,也即新图像 ( 10 , 11 ) (10,11) (10,11) 处的像素值。
OpenCv实战
直接用 resize
函数即可实现放大缩小。
cv.resize(img, dsize, [interpolation])
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def show(img):
plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB), cmap='gray', vmin=0, vmax=255)
plt.show()
img = cv.imread('pic/rabbit50x33.jpg') # 路径更换成新的图片
img_resize1 = cv.resize(img, (330, 500), interpolation=cv.INTER_NEAREST)
img_resize2 = cv.resize(img, (330, 500), interpolation=cv.INTER_LINEAR)
show(img)
show(np.hstack([img_resize1, img_resize2]))
标签:11,10,img,6.7,7.3,几何变换,3.3,图像 来源: https://blog.csdn.net/gengli2017/article/details/116301237