图像的缩放变换

在日常工作中,我们经常需要对图像进行缩放(放大、缩小),旋转平移等各种操作,这类操作统称为图像的几何变换。相对于前面提到的灰度变换,几何变换是改变了原图像像素点在新图像中的空间位置。

我们首先来看看图像缩放操作。假设一幅图像是100×100像素大小,放大一倍后是200×200大小。图像中的每一个像素点位置可以看作是一个点,也可以看作是二维平面上的一个矢量。图像缩放,本质上就是将每个像素点的矢量进行缩放,也就是将矢量x方向和y方向的坐标值缩放。也就是[x, y]变成了 [kxx,kyy] [ k x ⋅ x , k y ⋅ y ] ,一般情况下 kx=ky k x = k y ,但是很多时候也不相同,例如将100×100的图像变成400×300的图像。学过线性代数的同学很快就能知道,这可以表示成矩阵乘法的形式:

[uv]=[kx00ky][xy](5) (5) [ u v ] = [ k x 0 0 k y ] [ x y ]

通过上述矩阵乘法的形式,我们就把原图像上的每一个像素点映射到新图像上相应的像素点了,这称为前向映射

但是,我们很快注意到,原始图像有100×100=10000个像素点,而变换后的图像是200×200=40000个像素点。纵使把原始图像的10000个像素点全部映射到新图像上的对应点上,新图像上仍然有40000-10000=30000个点没有与原图像进行对应,那这30000个像素点的灰度值从何而来呢?

我们把上面的矩阵表达式稍微转换下,两边乘以放大矩阵的逆矩阵:

[kx00ky]1[uv]=[xy](6) (6) [ k x 0 0 k y ] − 1 [ u v ] = [ x y ]

通过上面的式子,我们可以将新图像中的每一个像素点[u, v]与原图像中的一个像素点[x, y]对应起来了。这称为 后向映射。显然后向映射比前向映射更有效。

import cv2
import numpy as np

lenna100 = cv2.imread("lenna100.png", 0)
row, col = lenna100.shape
kx, ky = 2, 2
A = np.mat([[kx, 0], [0, ky]])
lenna200 = np.zeros((kx * row, ky * col))

for r in range(kx * row):
    for l in range(ky * col):
        v = np.dot(A.I, np.array([r, l]).T)
        lenna200[r, l] = lenna100[int(v[0, 0]), int(v[0, 1])]

cv2.imshow("lenna100", lenna100)
cv2.imshow("lenna200", lenna200.astype("uint8"))
cv2.waitKey()

图像的缩放变换_第1张图片

你可能感兴趣的:(图像处理与OpenCV)