关于cv2.triangulatePoints()输出单位及立体相机三角化相关问题的咨询
Hey there, let's walk through your setup and address the unspoken questions you probably have (since your message cuts off at "I know..."):
先梳理下你的现有流程(确认我没理解错)
- 你搭了一套双目相机系统,俩相机垂直摆放但都对准同一个中心
- 已经完成单目标定和立体标定,用的是13cm×13cm的ChArUco板,立体标定误差约1.39像素——不过你提到自己没指定棋盘格的实际单位大小,这可能是个关键细节
- 之后用同步采集的视频跟踪目标,按标准流程做了三角化:先对左右相机的2D点去畸变,以左相机为世界坐标系原点构建投影矩阵,右相机用
K2 [R | t]作为投影矩阵,调用三角化函数后转成世界坐标并完成绘图
核心问题拆解(针对你大概率关心的标定、三角化单位问题)
1. 标定环节的“单位”误区
敲黑板!你说用了13cm的ChArUco板但“没指定单位”——这里要明确:OpenCV的cv2.stereoCalibrate()是需要你传入实际物理尺寸的3D参考点的。比如你得把ChArUco板的某个角设为(0,0,0),相邻角点设为(13,0,0)(单位:cm),这样标定得到的R、t这些参数才是基于厘米单位的。
如果你标定时只传入了相对坐标(比如(0,0,0), (1,0,0), (2,0,0)这种整数),那OpenCV会把“1”当成一个单位,这个单位对应的实际物理长度就是你的ChArUco板边长——也就是13cm,但OpenCV自己不知道这个比例,所以后续所有结果的单位都是“1个棋盘格边长”。
2. cv2.triangulatePoints()的输出单位
这个函数输出的是齐次坐标(X,Y,Z,W),你转成世界坐标时应该是做了X/W, Y/W, Z/W对吧?这个结果的单位完全由你立体标定时传入的3D参考点单位决定:
- 如果标定时给的3D点是厘米单位,那三角化结果的单位就是厘米
- 如果标定时用的是“棋盘格格数”作为单位,那结果的单位就是13cm,你需要手动把结果乘以13才能得到实际厘米数
3. 你的三角化流程是否正确?
从描述来看,你的流程是完全标准的:
- 以左相机为世界原点,投影矩阵
P1 = K1 [I | 0] - 右相机投影矩阵用
P2 = K2 [R | t] - 去畸变后再三角化,最后转成非齐次世界坐标
而且立体标定误差1.39像素是个很不错的结果,说明相机参数校准得很到位,这会让三角化结果的准确性有保障。
如果你的“I know...”后面是想说结果和实际目标尺寸不符、或者对单位有疑惑,那大概率就是标定环节没把3D参考点的实际物理单位传对——只要补全这个步骤,重新做标定和三角化,结果的单位就会和你设定的物理单位一致了。
备注:内容来源于stack exchange,提问作者Adeu

