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=fx000fy0001x0y01

在数字图像中,图像缩小是通过减少像素个数实现,关键在于怎么去掉一部分像素点,而尽可能保持原有图像的概貌特征。下面介绍两种简单的图像缩小技术。
为了理解算法,应该先把图像想成是连续的,然后再四舍五入取离散值。比如计算后得出,缩小后的图像点 ( 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(rxx,ryy)
    如果 r x ⋅ x r_x\cdot x rxx 算出来是小数,四舍五入即可,其余同理。其实新图像的坐标

  • 局部平均值采样
    找出两次采样间的子块,然后求平均值为当前像素值。比如原图像大小为 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) (1011) 处的坐标。上面求处该坐标对应原图像 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)=(10.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)=(10.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]))
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值