OpenCV中两点之间的距离

时间:2012-08-22 04:13:17

标签: c image-processing opencv perspectivecamera

我想测量两点之间的实际距离,就像路上有一辆车在我面前,我和车辆之间的距离是什么?

我继续这样做:

1)找到透视变换以获得顶视图。

2)然后试图找到距离。

问题是我无法获得正确的顶视图。

如果有其他方式请告诉。

2 个答案:

答案 0 :(得分:5)

要测量两个3D点之间的距离,您需要找到两个点的3D坐标。然后很容易计算出欧氏距离:

d(p1,p2)= sqrt{(p1_x - p2_x)^2+(p1_y - p2_y)^2+(p1_z - p2_z)^2}

这里的问题是找到场景中物体的3D点(因为你知道你在哪里,在相机处,参考坐标)。

要查找3D位置,您需要找到单应性或相机姿势。为此,您需要在场景中检测至少4个点,这些点与您先验知道的已知模型或图像的4个点相匹配。例如,如果你有一个汽车的3D模型,并且你能够在场景中检测到与你的3D模型相对应的真实汽车的点,你将能够计算单应性变换,因此,你可以计算三维位置。那些要点。

无论如何问题很复杂,您需要使用许多算法进行检测,匹配,校准,并且您需要知道要检测哪个对象。

答案 1 :(得分:2)

问题比你想象的要困难。即使在某些假设下:

  1. 整条道路平坦(高度没有变化)。
  2. 在车轮接触地面(而非车顶)的点上测量车辆的像素位置。如果你测量屋顶,距离可能是无限的。
  3. 您的相机在恒定变焦下静止不动。
  4. 如果其中一个假设不成立,则测量距离将非常困难。 但如果他们坚持你需要做以下事情:

    1. 透视转换到顶视图对您没有帮助(因为透视定义会扭曲距离)。即使在俯视图中,光线也会以透视方式移动。你需要的是'正交'投影。当相机处于无限高度+无限大变焦时,它模拟顶视图。就像你在卫星图像或地图中看到的一样。
    2. 你问为什么你需要这么奇怪的转变?正交和透视变换之间的区别在于,在视角中,对象之间的距离取决于tan(a)和正义(sin)(a)。 a - 是由距离线(2点之间的线)占据的摄像机视野的角度。当'a'是一个非常小的角度而不是tan('a')= sin('a'),你可以使用保护性转换。但由于您的网络摄像头具有大约50-70度的广角,因此您只能在图像中心使用保护变换精确计算距离。
    3. 此外,您必须在计算距离之前消除相机镜头失真。
    4. 所以第一步是校准你的相机,我们cvUnDistort()来纠正它的视线。
    5. 据我所知,openCV中没有内置的正交变换。因此,您可以在校正后的图像上使用俯视投影变换,但只有当两辆车都靠近图像中心时,距离才会准确。
    6. 您可以使用unDisrtort()实现正交变换,但这需要一些时间,因为您可能不熟悉相机模型和相机校准数学。在unDistort()中,你应该基本插入与sin('a')匹配的泰勒展开系列的系数,即a,-a ^ 2/2,......等...
    7. 无论如何,我之前说过,测量距离是一个非常难的问题。 我建议使用以下简单但不太准确的解决方案:

      1. 纠正镜头失真
      2. 应用顶视图投影转换
      3. 如果您发现当车辆远离图像中心时距离测量会产生错误,请尝试添加手动校正。 您可以在这里找到几乎所需的开源代码: http://code.google.com/p/signfinder/wiki/HowSignfinderWorks 该软件检测街道名称标志,并应用投影校正以便能够阅读文本。 希望它有所帮助