特斯拉将最后一个深度感知传感器radar从车上拿掉之后,业内哗然,我们不禁在想,这到底是灵魂的扭曲,还是道德的沦丧.... 但是不管怎么样,自动驾驶还是要做的,动则几十万的激光雷达也不是一个事儿,还是需要更进一步的研究一下通过其他途径是否可靠,毕竟你2000快能解决问题的东西为什么要用20w呢?家里有矿?厂家家里有矿,消费者没有!
今日这个教程,主要是带大家入门一下单目深度估计,倒不是说一定靠谱,总之让大家入门一下,现在诸如waymo, tesla其实都在这个领域有很深的积累.不说别的,我觉得这个方向还是很有趣的,我喜欢看那种稠密的深度点云,因为你可以从上帝视角看到各个角度.
这篇教程的两个主要目的是:
- 带你入门单目深度估计;
- 带你入门生成伪雷达点云(Pesudo lidar point cloud);
- 觉得不错请点个赞再走谢谢
实现单目深度估计,有双目也有单目,有非监督也有监督,今天别的不聊,只聊最基础的,给你一个深度图,你怎么生成Presudo lidar ?
视频动态效果:
简单来说,给定你一张上面模型预测出来的深度图片,我们将其反算到3D,并且通过RGB的像素值信息来生成带有实际场景解析的点云.
这很重要,通过收藏,点赞,转发本教程,你将能够白嫖到的技能包括:
- 免费白嫖open3d可视化点云;
- 免费白嫖单目3D的相关技巧,比如2d反算3D,pin-hole模型,摄像头内参等;
- 免费白嫖如何通过深度生成点云,点云过滤,并显示彩色点云.
好了,不多说,开始白嫖.
深度估计模型
我们用到的深度估计模型是packnet, 关于深度估计模型的对比,很多模型有很多各自的优缺点,这里我们主要说的是这个,也就是用这个:
二话不多说,点进去,先把代码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的摄像头内参.
这个怎么拿?在哪里?
打开这个文件,你就找到了:
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的点云?
这张图,其实就是一张深度图和一个内参算出来的.
核心函数是这个:
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就可以产生彩色的点云了.
最后效果:
这是在kitti上的一个效果
最后,文中所有的代码在我们fork的packnet版本内:
更多
如果你想学习人工智能,对前沿的AI技术比较感兴趣,可以加入我们的知识星球,获取第一时间资讯,前沿学术动态,业界新闻等等!你的支持将会鼓励我们更频繁的创作,我们也会帮助你开启更深入的深度学习之旅!
往期文章
zhuanlan.zhihu.com/p/370147740
zhuanlan.zhihu.com/p/358778224
zhuanlan.zhihu.com/p/165009477
zhuanlan.zhihu.com/p/149398749