图像缩放后内参按比例调整,为何重建3D点坐标不一致?
图像缩放后3D重建坐标不一致的原因
已知图像缩放后,相机内参K会按对应比例调整,但同一点的3D重建坐标却出现差异。以下是Python验证实验:原图像尺寸为1920×1080(宽×高),缩放后为640×480,K1对应原图内参,K2对应缩放后内参,相机外参RT1、RT2保持不变,忽略倾斜因子与畸变影响,实验代码及结果如下:
import cv2 import numpy as np fx = 1040 fy = 1040 cx = 1920 / 2 cy = 1080 / 2 K1 = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]]) RT1 = np.array([[1, 0, 0, 4], [0, 1, 0, 5], [0, 0, 1, 6]]) # 随机设置外参 theta = np.pi / 6 RT2 = np.array([[np.cos(theta), -np.sin(theta), 0, 40], [np.sin(theta), np.cos(theta), 0, 50], [0, 0, 1, 60]]) # 随机设置外参 p1 = np.matmul(K1, RT1) # 投影矩阵 p2 = np.matmul(K1, RT2) # 投影矩阵 pt1 = np.array([100.0, 200.0]) pt2 = np.array([300.0, 400.0]) point3d1 = cv2.triangulatePoints(p1, p2, pt1, pt2) # 齐次坐标归一化 point3d1 = point3d1 / point3d1[3] print(point3d1)
运行结果:
[[-260.07160113] [ -27.39546108] [ 273.95189881] [ 1. ]]
随后进行图像缩放后的3D点重建测试:
rx = 640.0 / 1920.0 ry = 480.0 / 1080.0 fx = fx * rx fy = fy * ry cx = cx * rx cy = cy * ry K2 = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]]) p1 = np.matmul(K2, RT1) p2 = np.matmul(K2, RT2) pt1 = np.array([pt1[0] * rx, pt1[1] * ry]) pt2 = np.array([pt2[0] * rx, pt2[1] * ry]) point3d2 = cv2.triangulatePoints(p1, p2, pt1, pt2) # 齐次坐标归一化 point3d2 = point3d2 / point3d2[3] print(point3d2)
运行结果:
[[-193.03965985] [ -26.72133393] [ 189.12512305] [ 1. ]]
可见两次重建的3D点存在明显差异,原因如下:
核心原因:x、y方向缩放比例不一致
原图像宽1920、高1080,缩放后宽640、高480,计算得:
- x方向缩放比例
rx = 640/1920 = 1/3 ≈ 0.333 - y方向缩放比例
ry = 480/1080 = 4/9 ≈ 0.444
两个方向的缩放比例不相等,导致以下问题:
- 投影矩阵的行缩放比例失衡:相机投影矩阵
P = K * RT,其中K的x行(fx、cx)乘以rx,y行(fy、cy)乘以ry,使得P的x行和y行缩放比例不同,破坏了投影变换的一致性。 - 三角化的权重偏差:
cv2.triangulatePoints本质是通过最小化重投影误差求解3D点,当x、y方向缩放比例不同时,相当于对x和y方向的观测赋予了不同的权重,最终求解出的3D点会偏离真实值。
验证:等比例缩放时结果一致
如果将图像按等比例缩放,比如统一使用rx=1/3,此时缩放后图像尺寸为640×360,修改代码中ry为1/3,重新运行会发现两次重建的3D点几乎完全一致(浮点精度范围内)。
内容的提问来源于stack exchange,提问作者cui xingxing
相关产品推荐
相关产品推荐

