我试图找到相机相对于棋盘的相对位置(或者相反的方向) - 我觉得在不同的坐标系之间进行转换,例如按照建议here。我决定在这个阶段使用棋盘不仅用于校准,还用于实际位置确定,因为我可以使用findChessboardCorners
来获取imagePoints
(这样可以正常工作)。
我已经阅读了很多关于这个主题的内容,觉得我理解solvePnP
输出(即使我对openCV
和计算机视觉一般都是新手)。不幸的是,我从solvePnP
得到的结果和物理测量测试设置的结果是不同的:z方向的平移偏差大约。 25%。 x
和y
方向是完全错误的 - 几个数量级和不同的方向比我读到的相机坐标系(x指向图像,y向右,z远离相机)。如果我将tvec
和rvec
转换为世界坐标中的相机姿势,则差异仍然存在。
我的问题是:
solvePnP
是否以与我指定objectPoints
相同的单位输出翻译?objectPoints
(棋盘角落之一)中的第一个。可以,并且tvec
从相机坐标转换到那个点吗?这是我的代码(我附上 pro forma ,因为它不会抛出任何异常等)。我使用灰度图像来获取校准期间的相机内在矩阵和失真系数,因此决定以灰度级执行本地化。 chessCoordinates
是相对于原点(角点之一)的以mm为单位的棋盘点位置列表。 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)
答案 0 :(得分:10)
相机坐标与图像坐标相同。所以你有x ax指向相机的右侧,y ax指向下方,z指向相机所面对的方向。这是一个顺时针斧系统,同样适用于棋盘,所以如果你指定原点,比如棋盘的右上角,x轴沿着较长的一侧向右,y沿着较短的一侧。棋盘,z ax将向下指向地面。
解决PnP以与您指定棋盘字段长度的单位相同的单位输出平移,但它也可能使用相机校准中指定的单位,因为它使用相机矩阵。
Tvec指向您放置校准对象的世界坐标的原点。因此,如果您将第一个对象点放在(0,0)中,那么tvec将指向。
答案 1 :(得分:3)
相机和世界坐标系轴的方向是什么?
电路板上的0,0,0角是X& Y轴朝向其余角点。 Z轴始终指向远离电路板。这意味着它通常指向相机的方向。
solvePnP是否以与指定objectPoints相同的单位输出翻译?
是
我将世界原点指定为objectPoints中的第一个(棋盘角之一)。这样就可以了吗?从摄像机坐标转换到那个点?
是的,这很常见。在大多数情况下,第一个凸轮角设置为0,0,0,后续角设置为z = 0平面(例如;(1,0,0),(0,1,0)等)
tvec与旋转相结合,指向从板坐标框架到相机的那个点。简而言之; tvec& rvec为您提供反向翻译(世界 - >相机)。使用一些基本几何图形,您可以计算放置相机的转换 - >世界。