使用立体相机到物体的距离
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,您将无法很好地解释其中的内容。以上是关于使用立体相机到物体的距离的主要内容,如果未能解决你的问题,请参考以下文章