找到视频点和现实世界点之间的映射
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 求解您的数据我当然得到了一个精确的数值解(有四个一般点有一个精确的平面相机)但是图像显然是完全错误的(网格应该位于在街机上):
我正在对视频进行汽车跟踪。我正在尝试确定它行驶了多少米。
我运行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 求解您的数据我当然得到了一个精确的数值解(有四个一般点有一个精确的平面相机)但是图像显然是完全错误的(网格应该位于在街机上):