我在带有两个摄像机的多视图场景中使用 C++ 中的 open cv。我有两个相机的内在和外在参数。
我想将视图 1 中的 (X,Y) 点映射到第二个视图中的同一点。我有点不确定应该如何使用内在矩阵和外在矩阵,以便将点转换为 3D 世界,并最终在视图 2 中得到新的 2D 点。
如果没有一些附加信息,(通常)不可能在一个图像中获取 2D 坐标并将其映射到另一个 2D 坐标。
主要问题是左图像中的单个点将映射到右图像中的一条线(极线)。因为深度是一个自由参数,所以有无限多个可能的对应位置。其次,这一点完全有可能不存在在右图中,即它被遮挡。最后,可能很难准确确定哪个点是正确的对应关系,例如如果场景中没有纹理或者包含大量重复特征。
虽然基本矩阵(你从中得到cv::StereoCalibrate
无论如何)给你每个相机中的点之间的约束:x'Fx = 0
,对于给定的x'
将会有一整个家庭x
's 将满足方程。
一些可能的解决方案如下:
您知道一幅图像中 2D 点的 3D 位置。假设 3D 点位于公共坐标系中,您只需使用cv::projectPoints
与您想要投影到的其他相机的校准参数。
您可以使用 SIFT 或 ORB 等进行一些稀疏特征检测和匹配。然后,您可以计算单应性以将点从一幅图像映射到另一幅图像。这对物体是飞机做出了一些假设。如果你谷歌全景单应性,有很多讲座幻灯片详细介绍了这一点。
您校准相机,执行极线校正(cv::StereoRectify
, cv::initUndistortRectifyMap
, cv::remap
),然后通过立体匹配器运行它们。输出是一个视差图,它完全满足您的需求:从一个相机到另一个相机的每像素映射。那是,left[y,x] = right[y, x+disparity_map[y,x]]
.
(1) 是迄今为止最简单的,但您不太可能已经掌握该信息。 (2) 通常是可行的并且可能是合适的,并且正如另一位评论者指出的那样,如果平面性假设失败,则效果会很差。 (3) 是一般(理想)解决方案,但有其自身的缺点,并且依赖于图像是否适合密集匹配。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)