要测量两个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模型相对应的真实汽车的点,你将能够计算单应性变换,因此,你可以计算三维位置。那些要点。
无论如何问题很复杂,您需要使用许多算法进行检测,匹配,校准,并且您需要知道要检测哪个对象。
问题比你想象的要困难。即使在某些假设下:
- 整条道路平坦(高度没有变化)。
- 在车轮接触地面(而非车顶)的点上测量车辆的像素位置。如果你测量屋顶,距离可能是无限的。
- 您的相机在恒定变焦下静止不动。
醇>
如果其中一个假设不成立,则测量距离将非常困难。
但如果他们坚持你需要做以下事情:
- 透视转换到顶视图对您没有帮助(因为透视定义会扭曲距离)。即使在俯视图中,光线也会以透视方式移动。你需要的是'正交'投影。当相机处于无限高度+无限大变焦时,它模拟顶视图。就像你在卫星图像或地图中看到的一样。
- 你问为什么你需要这么奇怪的转变?正交和透视变换之间的区别在于,在视角中,对象之间的距离取决于tan(a)和正义(sin)(a)。 a - 是由距离线(2点之间的线)占据的摄像机视野的角度。当'a'是一个非常小的角度而不是tan('a')= sin('a'),你可以使用保护性转换。但由于您的网络摄像头具有大约50-70度的广角,因此您只能在图像中心使用保护变换精确计算距离。
- 此外,您必须在计算距离之前消除相机镜头失真。
- 所以第一步是校准你的相机,我们cvUnDistort()来纠正它的视线。
- 据我所知,openCV中没有内置的正交变换。因此,您可以在校正后的图像上使用俯视投影变换,但只有当两辆车都靠近图像中心时,距离才会准确。
- 您可以使用unDisrtort()实现正交变换,但这需要一些时间,因为您可能不熟悉相机模型和相机校准数学。在unDistort()中,你应该基本插入与sin('a')匹配的泰勒展开系列的系数,即a,-a ^ 2/2,......等...
醇>
无论如何,我之前说过,测量距离是一个非常难的问题。
我建议使用以下简单但不太准确的解决方案:
- 纠正镜头失真
- 应用顶视图投影转换
- 如果您发现当车辆远离图像中心时距离测量会产生错误,请尝试添加手动校正。
您可以在这里找到几乎所需的开源代码:
http://code.google.com/p/signfinder/wiki/HowSignfinderWorks
该软件检测街道名称标志,并应用投影校正以便能够阅读文本。
希望它有所帮助
醇>