【单目测距】提供一种迭代测距的思路

【单目测距】提供一种迭代测距的思路

文章目录

  • 【单目测距】提供一种迭代测距的思路
    • 一、前言
    • 二、迭代测距
      • 2.1、提出
      • 2.2、计算
      • 2.3、参数
      • 2.4、代码
    • 三、后记

一、前言

  1. 智能驾驶领域,主流单目测距仍采取接地点像素进行测距。
  2. 博主提出一种迭代测距方式,此方式也是采取接地点像素测距,但是理论精度会比传统接地点测距方式要更高。
  3. 本文主要讲解博主提出的一种迭代测距的思考逻辑与代码实现。
  4. 之前有过测距分享【单目测距】已知相机角度如何测距
    【单目测距】提供一种迭代测距的思路_第1张图片

二、迭代测距

2.1、提出

本节主要分享 为什么我会想出迭代测距的方法?我的契机是什么?我是如何思考的?不感兴趣小伙伴可以直接跳过这一小节。

  1. 如今智能驾驶领域异常火爆,各方资本纷纷入场。在感知方面,当下 BEV(鸟瞰图)感知有巨大的潜力。不过当前 BEV 在车载芯片( xavier、orin )难以部署。且 BEV 数据集、训练环境成本也是痛点。

  2. 虽说如此,还是阻挡不住我们研究的热情。毕竟技术前进的道路是无法阻挡的。

  3. 那么 BEV 是怎么测距的呢?

    • 这里简单介绍一种 Lift 操作。我们先检测目标,然后对目标特征进行提取,提取特征后,对 4 - 45 m 41 个深度进行一个分类。
    • 这个和我们类别置信度有点异曲同工之妙,可以简单理解为一个逻辑回归,在哪一个深度置信度(概率)最高,确定为最终距离。

接地点像素测距,那我们是不是可以大胆点,直接分无穷个深度,最终选一个概率更大的深度。随之我们可以思考,是否可以找到一个收敛的数列,迭代寻找一个最有可能的值?

此时的博主不由自主看向窗外。落日的余晖照亮远处的河水,阵阵微风却没有激起一丝涟漪。"清风徐来,水波不兴,举酒。。。"打住!打住!,还是继续写博客吧。

2.2、计算

已知像素 (u, v) 的情况下,我们只需要知道目标离相机的深度 Zcamera ,我们就可以求出目标的相机坐标系下坐标 (Xcamera, Ycamera, Zcamera)

img.png

已知 (Xcamera, Ycamera, Zcamera),又已知外参标定结果,那么很容易求出目标离我们车体 ego_car 的坐标(Xcar, Ycar, Zcar)。

img.png

关键点就在于我们的 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)。

2.3、参数

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张图片 【单目测距】提供一种迭代测距的思路_第3张图片 【单目测距】提供一种迭代测距的思路_第4张图片
α = 2 迭代 4 次 α = 4 迭代 31 次 α = 6 迭代 inf 次
【单目测距】提供一种迭代测距的思路_第5张图片 【单目测距】提供一种迭代测距的思路_第6张图片 【单目测距】提供一种迭代测距的思路_第7张图片

注:迭代的过程可以理解为使得地面平行的过程。

2.4、代码

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)

三、后记

博客就写到这里吧。有什么疑问,欢迎私信交流。对于迭代测距的误差分析、与其他方法对比总结,我们下次再分享。谢谢收看,关注读书猿,点赞收藏不迷路。

你可能感兴趣的:(自动驾驶,python)