找到视频点和现实世界点之间的映射

finding the mapping between video point and real world point

我正在对视频进行汽车跟踪。我正在尝试确定它行驶了多少米。

我运行domly从一个视频帧中拉取了7个点。我把point1作为我的起点

然后在相应的 Google 地图透视图上,我计算了 6 个点到原点的距离(delta x 和 delta y)

那我运行下面

pts_src = np.array([[417, 285], [457, 794], [1383, 786], [1557, 423], [1132, 296], [759, 270], [694, 324]])

pts_dst = np.array([[0,0], [-3, -31], [30, -27], [34, 8], [17, 15], [8, 7], [6, 1]])

h, status = cv2.findHomography(pts_src, pts_dst)

a = np.array([[1032, 268]], dtype='float32')
a = np.array([a])

# finally, get the mapping
pointsOut = cv2.perspectiveTransform(a, h)

我测试点7的映射时,结果是错误的。

我错过了什么吗?还是我使用了错误的方法? 谢谢

这是视频中的图片

我已经标记了点,这是映射

x,y 列表示图像上的像素。 metered 列表示从原点到该点的距离(以米为单位)。我基本上是使用 google 地图,将地理代码转换为 UTM 并计算 x 和 y 差值。

我尝试输入第 7 个点,我得到了 [[[14.682752 9.927497]]] 作为输出,它在 x 轴上很远。

知道我做错了什么吗?

相机不是理想的针孔相机,因此单应性无法捕捉到真正的变换。

对于小角度相机,结果非常接近,但对于 fish-eye 相机,结果可能非常不同。

此外,根据我的经验,文献中发现的理论镜头畸变模型对于 real-world 镜头来说不是很准确(multi-element 会做一些“奇怪”的事情来补偿 barrel/cushion 失真)。今天也可以使用 non-spherical 镜头,其中转换可以是任何东西。

为了能够获得准确的结果,我找到的唯一解决方案实际上是使用插值样条函数映射变换函数。

编辑

在你的情况下,我会说问题出在输入数据中:考虑由点 6、3、1、2

形成的 quasi-quadrilateral

如果A-D米的距离是36.9米,那么B-C距离怎么可能是53.8米呢?

可能问题出在您收集数据的方式上,或者 google 地图对于如此小的测量值不应该被认为是可靠的。

一个解决方案可能只是测量点的相对距离,然后从该距离矩阵求解出它们在平面上的坐标。

编辑

为了检查我写了一个简单的 non-linear 最小二乘求解器(通过随机爬山工作)使用我的地板图片来测试它。 几秒后(写的是Python,所以速度不是它最好的特性)可以解出一个一般的pinpoint planar camera equation:

 pixel_x = (world_x*m11 + world_y*m12 + m13) / w
 pixel_y = (world_x*m21 + world_y*m22 + m23) / w
 w = (x*m31 + y*m32 + m33)

 m11**2 + m12**2 + m13**2 = 1

而且我可以获得最大误差小于 4 像素的相机(在 4k 图像上)。

使用 YOUR 数据,但是我无法得到小于 120 像素的错误。 我为您的数据找到的最佳矩阵是:

0.0704790534896005     -0.0066904288370295524   0.9974908226049937
0.013902632209214609   -0.03214426521221147     0.6680756144949469
6.142954035443663e-06  -7.361135651590592e-06   0.002007213927080277

仅使用点 1、2、3 和 6 求解您的数据我当然得到了一个精确的数值解(有四个一般点有一个精确的平面相机)但是图像显然是完全错误的(网格应该位于在街机上):