我正在通过视频进行汽车跟踪。我正在尝试确定它行驶了多少米。
我从视频帧中随机抽取了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的映射时,结果是错误的。
我错过了什么吗?还是我使用了错误的方法? 谢谢
x,y列表示图像上的像素。测量列表示从原点到点的距离(以米为单位)。我基本上是使用Google地图,将地理代码转换为UTM并计算x和y的差异。
我尝试输入第7个点,并得到[[[14.682752 9.927497]]]作为输出,该输出在x轴上很远。
知道我做错什么了吗?
答案 0 :(得分:4)
照相机不是理想的针孔照相机,因此单应性无法捕获真实的变换。
对于小角度相机而言,结果非常接近,但对于鱼眼镜头而言,结果可能会非常差。
而且,以我的经验来看,只是文献中找到的理论镜头畸变模型对于现实世界的镜头(做“奇怪”事情以补偿镜筒/靠垫畸变的多元件)不是很准确。如今,非球面镜片的使用也可行,在这种非球面镜片的转换中,一切都可以。
为了获得准确的结果,我发现的唯一解决方案是实际上是使用插值样条函数映射变换函数。
在您的情况下,我会说问题出在输入数据中:考虑由点6、3、1、2、2形成的准四边形
如果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图像上)。
使用您的数据,但是我无法获得小于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求解数据,我当然得到了精确的数值解(有四个通用点,只有一个精确的平面摄像机),但是图像显然是完全错误的(网格应该位于网格上街道平面):