我在互联网上看到很多关于如何使用openCV进行相机+投影仪校准的博客条目和视频以及来源,以生成camera.yml
,projector.yml
和{{1}文件。
之后我还没有看到有人讨论如何处理这些文件。事实上,我自己做过校准,但我不知道自己应用程序的下一步是什么。
假设我编写了一个应用程序,现在使用相机 - 我校准的投影仪系统来跟踪对象并在其上投影。我将使用contourFind()从移动物体中抓取一些感兴趣的点,现在我想将这些点(从投影仪!)投射到物体上!
我想要做的是(例如)跟踪对象的质心(COM)并在跟踪对象的摄像机视图上显示一个点(在其COM处)。然后应该在物体的COM上实时投射一个点。
似乎projectorExtrinsics.yml
是我在加载yml文件后应该使用的openCV函数,但我不确定如何解释所有内在&相机和投影仪的外在校准值。即,projectPoints()
需要
所以如果我在projectPoints()
中使用投影仪或相机(哪一个?)内在函数+系数,那么我只会'纠正'2个乐器中的一个。我在哪里/如何使用对方的内在函数??
除了projectPoints()
yml文件和load()
之外还需要使用什么? (也许是不成比例的?)
非常感谢任何有关此事的帮助。 如果有教程或书籍(不,O'Reilly“学习openCV”也没有谈论如何使用校准yml文件! - 仅关于如何进行实际校准),请指出我的方向。我不一定需要一个确切的答案!
答案 0 :(得分:4)
首先,您似乎对相机/投影仪模型的一般作用感到困惑:它的作用是将3D世界点映射到2D图像点。这听起来很明显,但这意味着给定外在函数R,t(用于方向和位置),失真函数D(。)和内在函数K,你可以推断这个特定的相机的2D投影m 3D点M如下:m = KD(R.M + t)。对于每个输入3D点,projectPoints
函数完全(即3D到2D投影),因此您需要为提供与您想要投射3D点的相机相关的输入参数(投影机K& D,如果你想要投影机2D坐标,相机K& D,如果你想要相机2D坐标)。
其次,当您联合校准您的相机和投影仪时,您不会估计相机的一组外部物质R,t和投影机的另一个外部物质,但只有一个R和一个t,它们代表旋转和平移在相机和投影仪的坐标系之间。例如,这意味着假设您的相机具有rotation = identity和translation = 0,并且投影机的旋转= R且平移= t(或者相反,取决于您进行校准的方式)。
现在,关于你提到的应用,真正的问题是:你如何估计给定点的3D坐标?
使用两个摄像头和一个投影仪,这很容易:您可以跟踪两个摄像头图像中感兴趣的对象,使用函数{{1}使用两个2D投影对其三维位置进行三角测量最后使用triangulatePoints
在投影机2D坐标中投影此3D点,以便了解投影机的显示位置。
只有一台摄像机和一台投影机,这仍然是可能的,但更难,因为您无法仅通过一次观察对跟踪点进行三角测量。基本思想是像稀疏立体视差估计问题一样处理问题。可能的方法如下:
使用投影仪投影非模糊图像(例如黑白噪点),以便对相机观察到的场景进行纹理处理。
和以前一样,跟踪相机图像中感兴趣的对象
对于每个感兴趣的对象,将其在摄像机图像中的位置周围的小窗口与投影仪图像相关联,以便找到它在投影仪中投影的位置2D坐标
与上述方法不同的另一种方法是使用校准参数,可以使用projectPoints
和stereoRectify
(或StereoBM::operator()
进行GPU实现的密集3D重建),使用估计的场景深度将跟踪的2D位置映射到3D,最后使用gpu::StereoBM_GPU::operator()
投影到投影仪。
无论如何,使用两台相机更容易,也更准确。
希望这有帮助。