import numpy as np
import cv2
# ========== 1. 定义内参矩阵 K ==========
# 假设相机焦距 fx=fy=500 像素,图像中心在 (320, 240)
K = np.array([[500, 0, 320],
[ 0, 500, 240],
[ 0, 0, 1]], dtype=np.float32)
# ========== 2. 定义外参 R 和 T ==========
# 假设相机没有旋转(单位矩阵),向右平移 10 个单位,向前 5 个单位
R = np.eye(3, dtype=np.float32) # 无旋转
T = np.array([10, 0, 5], dtype=np.float32) # 平移向量
# 组合成外参矩阵 [R | T] → 3x4
RT = np.hstack((R, T.reshape(3, 1))) # shape: (3, 4)
# ========== 3. 定义一个世界坐标点 ==========
# 例如:空间中一个点 (X=2, Y=3, Z=10)
P_world = np.array([2, 3, 10, 1], dtype=np.float32) # 齐次坐标
# ========== 4. 投影到图像平面 ==========
# 先用外参变换到相机坐标系
P_camera = RT @ P_world # shape: (3,)
# 再用内参投影到图像(像素坐标)
p_homogeneous = K @ P_camera # shape: (3,)
# 转换为非齐次坐标 (u, v)
u = p_homogeneous[0] / p_homogeneous[2]
v = p_homogeneous[1] / p_homogeneous[2]
print(f"投影后的像素坐标: u={u:.2f}, v={v:.2f}")
# 输出示例: u=370.00, v=255.00
实际应用中怎么获得内参和外参?
内参:通过“相机标定”获得
用棋盘格标定板 + 多张照片 → OpenCV 自动计算内参和畸变系数。
# 示例:标定相机(简化版)
import cv2
import numpy as np
# 准备标定板角点的世界坐标(假设 Z=0)
objp = np.zeros((6*9, 3), np.float32)
objp[:, :2] = np.mgrid[0:9, 0:6].T.reshape(-1, 2)
objpoints = [] # 3D 点
imgpoints = [] # 2D 点
# 假设你有若干张标定图像
images = ["calib1.jpg", "calib2.jpg", ...]
for img_path in images:
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, (9,6), None)
if ret:
objpoints.append(objp)
imgpoints.append(corners)
# 相机标定 → 得到内参、畸变系数、外参(每张图的)
ret, K, dist, rvecs, tvecs = cv2.calibrateCamera(
objpoints, imgpoints, gray.shape[::-1], None, None
)
print("内参矩阵 K:\n", K)
print("畸变系数:\n", dist)
外参:标定过程中每张图都会得到一个外参(R 和 T)
rvecs
:旋转向量(需用cv2.Rodrigues()
转成旋转矩阵 R)tvecs
:平移向量 T# 将旋转向量转为旋转矩阵 R, _ = cv2.Rodrigues(rvecs[0]) # 第一张图的旋转矩阵 T = tvecs[0].flatten() # 第一张图的平移向量 print("第一张图的外参 R:\n", R) print("第一张图的外参 T:\n", T)