将lidar转化成为图片有很多种方法, 最近在思考如何根据自己设定的相机的角度来查看点云.

大致的想法是,输入lidar点云,以及从lidar到相机的pose, 这个pose,即沿着三个轴的旋转以及平移,可以是任意的,是人为指定的. 然后输出的是相机在这个pose下所拍摄到的相机的图片.

如果这个想法能够实现,就能够从不同的角度看点云形成的图片,比如第一人称视角,或者俯视图等.

以kitti为例

kitti raw的数据采集车是这样的.

点云 转 dem 点云转图像_点云

因为只有点云的话,不太好看第一人称的点云是怎么样的, 这里以相机俯视的角度来看.

那么第一步就是要传入相机的变换了.

即如何从

点云 转 dem 点云转图像_r语言_02


变到下面的

* ------->x
|
|
|
y

其中 *代表着z轴穿过纸向里.

有两种方式都可以实现

rx:0
ry:180
rz:90
和
rx:180
ry: 0
rz: 270

先解释一下,

后三行,

即先绕着x轴转180度,这个不用区分是顺时针,结果都一样.

然后rz=270度,指的是

点云 转 dem 点云转图像_r语言_03


右手坐标系下,即大拇指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如下

点云 转 dem 点云转图像_点云_04


虚拟相机的pose之后,得到的图片如下

点云 转 dem 点云转图像_r语言_05

如果单独把tz调高一些的话,即希望相机往lidar的正上方平移2米,得到的如下

点云 转 dem 点云转图像_开发语言_06


如果继续平移2米的话

点云 转 dem 点云转图像_开发语言_07

其他的视角也可以得到,比如斜向下45度的角度等等.

这里不再演示.