备注
前往结尾 下载完整示例代码。或者通过 Binder 在浏览器中运行此示例。
使用几何变换#
在这个例子中,我们将看到如何在图像处理的背景下使用几何变换。
import math
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage import transform
基础#
支持几种不同的几何变换类型:相似性、仿射、投影和多项式。有关可用变换类型的教程,请参见 单应性类型。
几何变换可以通过显式参数(例如缩放、剪切、旋转和平移)或变换矩阵来创建。
首先,我们使用显式参数创建一个转换:
tform = transform.SimilarityTransform(scale=1, rotation=math.pi / 2, translation=(0, 1))
print(tform.params)
[[ 6.123234e-17 -1.000000e+00 0.000000e+00]
[ 1.000000e+00 6.123234e-17 1.000000e+00]
[ 0.000000e+00 0.000000e+00 1.000000e+00]]
或者,您可以通过变换矩阵本身来定义一个变换:
matrix = tform.params.copy()
matrix[1, 2] = 2
tform2 = transform.SimilarityTransform(matrix)
这些变换对象随后可以用于在源坐标系和目标坐标系之间应用正向和逆向坐标变换:
[[6.123234e-17 3.000000e+00]]
[[ 0.000000e+00 -6.123234e-17]]
图像扭曲#
几何变换也可以用来扭曲图像:
text = data.text()
tform = transform.SimilarityTransform(
scale=1, rotation=math.pi / 4, translation=(text.shape[0] / 2, -100)
)
rotated = transform.warp(text, tform)
back_rotated = transform.warp(rotated, tform.inverse)
fig, ax = plt.subplots(nrows=3)
ax[0].imshow(text, cmap=plt.cm.gray)
ax[1].imshow(rotated, cmap=plt.cm.gray)
ax[2].imshow(back_rotated, cmap=plt.cm.gray)
for a in ax:
a.axis('off')
plt.tight_layout()
参数估计#
除了上述基本功能外,您还可以使用最小二乘法估计几何变换的参数。
这可以用于图像配准或校正,其中您在两幅图像中有一组控制点或同源/对应点。
假设我们想要识别一张照片上的字母,这张照片不是从正面拍摄的,而是从一个特定的角度拍摄的。在最简单的情况下,平面纸张表面的字母是投影变形的。简单的匹配算法将无法匹配这些符号。解决这个问题的一个方法是对图像进行扭曲,以消除变形,然后应用匹配算法:
text = data.text()
src = np.array([[0, 0], [0, 50], [300, 50], [300, 0]])
dst = np.array([[155, 15], [65, 40], [260, 130], [360, 95]])
tform3 = transform.ProjectiveTransform()
tform3.estimate(src, dst)
warped = transform.warp(text, tform3, output_shape=(50, 300))
fig, ax = plt.subplots(nrows=2, figsize=(8, 3))
ax[0].imshow(text, cmap=plt.cm.gray)
ax[0].plot(dst[:, 0], dst[:, 1], '.r')
ax[1].imshow(warped, cmap=plt.cm.gray)
for a in ax:
a.axis('off')
plt.tight_layout()
plt.show()
上述估计依赖于对点位置的准确知识及其对应关系的准确选择。如果点的位置存在不确定性,则可以提供权重,使得最终的变换优先考虑那些具有最高权重的点的准确拟合。另一种称为 RANSAC算法 的方法在对应点不完全准确时非常有用。有关如何在scikit-image中使用这种方法的深入描述,请参阅 使用 RANSAC 进行鲁棒匹配 教程。
脚本总运行时间: (0 分钟 0.144 秒)