目录
4.1针孔照相机模型
对于大多数应用来说,针孔照相机模型简单,并且具有足够的精确度。该照相机从一个小孔采集射到暗箱内部的光线。 在针孔照相机模型中,在光线投影到图像平面之前,从唯一一个点经过,也就是照相机中心 C。
在针孔照相机中,三维点 X
投影为图像点
x
(两个点都是用齐次坐标表示的),如下
所示:
4.1.1照相机矩阵
照相机矩阵可以分解为:。
其中,R 是描述照相机方向的旋转矩阵,t 是描述照相机中心位置的三维平移向量,内标定矩阵 K 描述照相机的投影性质。
图像平面和照相机中心间的距离为焦距
f
。当像素数组在传感器上偏斜的时候,需要
用到倾斜参数
s。即:
4.1.2 三维点的投影
下面来创建照相机类,用来处理我们对照相机和投影建模所需要的全部操作:
实验代码:
import numpy as np
from scipy import linalg
import matplotlib.pyplot as plt
class Camera(object):
""" 表示针孔照相机的类 """
def __init__(self, P):
""" 初始化 P = K[R|t] 照相机模型 """
self.P = P
self.K = None # 标定矩阵
self.R = None # 旋转
self.t = None # 平移
self.c = None # 照相机中心
def project(self, X):
""" X(4×n 的数组)的投影点,并且进行坐标归一化 """
x = np.dot(self.P, X)
x /= x[2] # 归一化
return x
def generate_random_rotation_matrix():
""" 生成一个随机旋转矩阵 """
theta = np.random.uniform(0, 2 * np.pi)
phi = np.random.uniform(0, np.pi)
z = np.random.uniform(0, 2 * np.pi)
Rz = np.array([[np.cos(z), -np.sin(z), 0],
[np.sin(z), np.cos(z), 0],
[0, 0, 1]])
Ry = np.array([[np.cos(phi), 0, np.sin(phi)],
[0, 1, 0],
[-np.sin(phi), 0, np.cos(phi)]])
Rx = np.array([[1, 0, 0],
[0, np.cos(theta), -np.sin(theta)],
[0, np.sin(theta), np.cos(theta)]])
R = np.dot(Rz, np.dot(Ry, Rx))
return R
# 生成随机三维点
np.random.seed(0) # 固定随机种子以确保实验可重复
n_points = 100
X = np.vstack((np.random.rand(3, n_points), np.ones(n_points))) # 4 × n 的点
# 生成相机投影矩阵
K = np.eye(3)
R = np.eye(3)
t = np.array([[0], [0], [-5]])
P = np.hstack((R, t)) # 形成 K[R|t] 矩阵
camera = Camera(P)
# 投影点
projected_points = camera.project(X)
# 画图
plt.figure(figsize=(10, 8))
plt.scatter(projected_points[0], projected_points[1], c='blue', label='Original Projection')
# 随机旋转并投影
n_rotations = 5
for i in range(n_rotations):
R_random = generate_random_rotation_matrix()
P_random = np.hstack((R_random, t)) # 使用相同的平移
camera.P = P_random
rotated_projected_points = camera.project(X)
plt.scatter(rotated_projected_points[0], rotated_projected_points[1], label=f'Rotation {i + 1}')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Projection of 3D Points with Different Random Rotations')
plt.legend()
plt.grid(True)
plt.show()
分析:
-
生成三维点:
- 随机生成了 100 个三维点,使用
np.vstack
将其转换为 4 × n 的齐次坐标形式。
- 随机生成了 100 个三维点,使用
-
生成相机投影矩阵:
- 这里我们使用单位矩阵作为标定矩阵和旋转矩阵,同时设置一个简单的平移。
-
投影和绘图:
- 初次投影后的点用蓝色显示。
- 对每个随机生成的旋转矩阵