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

标签 c++ opencv camera projection

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

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

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

我想做的是(例如)跟踪物体的质心 (COM) 并在被跟踪物体的相机 View 上显示一个点(在其 COM 处)。然后一个点应该实时投影到对象的COM上。

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

作为参数
  • 要重新投影的点 vector (呃!)
  • 旋转+平移矩阵。我想我可以在这里使用 projectorExtrinsics。或者我可以使用 composeRT() 函数从 projectorExtrinsics(我在 yml 文件中有)和 cameraExtrinsics(我没有。附带问题:我不应该保存它们吗?也在文件中??)。
  • 内在矩阵。现在这很棘手。我应该在这里使用相机还是投影仪内在矩阵?
  • 失真系数。我应该在这里使用投影仪还是相机系数?
  • 其他参数...

因此,如果我在 projectPoints() 中使用投影仪或相机(哪一个??)内在函数 + 系数,那么我将只对这两种仪器中的一种进行“校正”。我将在哪里/如何使用其他工具的内在函数??

除了 load() yml 文件和 projectPoints() 之外,我还需要使用什么? (也许不失真?)

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

最佳答案

首先,您似乎对相机/投影仪模型的一般作用感到困惑:它的作用是将 3D 世界点映射到 2D 图像点。这听起来很明显,但这意味着给定外部参数 R,t(用于方向和位置)、畸变函数 D(.) 和内部参数 K,您可以针对这个特定的相机推断 a 的二维投影 m 3D点M如下:m = K.D(R.M+t)。 projectPoints 函数为每个输入的 3D 点执行此操作(即 3D 到 2D 投影),因此您需要给它与您想要 3D 点的相机关联的输入参数projected(投影仪 K&D,如果你想要投影仪 2D 坐标,相机 K&D,如果你想要相机 2D 坐标)。

其次,当你 union 校准你的相机和投影仪时,你不会为相机估计一组外部参数 R,t,为投影仪估计另一组外部参数 R,t,而只估计一个 R 和一个 t,它们代表旋转和平移 在相机和投影仪的坐标系之间。例如,这意味着假设您的相机具有旋转 = 身份和平移 = 零,并且投影仪具有旋转 = R 和平移 = t(或相反,取决于您如何进行校准)。

现在,关于您提到的应用程序,真正的问题是:您如何估计给定点的 3D 坐标?

使用两个摄像头和一个投影仪,这会很容易:您可以跟踪两个摄像头图像中感兴趣的对象,使用函数 triangulatePoints 使用两个 2D 投影对它们的 3D 位置进行三角测量 最后使用 projectPoints 将此 3D 点投影到投影仪 2D 坐标中,以便了解投影仪在何处显示内容。

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

  1. 使用投影仪转换清晰的图像(例如黑白噪声),以便对相机观察到的场景进行纹理处理。

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

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

与上述方法不同的另一种方法是使用校准参数,可以使用 stereoRectifyStereoBM::operator()(或gpu::StereoBM_GPU::operator() 用于 GPU 实现),使用估计的场景深度将跟踪的 2D 位置映射到 3D,最后使用 projectPoints 投影到投影仪中.

无论如何,使用两个摄像头更容易、更准确。

希望这对您有所帮助。

关于c++ - 如何在相机 - 投影仪系统中重新投影点(校准后),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22290017/

相关文章:

c++ - Python 解析标准输入比 C++ 快得多

python - 在python中的蒙版外的图像上添加模糊/渐变

python - 如何 cv2.imshow 存储在 Numpy 数组中的图像?

python-2.7 - 将图像中的 Blob 识别为车辆的 Blob

opencv - 在 OpenCV 中绘制平面的法向量

iOS 相机 : manual exposure duration but auto ISO?

c++ - 从 STL 列表中删除特定节点

c++ - 从模板类中获取 "sub-type"

C++:参数与参数之间的区别?

c++ - 如何围绕原点倾斜相机