使用立体相机到物体的距离

Posted

技术标签:

【中文标题】使用立体相机到物体的距离【英文标题】:Distance to the object using stereo camera 【发布时间】:2011-09-08 15:43:24 【问题描述】:

有没有办法使用立体相机计算到特定物体的距离? 是否有使用视差或角度来获取距离的方程式或其他东西?

【问题讨论】:

希望你不要介意,我把你的第二句话改写了一下。 如果答案确实回答了您的问题,请尝试将答案标记为已接受。 【参考方案1】:

注意:此处描述的所有内容都可以在 Learning OpenCV 书籍的相机校准和立体视觉章节中找到。您应该阅读这些章节以更好地理解以下步骤。

一种不需要您自己测量所有相机内参和外参的方法是使用 openCVs 校准函数。相机内在函数(镜头畸变/歪斜等)可以用 cv::calibrateCamera 计算,而外在参数(左右相机之间的关系)可以用 cv::stereoCalibrate 计算。这些函数采用像素坐标中的一些点,并尝试将它们映射到真实世界的对象坐标。 CV 有一种巧妙的方法来获取这些点,打印出黑白棋盘并使用 cv::findChessboardCorners/cv::cornerSubPix 函数来提取它们。应该有大约 10-15 个图像对的棋盘。

校准函数计算的矩阵可以保存到光盘中,因此您不必在每次启动应用程序时都重复此过程。你可以在这里得到一些简洁的矩阵,允许你创建一个校正图(cv::stereoRectify/cv::initUndistortRectifyMap),以后可以使用 cv::remap 将其应用于你的图像。您还会得到一个称为 Q 的简洁矩阵,它是一个视差到深度矩阵。

校正图像的原因是,一旦完成一对图像的过程(假设您的校准正确),一个图像中的每个像素/对象都可以在同一行找到在另一张图片中。

您可以从这里开始使用几种方法,具体取决于您在图像中寻找的功能类型。一种方法是使用 CV 的立体对应函数,例如 Stereo Block Matching 或 Semi Global Block Matching。这将为您提供整个图像的视差图,可以使用 Q 矩阵 (cv::reprojectImageTo3D) 将其转换为 3D 点。

这样做的缺点是除非图像中有很多纹理信息,否则 CV 并不是非常擅长构建密集的视差图(您会在其中出现无法找到正确视差的间隙给定像素),因此另一种方法是找到您想要匹配自己的点。假设您在左侧图像中的 x=40,y=110 和右侧图像中找到 x=22 中的特征/对象(由于图像经过校正,它们应该具有相同的 y 值)。视差计算为 d = 40 - 22 = 18。

构造一个 cv::Point3f(x,y,d),在我们的例子中是 (40,110,18)。以同样的方式找到其他有趣的点,然后将所有点发送到 cv::perspectiveTransform (以 Q 矩阵作为变换矩阵,本质上这个函数是 cv::reprojectImageTo3D 但对于稀疏视差图),输出将是点以左侧相机为中心的 XYZ 坐标系。

【讨论】:

过程的伟大总结,实际上做总结的人并不多,只是引用“去看看第12章!”。感谢您花时间解释:) @Orka 很棒的总结,真的很感谢你,但你能帮我如何使用 openCv 获得每个点的差异吗?【参考方案2】:

我仍在努力,所以我不会发布完整的源代码。但我会给你一个概念性的解决方案。

您将需要以下数据作为输入(对于两个摄像头):

摄像头位置 相机兴趣点(相机正在注视的点) 相机分辨率(水平和垂直) 相机视野角度(水平和垂直)

您可以自己测量最后一个,方法是将相机放在一张纸上并画两条线并测量这些线之间的角度。

相机不必以任何方式对齐,您只需要能够在两个相机中看到您的对象。

现在计算从每个相机到您的对象的向量。您有来自每个相机的对象的 (X,Y) 像素坐标,并且您需要计算一个向量 (X,Y,Z)。请注意,在简单的情况下,对象正好位于相机的中间,解决方案就是 (camera.PointOfInterest - camera.Position)。

一旦你的两个向量都指向你的目标,由这些向量定义的线应该在理想世界中的一个点相交。在现实世界中,他们不会因为小的测量误差和相机的分辨率有限。所以使用下面的链接来计算两条线之间的距离向量。

Distance between two lines

在该链接中:P0 是您的第一个凸轮位置,Q0 是您的第二个凸轮位置,u 和 v 是从相机位置开始并指向目标的向量。

你对实际距离不感兴趣,他们想计算。您需要向量 Wc - 我们可以假设对象位于 Wc 的中间。确定对象在 3D 空间中的位置后,您还可以获得所需的任何距离。

我会尽快发布整个源代码。

【讨论】:

您曾经提供过“完整”源代码吗?我有兴趣查看(又一个)从两个图像中获取深度的示例 @Eiver。可以在您实施时提供一些示例链接吗?提前谢谢.. @Eiver。你能和我们分享你的代码吗?提前致谢 @MohamedAM-Hassan 嗨!抱歉,但我完全被重定向到其他事情并且永远无法完成。【参考方案3】:

我有检测人脸的源代码,它不仅返回深度,还返回以左相机(或右相机,我不记得)为原点的真实世界坐标。它改编自“Learning OpenCV”的源代码,并参考一些网站以使其正常工作。结果通常相当准确。

【讨论】:

嗨,Tony,您能告诉我有关此源代码的更多详细信息吗? 他说,买一本《学习OpenCV》,这真的很值得投资。您也可以在 Google 中找到 book 的源代码,但同样,如果没有 book,您将无法很好地解释其中的内容。

以上是关于使用立体相机到物体的距离的主要内容,如果未能解决你的问题,请参考以下文章

如何测量相机与物体之间的距离

双目立体视觉

立体匹配算法(局部立体匹配 全局立体匹配 深度学习立体匹配 )

立体视觉:深度估计

物联网22.物联网开发之先进传感 - 立体相机

立体匹配算法(局部立体匹配 全局立体匹配 深度学习立体匹配 )