单目深度估计做自动驾驶靠谱吗?一文带你入门单目深度估计与伪雷达点云

806 阅读4分钟

特斯拉将最后一个深度感知传感器radar从车上拿掉之后,业内哗然,我们不禁在想,这到底是灵魂的扭曲,还是道德的沦丧.... 但是不管怎么样,自动驾驶还是要做的,动则几十万的激光雷达也不是一个事儿,还是需要更进一步的研究一下通过其他途径是否可靠,毕竟你2000快能解决问题的东西为什么要用20w呢?家里有矿?厂家家里有矿,消费者没有!

今日这个教程,主要是带大家入门一下单目深度估计,倒不是说一定靠谱,总之让大家入门一下,现在诸如waymo, tesla其实都在这个领域有很深的积累.不说别的,我觉得这个方向还是很有趣的,我喜欢看那种稠密的深度点云,因为你可以从上帝视角看到各个角度.

这篇教程的两个主要目的是:

  • 带你入门单目深度估计;
  • 带你入门生成伪雷达点云(Pesudo lidar point cloud);
  • 觉得不错请点个赞再走谢谢

实现单目深度估计,有双目也有单目,有非监督也有监督,今天别的不聊,只聊最基础的,给你一个深度图,你怎么生成Presudo lidar ?

视频动态效果:

www.bilibili.com/video/BV1QU…

image-20210601194044679

image-20210601194106301

image-20210601194142318

image-20210531164910815

简单来说,给定你一张上面模型预测出来的深度图片,我们将其反算到3D,并且通过RGB的像素值信息来生成带有实际场景解析的点云.

image-20210531171211394

image-20210531171313642

这很重要,通过收藏,点赞,转发本教程,你将能够白嫖到的技能包括:

  • 免费白嫖open3d可视化点云;
  • 免费白嫖单目3D的相关技巧,比如2d反算3D,pin-hole模型,摄像头内参等;
  • 免费白嫖如何通过深度生成点云,点云过滤,并显示彩色点云.

好了,不多说,开始白嫖.

深度估计模型

我们用到的深度估计模型是packnet, 关于深度估计模型的对比,很多模型有很多各自的优缺点,这里我们主要说的是这个,也就是用这个:

github.com/TRI-ML/pack…

二话不多说,点进去,先把代码clone一下,同时把模型下载一下.然后你还需要下载一下里面提供的 kitti_tiny这个洞洞,就几张图片.然后我们要做的第一件事情就是生成对应的深度图,和深度npZ.

python3 scripts/infer.py --checkpoint ./weights/PackNet01_HR_velsup_CStoK.ckpt --input data/KITTI_tiny/2011_09_26/2011_09_26_drive_0023_sync/image_02/data --output ./data/kitti --save npz

python3 scripts/infer.py --checkpoint ./weights/PackNet01_HR_velsup_CStoK.ckpt --input data/KITTI_tiny/2011_09_26/2011_09_26_drive_0023_sync/image_02/data --output ./data/kitti 

这里是以kitti为例子.

完了你就有了我们开头的第一张图了.

接下来就是核心了,我们需要拿到kitti camera的摄像头内参.

这个怎么拿?在哪里?

image-20210531171910730

打开这个文件,你就找到了:

CAMERA01:
9.842439e+02 0.000000e+00 6.900000e+02 0.000000e+00 9.808141e+02 2.331966e+02

没错,就是K_00里面的数值,里面是这个东西:

cx 0 fx
0 cy fy
0  0  0

关于具体的参数小孔成像原理,可以参考一下其他论文.

好了,你距离成功就差最后一步了,通过一张深度图,如何发算出3D的点云?

image-20210531171313642

这张图,其实就是一张深度图和一个内参算出来的.

核心函数是这个:

def depth2ptc_universal(depth, intrinsics):
    """
    depth: depth img ie. [384, 640]
    intrinsics: []
    """
    vu = np.indices(depth.shape).reshape(2, -1).T
    vu[:, 0], vu[:, 1] = vu[:, 1], vu[:, 0].copy()
    uv = vu
    uv_depth = np.column_stack((uv.astype(float), depth.reshape(-1)))

    cx, cy, fx, fy = intrinsics
    n = uv_depth.shape[0]
    x = ((uv_depth[:, 0]-cx)*uv_depth[:, 2])/fx + 0
    y = ((uv_depth[:, 1]-cy)*uv_depth[:, 2])/fy + 0
    pts_3d_rect = np.zeros((n, 3))
    pts_3d_rect[:, 0] = x
    pts_3d_rect[:, 1] = y
    pts_3d_rect[:, 2] = uv_depth[:, 2]
    return pts_3d_rect

输入一张深度图,和内参,给你输出一个点云.

好了,你现在已经掌握了深度图到3D了,白嫖成功.

open3d可视化彩色点云

那么这个彩色化点云怎么显示呢?open3d里面提供的接口是这样的:

ptc = np.array(ptc).astype(np.float32)
point_cloud = o3d.geometry.PointCloud()
point_cloud.points = o3d.utility.Vector3dVector(ptc)
# point_cloud.colors = o3d.utility.Vector3dVector(img.reshape(-1, 3)[indices][:, ::-1]/255)
point_cloud.transform(
[[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
o3d.visualization.draw_geometries([point_cloud])

通过设定里面的colors就可以产生彩色的点云了.

最后效果:

image-20210531172619740

image-20210601193819007

image-20210601193906409

image-20210601193946952

这是在kitti上的一个效果

最后,文中所有的代码在我们fork的packnet版本内:

manaai.cn/aicodes_det…

更多

image-20200820181257044

如果你想学习人工智能,对前沿的AI技术比较感兴趣,可以加入我们的知识星球,获取第一时间资讯,前沿学术动态,业界新闻等等!你的支持将会鼓励我们更频繁的创作,我们也会帮助你开启更深入的深度学习之旅!

image-20200515153654923

往期文章

zhuanlan.zhihu.com/p/370147740

zhuanlan.zhihu.com/p/358778224

zhuanlan.zhihu.com/p/165009477

zhuanlan.zhihu.com/p/149398749

zhuanlan.zhihu.com/p/147622974

zhuanlan.zhihu.com/p/144727162