![Python图像处理经典实例](https://wfqqreader-1252317822.image.myqcloud.com/cover/443/46424443/b_46424443.jpg)
1.4 应用透视变换和单应性变换
透视(投影)变换的目标是从两个图像之间的点对应估算单应性矩阵(矩阵H)。由于矩阵的景深(DOF)为8,因此至少需要4对匹配点来计算两幅图像的单应性矩阵。计算单应性矩阵所需要的基本概念如图1-6所示。
幸运的是,读者不需要计算奇异值分解(SVD),并且矩阵H也是通过scikit-image库的transform模块中的ProjectiveTransform()函数自动计算的。在本实例中,我们会用该函数来计算单应性矩阵。
![](https://epubservercos.yuewen.com/E26B6A/25643742509453806/epubprivate/OEBPS/Images/1-6.jpg?sign=1738987737-fOgKkWk7z6AU2hhff1riQvFgQSQ9T5za-0-9c2691c2a3901ceac01b6dc64d272f32)
图1-6
1.4.1 准备工作
在该实例中,我们会用到一幅“蜂鸟”图像和一幅“月球上的宇航员”图像。我们还是按照常规的做法,先导入所需要的Python库:
from skimage.transform import ProjectiveTransform from skimage.io import imread import numpy as np import matplotlib.pylab as plt
1.4.2 执行步骤
使用scikit-image库的transform 模块,我们执行以下步骤,来对图像应用投影变换。
1.首先读取源图像,并使用np.zeros()函数创建目标图像:
im_src = (imread('images/humming2.png')) height, width, dim = im_src.shape im_dst = np.zeros((height, width, dim))
2.创建一个ProjectiveTransform类的实例:
pt = ProjectiveTransform()
3.要自动估算单应性矩阵H,只需在源图像和目标图像之间提供4对匹配点。在这里,我们将目标图像的4个拐角点和输入蜂鸟图像的4个拐角点作为匹配点,如下所示:
src = np.array([[ 295., 174.], [ 540., 146. ], [ 400., 777.], [ 60., 422.]]) dst = np.array([[ 0., 0.], [height-1, 0.], [height-1, width-1], [ 0., width-1]])
4.获取目标图像中每个像素索引所对应的源图像像素索引:
x, y = np.mgrid[:height, :width] dst_indices = np.hstack((x.reshape(-1, 1), y.reshape(-1,1))) src_indices = np.round(pt.inverse(dst_indices), 0).astype(int) valid_idx = np.where((src_indices[:,0] < height) & (src_indices[:,1] < width) & (src_indices[:,0] >= 0) & (src_indices[:,1] >=0)) dst_indicies_valid = dst_indices[valid_idx] src_indicies_valid = src_indices[valid_idx]
5.把像素从源图像复制到目标图像:
im_dst[dst_indicies_valid[:,0],dst_indicies_valid[:,1]] = im_src[src_indicies_valid[:,0],src_indicies_valid[:,1]]
运行上述代码,输出如图1-7所示。
![](https://epubservercos.yuewen.com/E26B6A/25643742509453806/epubprivate/OEBPS/Images/1-7.jpg?sign=1738987737-xh29snm60loN5g5t5EO5HEM61edoZk1d-0-946f4f79ee987cccb1936968e9048e79)
图1-7
图1-8所示的是“月球上的宇航员”的源图像和显示在画布上的目标图像。通过在源图像(拐角点)和画布上的目标图像(拐角点)之间给出4对匹配点,该操作执行起来非常简单。
![](https://epubservercos.yuewen.com/E26B6A/25643742509453806/epubprivate/OEBPS/Images/1-8.jpg?sign=1738987737-WVm2rOc0cFzB4tCanKvC4yL87F686swp-0-74f3f2f45e6ca6de5ac72bed63711a5e)
图1-8
执行投影变换后的输出图像如图1-9所示。
![](https://epubservercos.yuewen.com/E26B6A/25643742509453806/epubprivate/OEBPS/Images/1-9.jpg?sign=1738987737-heku8PA28MDeRORRuYwJi6kR2dKg74mZ-0-f3652dc2d67a68601dffc069b602c16b)
图1-9
1.4.3 工作原理
在上述两种情况下,输入图像被投影到输出图像的理想位置。为了对图像应用透视变换,我们首先需要创建ProjectiveTransform对象。
我们需要将源图像中的一组4像素位置和相应的目标图像中匹配的4像素位置连同ProjectiveTransform对象实例一起传递给estimate()函数,后者将计算单应性矩阵H(如果单应性矩阵H可通过计算得到,则函数返回True)。
在ProjectiveTransform对象上调用inverse()函数,该函数将提供与所有目标像素索引相对应的源像素索引。
1.4.4 更多实践
warp()函数(而不是inverse()函数)可以用于实现单应性/投影变换。