有没有办法用立体摄像机计算到特定物体的距离?使用视差或角度来计算距离有没有方程式或其他东西?
发布于 2011-06-06 09:28:18
注意:这里描述的一切都可以在学习OpenCV一书中关于相机校准和立体视觉的章节中找到。您应该阅读这些章节,以便更好地理解下面的步骤。
一种不需要您自己测量所有相机内部和外部的方法是使用openCV校准功能。相机内部特性(镜头失真/倾斜等)可以使用cv::calibrateCamera计算,而外部特性(左右相机之间的关系)可以使用cv::stereoCalibrate计算。这些函数获取像素坐标中的许多点,并尝试将它们映射到现实世界中的对象坐标。CV有一种很好的方法来获得这样的点,打印出一个黑白棋盘,并使用cv::findChessboardCorners/cv::cornerSubPix函数来提取它们。大约10-15对棋盘图像就可以了。
可以将校准函数计算出的矩阵保存到磁盘中,这样您就不必在每次启动应用程序时都重复此过程。您在这里得到了一些整洁的矩阵,它们允许您创建一个校正图(cv::stereoRectify/cv::initUndistortRectifyMap),稍后可以使用cv::remap将其应用于您的图像。你还可以得到一个叫做Q的整齐矩阵,这是一个视差到深度的矩阵。
校正图像的原因是,一旦完成了一对图像的校正过程(假设您的校准是正确的),就可以在另一幅图像的同一行上找到一幅图像中的每个像素/对象。
有几种方法可以从这里开始,这取决于您在图像中寻找的特征类型。一种方法是使用CV立体对应函数,例如立体块匹配或半全局块匹配。这将为您提供整个图像的视差图,可以使用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坐标系中的点,左侧相机位于中心。
发布于 2011-06-05 16:21:55
我仍然在做它,所以我还不会发布完整的源代码。但我会给你一个概念性的解决方案。
您将需要以下数据作为输入(对于两个摄像头):
相机position
(水平和垂直)视角
你可以自己测量最后一个,把相机放在一张纸上,画两条线,然后测量这两条线之间的角度。
相机不需要以任何方式对齐,您只需要能够在两个相机中看到您的对象。
现在计算从每个摄影机到您的对象的向量。您拥有来自每个摄影机的对象的(X,Y)像素坐标,并且需要计算一个向量(X,Y,Z)。请注意,在简单的情况下,对象正好在相机的中间,解决方案将简单地为(camera.PointOfInterest - camera.Position)。
一旦两个向量都指向目标,由这些向量定义的线应该在理想世界中的一点相交。在现实世界中,由于测量误差小和摄像机分辨率有限,它们不会。所以使用下面的链接来计算两条线之间的距离矢量。
在链接中: P0是第一个凸轮位置,Q0是第二个凸轮位置,u和v是从摄像机位置开始并指向目标矢量。
你对实际距离不感兴趣,他们想要计算。你需要向量Wc -我们可以假设对象在Wc的中间。一旦你有了你的物体在3D空间中的位置,你也可以得到你喜欢的任何距离。
我将很快发布完整的源代码。
发布于 2011-06-13 15:20:54
我有检测人脸的源代码,返回的不仅是深度,还有真实世界的坐标,其中左摄像头(或右摄像头,我记不清了)是原点。它改编自“学习OpenCV”中的源代码,并参考了一些网站以使其工作。结果通常是相当准确的。
https://stackoverflow.com/questions/6241607
复制相似问题