我正在尝试创建结构光三维扫描仪。
相机标定
相机标定是OpenCV官方教程的副本。结果,我有了相机内部参数(相机矩阵
)。
投影仪标定
投影仪标定可能不正确,但是过程是:投影仪显示棋盘图案,摄像机从不同角度拍摄一些照片。使用相机参数对图像进行cv.undistored,然后使用OpenCV官方教程对结果图像进行校准。结果,我有了投影仪内部参数(投影仪矩阵
)。
旋转和平移
从cv.calibrate
中,我得到旋转和平移向量作为结果,但向量数目与图像数目相同,我认为这不是正确的,因为我在标定时移动了相机和投影仪。我的新想法是在扫描背景上投影棋盘,进行校准,这样我将获得旋转向量
和平移向量
。我不知道这是否是正确的方法。
扫描
扫描过程如下:
生成图案->使用投影仪矩阵
对图案进行畸变校正->投影图案并使用相机拍摄照片->使用相机矩阵
对拍摄的照片进行畸变校正
相机-投影仪像素映射
我使用GrayCode图案,并使用cv.graycode.getProjPixel,在相机和投影仪之间获得了像素映射
。我的投影仪分辨率不是很高,最后的图案不是很清晰。我将创建自定义函数,生成没有最后几个图案的映射。
问题
我不知道如何从所有这些信息中获得深度图
(Z
)。我的困惑在于有3个坐标系-相机、投影仪和世界坐标系。
如何使用代码找到'Z'?我是否可以从图像和图案之间的像素映射
中仅获取Z
?
已有的信息:
p(x,y,1) = R*q(x,y,z) + T
- 这里p
是图像点,q
是真实世界的点(可能是三维坐标),R
和T
是旋转向量和平移向量。如何找到R
和T
?Z = B.f/(x-x')
- 这里Z
是深度坐标,B
是基线(摄像机和投影仪之间的距离),我可以用手测量它,但这可能不是最好的方法,(x-x')
是摄像机像素和投影仪像素之间的距离。我不知道如何得到基线。也许这就是平移向量
?- 我尝试获取4个有意义的点,将它们用在cv.getPerspectiveTransform中,并使用此结果在cv.reprojectImageTo3D中使用。但是
cv.getPerspectiveTransform
返回3x3矩阵,而cv.reprojectImageTo3D
使用Q-4×4透视变换矩阵,可以通过
stereoRectify获得。
类似的问题:
- 如何从结构光3D扫描获取点云数据? - 答案是
您需要定义一个向量,该向量从相机透视中心到图像中的像素,并将此向量旋转相机旋转
。但我不知道如何定义/找到这个向量,需要旋转向量
。 - 如何计算两个摄像机之间的旋转和平移? - 问题是关于两个摄像机之间的R和T,但几乎所有地方都写道投影仪是相机的反向。一个好的答案是
您唯一需要做的就是确保校准棋盘由两个摄像机看到。
但我认为如果我投影棋盘图案,它将被墙壁额外扭曲(射影变换)。
还有许多其他资源,我会在评论中更新列表。我错过了一些东西,也不知道如何实现它。