我正在尝试找到相机相对于棋盘的位置(或者反过来)- 我觉得在不同坐标系之间转换没问题,例如建议在这里。我决定在此阶段不仅用棋盘进行校准,而且还要确定实际位置,因为我可以使用findChessboardCorners
获取imagePoints
(这个方法工作正常)。
我已经阅读了很多关于这个主题的文章,并且认为我理解solvePnP
的输出(尽管我完全是新手openCV
和计算机视觉)。不幸的是,从solvePnP
获得的结果和物理测量测试设置的结果不同:z方向上的平移偏差约为25%。x
和y
方向完全错误 - 比我所阅读的相机坐标系(x指向图像上方,y向右,z远离相机)高几个数量级并且方向不同。如果我将tvec
和rvec
转换为相机在世界坐标系中的位置,差异仍然存在。
我的问题是:
- 相机和世界坐标系的轴方向是什么?
solvePnP
输出的平移是否与我指定的objectPoints
具有相同的单位?- 我将世界原点指定为
objectPoints
的第一个点(其中一个棋盘角落)。这样做可以吗?tvec
是到达该点的平移向量,从相机坐标开始?
这是我的代码(我以纯文本形式附加它,因为它不会引发任何异常等)。我使用灰度图像获取相机内部矩阵和畸变系数进行校准,因此决定在灰度下执行本地化。 chessCoordinates
是棋盘点相对于原点(其中一个角点)在毫米中的位置列表。 camMatrix
和distCoefficients
来自校准(使用相同的棋盘和objectPoints
执行)。
camCapture=cv2.VideoCapture(0) # Take a picture of the target to get the imagePoints
tempImg=camCapture.read()
imgPts=[]
tgtPts=[]
tempImg=cv2.cvtColor(tempImg[1], cv2.COLOR_BGR2GRAY)
found_all, corners = cv2.findChessboardCorners(tempImg, chessboardDim )
imgPts.append(corners.reshape(-1, 2))
tgtPts.append(np.array(chessCoordinates, dtype=np.float32))
retval,myRvec,myTvec=cv2.solvePnP(objectPoints=np.array(tgtPts), imagePoints=np.array(imgPts), cameraMatrix=camMatrix, distCoeffs=distCoefficients)