将lidar转化成为图片有很多种方法, 最近在思考如何根据自己设定的相机的角度来查看点云.
大致的想法是,输入lidar点云,以及从lidar到相机的pose, 这个pose,即沿着三个轴的旋转以及平移,可以是任意的,是人为指定的. 然后输出的是相机在这个pose下所拍摄到的相机的图片.
如果这个想法能够实现,就能够从不同的角度看点云形成的图片,比如第一人称视角,或者俯视图等.
以kitti为例
kitti raw的数据采集车是这样的.
因为只有点云的话,不太好看第一人称的点云是怎么样的, 这里以相机俯视的角度来看.
那么第一步就是要传入相机的变换了.
即如何从
变到下面的
* ------->x
|
|
|
y
其中 *代表着z轴穿过纸向里.
有两种方式都可以实现
rx:0
ry:180
rz:90
和
rx:180
ry: 0
rz: 270
先解释一下,
后三行,
即先绕着x轴转180度,这个不用区分是顺时针,结果都一样.
然后rz=270度,指的是
右手坐标系下,即大拇指z-向上时,食指x向前,中指y向左时,逆时针绕z轴旋转270度.即从x转到y的方向.
前三行的rz:90指的是也是在上面的右手坐标系下, 沿着食指向中指的转动方向,转动 90度.
这样的话,相机就朝下看了,假设相机位置和lidar位置重合,即 tx,ty,tz=0,那么lidar到相机的pose即为
def view(self, rx, ry, rz, tx, ty, tz):
mx = self.rotx(rx)
my = self.roty(ry)
mz = self.rotz(rz)
rotation = np.dot(mz, np.dot(my, mx))
translation = np.array([tx, ty, tz])
return self.transform_from_rot_trans(rotation, translation), rotation, translation
这里的
def rotx(self, t):
"""Rotation about the x-axis."""
c = np.cos(t)
s = np.sin(t)
return np.array([[1, 0, 0],
[0, c, -s],
[0, s, c]])
def roty(self, t):
"""Rotation about the y-axis."""
c = np.cos(t)
s = np.sin(t)
return np.array([[c, 0, s],
[0, 1, 0],
[-s, 0, c]])
def rotz(self, t):
"""Rotation about the z-axis."""
c = np.cos(t)
s = np.sin(t)
return np.array([[c, -s, 0],
[s, c, 0],
[0, 0, 1]])
def transform_from_rot_trans(self, R, t):
"""Transforation matrix from rotation matrix and translation vector."""
R = R.reshape(3, 3)
t = t.reshape(3, 1)
return np.vstack((np.hstack([R, t]), [0, 0, 0, 1]))
最后,先将lidar坐标转化为相机坐标,再由相机坐标转化为像素坐标即可.
以kitti的数据为例.
lidar点云用pcl看的bev如下
虚拟相机的pose之后,得到的图片如下
如果单独把tz调高一些的话,即希望相机往lidar的正上方平移2米,得到的如下
如果继续平移2米的话
其他的视角也可以得到,比如斜向下45度的角度等等.
这里不再演示.