Rangenet++球面投影代码

已有工作

代码开源地址:https://github.com/PRBonn/lidar

在项目train/common/laserscan中定义了LaserScan类,其中定义的reset方法已经能够实现球面投影转换了,球面投影转换公式略。

代码实现

下面我们尝试自己来实现这部分代码:

首先我们需要获取.las文件的数据,这部分代码我们可以使用库laspy实现。

接下去我们需要获取las文件中每个点的三维坐标,并计算到当前位置的距离,代码中为(0,0,0)

x = las.X * las.header.scale[0] + las.header.offset[0]
y = las.Y * las.header.scale[1] + las.header.offset[1]
z = las.Z * las.header.scale[2] + las.header.offset[2]

再根据一些简单的数学计算得到方位角和仰角,并进行归一化。

# 计算range, azimuth, 和 elevation
range_ = np.sqrt(x**2 + y**2 + z**2)  # 距离
azimuth = np.arctan2(y, x)  # 方位角
elevation = np.arcsin(z / range_)  # 仰角

# 将方位角归一化到 [0, 2*pi]
azimuth = (azimuth + np.pi) % (2 * np.pi)

# 归一化 elevation 到 [0, 1],可以调整范围
elevation = (elevation + np.pi / 2) / np.pi

接下来将数据映射到二维平面上,选择最近的点填入。

# 初始化range image,默认填充为无限大值
range_image = np.full((H, W), np.inf)

# 将range值填入range image中,选择最近的点
for i in range(len(range_)):
    if range_image[v[i], u[i]] > range_[i]:
        range_image[v[i], u[i]] = range_[i]

# 将无穷大的值替换为图像中的最大范围值
range_image[range_image == np.inf] = 0

最后进行可视化展示等,完整的代码如下:

import laspy
import numpy as np
import matplotlib.pyplot as plt

# 设置range image分辨率
H = 64  # 垂直分辨率
W = 1024  # 水平分辨率

# 读取LAS文件
las_file = "yourPointCloud.las" 
las = laspy.read(las_file)

# 获取点的X, Y, Z坐标
x = las.X * las.header.scale[0] + las.header.offset[0]
y = las.Y * las.header.scale[1] + las.header.offset[1]
z = las.Z * las.header.scale[2] + las.header.offset[2]

# 计算range, azimuth, 和 elevation
range_ = np.sqrt(x**2 + y**2 + z**2)  # 距离
azimuth = np.arctan2(y, x)  # 方位角
elevation = np.arcsin(z / range_)  # 仰角

# 将方位角归一化到 [0, 2*pi]
azimuth = (azimuth + np.pi) % (2 * np.pi)

# 归一化 elevation 到 [0, 1],可以调整范围
elevation = (elevation + np.pi / 2) / np.pi

# 将 azimuth 和 elevation 映射到图像坐标
u = (azimuth / (2 * np.pi) * W).astype(int)  # 水平坐标
v = (elevation * H).astype(int)  # 垂直坐标

# 初始化range image,默认填充为无限大值
range_image = np.full((H, W), np.inf)

# 将range值填入range image中,选择最近的点
for i in range(len(range_)):
    if range_image[v[i], u[i]] > range_[i]:
        range_image[v[i], u[i]] = range_[i]

# 将无穷大的值替换为图像中的最大范围值
range_image[range_image == np.inf] = 0

# 可视化range image
plt.figure(figsize=(10, 5))

# 使用热力图显示range image
plt.imshow(range_image, cmap='viridis')  # 可以使用'gray', 'plasma', 'inferno'等其他色彩图
plt.colorbar(label='Range')  # 添加颜色条,显示range值
plt.title("Range Image Visualization")
plt.xlabel("Azimuth (pixels)")
plt.ylabel("Elevation (pixels)")
plt.show()

# 如果需要,可以保存可视化图片
plt.imsave("range_image_visualization.png", range_image, cmap='viridis')

由于博主的数据是机载激光雷达数据,在尝试进行转换后发现效果并不好,故打算尝试其它点云数据分析方法。

  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值