Jupyter AI

8 几何变换之仿射变换与投影变换

📅 发表日期: 2024年8月11日

分类: 🖼️计算机图形学入门

👁️阅读: --

在计算机图形学中,几何变换是将物体从一个空间位置转换到另一个空间位置的方法。在上一篇中,我们详细讨论了平移、旋转与缩放等基本几何变换。而在本篇中,我们将深入探讨 仿射变换投影变换

仿射变换

什么是仿射变换?

仿射变换 是一种更为广泛的变换,能够保持点、直线和面之间的关系。具体来说,仿射变换不仅可以进行平移、旋转和缩放,还允许进行剪切操作。仿射变换可被描述为以下数学形式:

[xy1]=[abtxcdty001][xy1]\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} a & b & tx \\ c & d & ty \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}

其中,[xy1]\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} 是变换后的坐标,a,b,c,da, b, c, d 描述了线性变换的部分,tx,tytx, ty 是平移量。

仿射变换的示例

考虑一个简单的例子,我们有一个正方形的顶点坐标:

  • A(1, 1)
  • B(1, 3)
  • C(3, 3)
  • D(3, 1)

我们希望对它进行 平移缩放,具体变换矩阵如下:

[201021001]\begin{bmatrix} 2 & 0 & 1 \\ 0 & 2 & 1 \\ 0 & 0 & 1 \end{bmatrix}

在这里,我们对x坐标进行2倍缩放,并对每个点进行平移1个单位。

代码示例

以下是用 Python 结合 NumPy 实现仿射变换的代码示例:

import numpy as np
import matplotlib.pyplot as plt

# 定义正方形的顶点
square = np.array([[1, 1, 1],
                   [1, 3, 1],
                   [3, 3, 1],
                   [3, 1, 1],
                   [1, 1, 1]])  # 闭合的正方形

# 定义仿射变换矩阵
transform_matrix = np.array([[2, 0, 1],
                              [0, 2, 1],
                              [0, 0, 1]])

# 执行仿射变换
transformed_square = square @ transform_matrix.T

# 绘制原始正方形和变换后的正方形
plt.figure()
plt.plot(square[:, 0], square[:, 1], label='Original Square', marker='o')
plt.plot(transformed_square[:, 0], transformed_square[:, 1], label='Transformed Square', marker='x')
plt.axis('equal')
plt.legend()
plt.title("Affine Transformation")
plt.grid()
plt.show()

投影变换

什么是投影变换?

投影变换 是将三维物体映射到二维平面上的一种变换。投影变换会将物体的深度信息进行压缩,其通用矩阵形式如下所示:

[xyw]=[f000f0001][xyz]\begin{bmatrix} x' \\ y' \\ w \end{bmatrix} = \begin{bmatrix} f & 0 & 0 \\ 0 & f & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix}

这里,ff 是焦距,ww 是齐次坐标的维度。

投影变换的示例

假设我们有一个三角形在三维空间中的顶点坐标为:

  • P1(1, 1, 1)
  • P2(1, -1, 1)
  • P3(-1, -1, 1)

我们想要将这个三角形投影到二维平面上。

代码示例

以下是三维到二维投影的代码示例:

# 定义三角形的顶点
triangle_3d = np.array([[1, 1, 1],
                         [1, -1, 1],
                         [-1, -1, 1],
                         [1, 1, 1]])  # 闭合的三角形

# 定义投影矩阵
focal_length = 1
projection_matrix = np.array([[focal_length, 0, 0],
                               [0, focal_length, 0],
                               [0, 0, 1]])

# 执行投影变换
projected_triangle = triangle_3d @ projection_matrix.T

# 归一化到二维
projected_triangle /= projected_triangle[:, 2].reshape(-1, 1)

# 绘制投影后的三角形
plt.figure()
plt.plot(projected_triangle[:, 0], projected_triangle[:, 1], label='Projected Triangle', marker='o')
plt.axis('equal')
plt.legend()
plt.title("Projection Transformation")
plt.grid()
plt.show()

总结

在本篇中,我们介绍了 仿射变换投影变换 的基本概念和实现。仿射变换 通过统一的矩阵表示多种变换,而 投影变换 则负责将三维场景映射到二维空间。通过实际案例和代码示例,我们能够更直观地理解这些变换的操作及其效果。

在下一篇中,我们将深入探讨 齐次坐标,这一重要概念将为我们提供更强大的变换工具。