首页 文章详情

鱼眼图像自监督深度估计原理分析和Omnidet核心代码解读

3D视觉工坊 | 146 2022-05-16 02:07 0 0 0
UniSMS (合一短信)
作者丨苹果姐@知乎
来源丨https://zhuanlan.zhihu.com/p/508090405
编辑丨3D视觉工坊
在自动驾驶实际应用中,对相机传感器的要求之一是拥有尽可能大的视野范围,鱼眼相机由于视场角(FOV)极大(标准镜头45°左右,广角镜头可大于60°,鱼眼相机可大于180°,也就是说甚至可以看到镜头后面的场景),在自动驾驶汽车上广泛使用。所以如何直接从鱼眼相机图像中估计深度是自动驾驶实际落地的一个重点问题。
然而鱼眼相机的大FOV带来的是非常大的非线性畸变,这决定了相比一般针孔相机,鱼眼相机图像的深度估计方法将更加复杂。虽然一个思路是对畸变进行矫正后再进行深度估计,但校正必定会引起FOV的缩小,失去使用鱼眼相机的意义,所以直接从鱼眼相机原图进行深度估计是学术界研究的热点问题。目前Valeo公司在鱼眼图像深度估计的研究中处于领先地位,博主之前对该公司的一系列成果做过一个简要综述:https://zhuanlan.zhihu.com/p/495899515
该公司的github地址是:https://github.com/rvarun7777,核心代码都存放在omnidet路径下,但与论文omnidet[1]中描述的内容差距较大,仅开放了distance/detection/semantic/motion四个独立任务以及联合多任务的基线版本,其中distance任务即鱼眼深度估计任务,相比FisheyeDistanceNet[2],并没有使用可变卷积、超分辨率网络、速度监督信号、交叉一致性损失等trick,而是仅保留了和monodepth2[3]一致的重投影ssim+l1损失以及平滑损失,但重投影部分是鱼眼图像深度估计的核心,还是值得我们深入学习。以下进行相关部分的原理分析和核心代码解读:
[1]OmniDet: Surround View Cameras based Multi-task Visual Perception Network for Autonomous Driving (ICRA 2021)
[2] FisheyeDistanceNet: Self-Supervised Scale-Aware Distance Estimation using Monocular Fisheye Camera for Autonomous Driving (ICRA 2020)
[3] Digging Into Self-Supervised Monocular Depth Estimation (ICCV 2019)
首先,从大的理论上,鱼眼图像自监督深度估计和针孔图像自监督深度估计一致,都是采用sfm-learner[4]的方法:
[4] Unsupervised Learning of Depth and Ego-Motion from Video (CVPR 2017)
即利用视频连续帧图像之间的重投影对位姿和深度的约束,来实现网络对深度和位姿的学习。本文假设读者已掌握针孔图像重投影的原理,如果不甚了解请先阅读博主的以下文章:https://zhuanlan.zhihu.com/p/462656351
现在正式进入鱼眼图像自监督深度估计内容。

一、鱼眼相机成像模型

关于鱼眼相机成像模型,可以参考博主以下文章:https://zhuanlan.zhihu.com/p/456538243
整个模型可以通过下图表示:
点P为空间中的一点,Oc为鱼眼相机的光心,Oc-XcYcZc为鱼眼相机坐标系。OcP和z轴的夹角为θ,也称为入射角。P经过Oc后在焦距为f的像平面上成像,由于鱼眼相机的畸变,点P在图像坐标系OXY中的投影不在直线传播的Po上,而是在经过折射的p'上。p'到图像坐标系原点O的距离为rd。鱼眼相机的畸变公式:
描述了rd和θ的关系,即可以将3D与2D联系起来,实现3D到2D坐标的互相转换。要注意的是因为这个折射关系与焦距f无关,所以为了简便,畸变公式描述的rd是归一化像平面上p'到O的距离。所以在实际计算中,还需要通过相机的内参,转换到焦距为f的像平面上的像素坐标系的坐标u,v。
了解了鱼眼相机成像模型,我们可以较容易地实现重投影过程。

二、重投影之2D到3D投影

首先进行的是target帧图像2D坐标到3D坐标的投影,即已知像素坐标[u, v],求3D坐标[X, Y, Z]。这里需要的输入参数为内参矩阵K、畸变系数列表D、distance网络的输出深度值distance(d)。这里值得指出的是,FisheyeDistanceNet[2]输出的并不是目标点到相机平面的垂直距离depth,而是目标点到相机光心的距离distance([X, Y, Z]的二范数),二者在上图中的关系是:depth = distance * cos(θ)。论文中未详细解释这样做的原因,可能是因为distance更加直观地符合自动驾驶应用场景。但博主考虑到由于distance是与位置相关的,为了让网络更好地学到位置,可能应该考虑加入位置编码信息,这点值得深入探索。
在2D到3D投影过程中,我们容易得到的是rd,而rd又在归一化像平面上,所以求rd的步骤为:
a.用np.meshgrid函数得到h*w分辨率的像素坐标系坐标[u, v]
b.像素坐标系经过内参矩阵,转换为归一化像平面坐标[x, y]
c.对[x, y]求二范数即为rd, 同时可以求得x,y在像平面的夹角φ
求得rd后,即可使用畸变公式求得θ:
d.使用np.root函数和畸变参数列表D、rd,求解得到θ矩阵。
Omnidet中这部分的代码为:
# Scale intrinsics to adjust image resize.
K, D = scale_intrinsic(args, intrinsic, coords)

x = np.linspace(0, args.input_width - 1, args.input_width)
y = np.linspace(0, args.input_height - 1, args.input_height)
mesh_x, mesh_y = np.meshgrid(x, y)
mesh_x, mesh_y = mesh_x.reshape(-1, 1), mesh_y.reshape(-1, 1)

x_cam = (mesh_x - K[1]) / K[0]
y_cam = (mesh_y - K[2]) / K[0]

r = np.sqrt(x_cam * x_cam + y_cam * y_cam)
theta_LUT = np.arctan2(y_cam, x_cam).astype(np.float32)
angle_LUT = np.zeros_like(r, dtype=np.float32)

for i, _r in tqdm(enumerate(r)):
a = np.roots([D[3], D[2], D[1], D[0], -_r])
a = np.real(a[a.imag == 0])
try:
a = np.min(a[a >= 0])
angle_LUT[i] = a
except ValueError: # raised if `a` is empty.
print(f"Field angle of incident ray is empty")
pass
在求θ(代码中的angle_LUT))过程中,由于np.roots函数返回的既有实数根又有复数根,所以需要过滤掉复数根,并且选取正的最小值(θ范围为0~FOV/2)。而且由于这个步骤耗时较长,而且是固定值,只需要计算一次,所以可以先离线计算出θ矩阵,在训练阶段直接使用。
得到θ和φ后,再根据distance网络输出的距离值d,即可得到P点在相机坐标系下的3D坐标[X, Y, Z]:
e.根据几何关系可得:
Z = d * cos(θ)
X = d * sin(θ)* cos(φ)
Y = d * sin(θ)* sin(φ)

三、重投影之3D到2D投影

求得target帧图像的3D坐标值[X, Y, Z]后,需要再通过posenet网络输出的pose信息,转换到source帧图像的3D坐标值,再投影到source帧图像的像素坐标系得到对应的像素坐标值[u, v],完成图像重构。
其中3D到2D投影的过程是第二节的逆过程:
a.根据3D坐标值[X, Y, Z],可求得r,φ, θ:
φ = arctan(Y/ X)
r = sqrt(X^2 + Y^2)
θ = arctan(r / Z)
b.根据畸变公式、畸变系数矩阵D和θ,可以求得rd
c.根据rd, r, φ, 可以求得归一化像平面坐标[x, y]:
x = rd * cos(φ)
y = rd * sin(φ)
d.根据内参矩阵K,可以求得焦平面像素坐标系坐标[u, v]
Omnidet中这部分的代码为:
x_cam, y_cam, z = [world_coords[:, i, :].unsqueeze(1) for i in range(3)]
# angle in the image plane
theta = torch.atan2(y_cam, x_cam)
# radius from angle of incidence
r = torch.sqrt(x_cam * x_cam + y_cam * y_cam)
# Calculate angle using z
a = np.pi / 2 - torch.atan2(z, r)
distortion_coeffs = distortion_coeffs.unsqueeze(1).unsqueeze(1)
r_mapping = sum([distortion_coeffs[:, :, :, i] * torch.pow(a, i + 1) for i in range(4)])

intrinsics = intrinsics.unsqueeze(1).unsqueeze(1)
x = r_mapping * torch.cos(theta) * intrinsics[:, :, :, 0] + intrinsics[:, :, :, 2]
y = r_mapping * torch.sin(theta) * intrinsics[:, :, :, 1] + intrinsics[:, :, :, 3]

四、图像重构和求损失函数

得到target帧图像在source帧图像中对应的像素坐标后,即可通过F.grid_sample函数完成图像重构,进而计算l1损失、SSIM损失、平滑损失等,因为与monodepth2[3]类似,本文不再赘述。

五、激光点云真值投影与模型评测

同样由于distancenet输出的是点P到光心的距离D,所以在模型评测时需要根据事先保存的θ矩阵先转换成深度值d,再与激光点云投影得到的gt深度图进行对比评测:
d = D * cos(θ)
其中点云投影过程与第三节过程相似,只是在生成gt深度图的时候有自己特殊的处理:
a. 已知激光点云坐标[X, Y, Z], 通过外参矩阵T转换到相机坐标系坐标[x, y, z]
b. 执行第三节的a-d步骤,但保留z坐标,得到像素坐标系坐标[u, v, z]
c.按照h*w分辨率初始化深度图gt_depth(h*w*1),过滤掉超出边界的坐标、z<0的坐标
d.由于分辨率的限制,和雷达与相机视角不同的影响,可能存在多个点映射到同一个像素坐标的情况,只保留深度值z最小的点。
e.根据d和gt_depth进行相关指标的评测
注:由于c、d步骤中的过滤操作并不影响图像重构(target帧多个点映射到source帧同一个点的情况),所以在第三节中并不需要进行过滤。
具体实现请参照monodepth2代码中generate_depth_map方法,并自行扩充到鱼眼相机投影模型。
至此,关于鱼眼图像自监督深度估计原理分析和核心代码解读告一段落,希望读者留言交流。
本文仅做学术分享,如有侵权,请联系删文。

3D视觉工坊精品课程官网:3dcver.com

1.面向自动驾驶领域的多传感器数据融合技术

2.面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)
3.彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进
4.国内首个面向工业级实战的点云处理课程
5.激光-视觉-IMU-GPS融合SLAM算法梳理和代码讲解
6.彻底搞懂视觉-惯性SLAM:基于VINS-Fusion正式开课啦
7.彻底搞懂基于LOAM框架的3D激光SLAM: 源码剖析到算法优化
8.彻底剖析室内、室外激光SLAM关键算法原理、代码和实战(cartographer+LOAM +LIO-SAM)

9.从零搭建一套结构光3D重建系统[理论+源码+实践]

10.单目深度估计方法:算法梳理与代码实现
11.自动驾驶中的深度学习模型部署实战
12.相机模型与标定(单目+双目+鱼眼)
13.重磅!四旋翼飞行器:算法与实战
14.ROS2从入门到精通:理论与实战
15.国内首个3D缺陷检测教程:理论、源码与实战

重磅!3DCVer-学术论文写作投稿 交流群已成立

扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流、ORB-SLAM系列源码交流、深度估计等微信群。


一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。

▲长按加微信群或投稿

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列三维点云系列结构光系列手眼标定相机标定激光/视觉SLAM自动驾驶)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近4000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
 圈里有高质量教程资料、答疑解惑、助你高效解决问题
觉得有用,麻烦给个赞和在看~  

good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter