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

时间:2019-05-12 18:15:14

标签: python opencv computer-vision projection homography

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

我从视频帧中随机抽取了7分。我以point1为起点

然后,在相应的Google Maps透视图中,我计算了距原始点(增量x和增量y)的6个点的距离

然后我运行了以下

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的映射时,结果是错误的。

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

这是视频中的图像 enter image description here

我已经标记了要点,这是映射 enter image description here

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

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

知道我做错什么了吗?

1 个答案:

答案 0 :(得分:4)

照相机不是理想的针孔照相机,因此单应性无法捕获真实的变换。

对于小角度相机而言,结果非常接近,但对于鱼眼镜头而言,结果可能会非常差。

而且,以我的经验来看,只是文献中找到的理论镜头畸变模型对于现实世界的镜头(做“奇怪”事情以补偿镜筒/靠垫畸变的多元件)不是很准确。如今,非球面镜片的使用也可行,在这种非球面镜片的转换中,一切都可以。

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

编辑

在您的情况下,我会说问题出在输入数据中:考虑由点6、3、1、2、2形成的准四边形

image with marked quasi-quadrilateral

如果A-D距离为36.9,那么B-C距离如何为53.8米?

可能是您如何收集数据的问题,或者对于如此小的测量结果,不应认为Google地图是可靠的。

一种解决方案可能就是测量这些点的相对距离,然后根据该距离矩阵在平面求解中找到它们的坐标。

编辑

为进行检查,我编写了一个简单的非线性最小二乘法求解器(通过随机爬坡进行工作),使用我的地板图片对其进行了测试。 几秒钟后(它是用Python编写的,因此速度并不是它的最佳功能)可以解决一般的精确平面相机方程:

 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图像上)。

enter image description here

使用您的数据,但是我无法获得小于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求解数据,我当然得到了精确的数值解(有四个通用点,只有一个精确的平面摄像机),但是图像显然是完全错误的(网格应该位于网格上街道平面):

enter image description here