如何在相机 - 投影仪系统中重新投影点(校准后)

时间:2014-03-10 00:11:53

标签: c++ opencv camera projection

我在互联网上看到很多关于如何使用openCV进行相机+投影仪校准的博客条目和视频以及来源,以生成camera.ymlprojector.yml和{{1}文件。

之后我还没有看到有人讨论如何处理这些文件。事实上,我自己做过校准,但我不知道自己应用程序的下一步是什么。

假设我编写了一个应用程序,现在使用相机 - 我校准的投影仪系统来跟踪对象并在其上投影。我将使用contourFind()从移动物体中抓取一些感兴趣的点,现在我想将这些点(从投影仪!)投射到物体上!

我想要做的是(例如)跟踪对象的质心(COM)并在跟踪对象的摄像机视图上显示一个点(在其COM处)。然后应该在物体的COM上实时投射一个点。

似乎projectorExtrinsics.yml是我在加载yml文件后应该使用的openCV函数,但我不确定如何解释所有内在&相机和投影仪的外在校准值。即,projectPoints()需要

作为参数
  • 要重新投射的点数(duh!)
  • 旋转+翻译矩阵。我想我可以在这里使用projectorExtrinsics。或者我可以使用composeRT()函数生成最终旋转&来自projectorExtrinsics(我在yml文件中)的最终翻译矩阵和cameraExtrinsics(我没有。侧面问题:我不应该将它们保存在文件中吗?)。
  • 内在函数矩阵。现在这很棘手。我应该在这里使用相机还是投影仪内在矩阵?
  • 失真系数。我应该再次使用投影机或相机系数吗?
  • 其他参数...

所以如果我在projectPoints()中使用投影仪或相机(哪一个?)内在函数+系数,那么我只会'纠正'2个乐器中的一个。我在哪里/如何使用对方的内在函数??

除了projectPoints() yml文件和load()之外还需要使用什么? (也许是不成比例的?)

非常感谢任何有关此事的帮助。 如果有教程或书籍(不,O'Reilly“学习openCV”也没有谈论如何使用校准yml文件! - 仅关于如何进行实际校准),请指出我的方向。我不一定需要一个确切的答案!

1 个答案:

答案 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点,以便了解投影机的显示位置。

只有一台摄像机和一台投影机,这仍然是可能的,但更难,因为您无法仅通过一次观察对跟踪点进行三角测量。基本思想是像稀疏立体视差估计问题一样处理问题。可能的方法如下:

  1. 使用投影仪投影非模糊图像(例如黑白噪点),以便对相机观察到的场景进行纹理处理。

  2. 和以前一样,跟踪相机图像中感兴趣的对象

  3. 对于每个感兴趣的对象,将其在摄像机图像中的位置周围的小窗口与投影仪图像相关联,以便找到它在投影仪中投影的位置2D坐标

  4. 与上述方法不同的另一种方法是使用校准参数,可以使用projectPointsstereoRectify(或StereoBM::operator()进行GPU实现的密集3D重建),使用估计的场景深度将跟踪的2D位置映射到3D,最后使用gpu::StereoBM_GPU::operator()投影到投影仪。

    无论如何,使用两台相机更容易,也更准确。

    希望这有帮助。