本节主要分享 为什么我会想出迭代测距的方法?我的契机是什么?我是如何思考的?不感兴趣小伙伴可以直接跳过这一小节。
如今智能驾驶领域异常火爆,各方资本纷纷入场。在感知方面,当下 BEV(鸟瞰图)感知有巨大的潜力。不过当前 BEV 在车载芯片( xavier、orin )难以部署。且 BEV 数据集、训练环境成本也是痛点。
虽说如此,还是阻挡不住我们研究的热情。毕竟技术前进的道路是无法阻挡的。
那么 BEV 是怎么测距的呢?
- 这里简单介绍一种 Lift 操作。我们先检测目标,然后对目标特征进行提取,提取特征后,对 4 - 45 m 41 个深度进行一个分类。
- 这个和我们类别置信度有点异曲同工之妙,可以简单理解为一个逻辑回归,在哪一个深度置信度(概率)最高,确定为最终距离。
接地点像素测距,那我们是不是可以大胆点,直接分无穷个深度,最终选一个概率更大的深度。随之我们可以思考,是否可以找到一个收敛的数列,迭代寻找一个最有可能的值?
此时的博主不由自主看向窗外。落日的余晖照亮远处的河水,阵阵微风却没有激起一丝涟漪。"清风徐来,水波不兴,举酒。。。"打住!打住!,还是继续写博客吧。
已知像素 (u, v) 的情况下,我们只需要知道目标离相机的深度 Zcamera ,我们就可以求出目标的相机坐标系下坐标 (Xcamera, Ycamera, Zcamera)
已知 (Xcamera, Ycamera, Zcamera),又已知外参标定结果,那么很容易求出目标离我们车体 ego_car 的坐标(Xcar, Ycar, Zcar)。
关键点就在于我们的 Zcamera 。
(1)假设 Zcamera = 0。 单位 m
(2)计算求得 (Xcamera, Ycamera, Zcamera)
(3)计算求得 (Xcar, Ycar, Zcar)
(4)Zcamera = Zcamera + α * (Zcar - h)。其中 h 为车体的高度,如果车体坐标远点在地面,那么 h = 0,如果车体在地面上方 1m 处,则 h = 1。α 是一个超参数,可以自己调整。
(5)循环(2)(3)(4)。如果 (4)中 abs(Zar - h) < delta_h。 则结束,最终结果为此时的 (Xcar, Ycar, Zcar)。
Zcamera: 影响迭代次数,初值越接近真实值,迭代次数越少。如果目标多聚集于 10-20m 处,建议设置 15。
delta_h: 设置为0.005,当Zcar 与 h 这个平面相差小于 5mm 时迭代结束,输出最终结果。精度要求高,可以设置更小一点,代价迭代次数更多。
α:关键参数。Zcamera 数列是否收敛关键取决于 α。做为数学系出身的直觉告诉我,当 α 小于某个值时,Zcamera 收敛,当 α 大于某个值时,Zcamera 发散。
如果是学生时代,我非要证明一下Zcamera收敛。夹逼定理?单调有界? 如果有 dalao 感兴趣可以帮我证明下。博主选取了像素点 (u, v) = (1000, 800)。在不同 α 取值时,观察了 Zcamera 值的变换。
α = 1 迭代 12 次 | α = 0.1 迭代 144 次 | α = 10 迭代 inf 次 |
---|---|---|
α = 2 迭代 4 次 | α = 4 迭代 31 次 | α = 6 迭代 inf 次 |
注:迭代的过程可以理解为使得地面平行的过程。
import numpy as np
def bev_coor(x, y, distance, param):
*other, param_mtx, r, t = param
x = (x - param_mtx[0][2]) / param_mtx[0][0]
y = (y - param_mtx[1][2]) / param_mtx[1][1]
coor = np.array([x, y, 1]).reshape(3, 1) * distance
res_coor = r @ coor + t # 车体坐标系
return res_coor
def get_bev_distance(x, y, h_car, param):
res_x, res_y, res_z = 0, 0, 0
z = 0 # 初值
while abs(res_z - h_car) > 0.005:
res_x, res_y, res_z = bev_coor(x, y, z, param)
z = z + 1 * (res_z - h_car)
return res_x, res_y, res_z
if __name__ == '__main__':
front_param = [...] # 相机内参、相机外参
u, v = 1000, 800 # 接地点像素
car_h = 0 # 车体离地面高度
point_bev = get_bev_distance(u, v, car_h, front_param)
博客就写到这里吧。有什么疑问,欢迎私信交流。对于迭代测距的误差分析、与其他方法对比总结,我们下次再分享。谢谢收看,关注读书猿,点赞收藏不迷路。