0. 硬件及系统
作者使用的系统为Ubuntu 20.04,环境配置为Python 3.8+Tensorflow 2.12+CUDA 11.8+cuDNN 8.6,硬件显卡为Nvidia4070。
在此不叙述CUDA、cuDNN、Anaconda的安装过程和基本操作。
1. 环境配置
在前人的基础上,本篇复现tf2的工程:
获取randlanet工程文件,创建名为randlanet的conda环境。
git clone --depth=1 https://github.com/luckyluckydadada/randla-net-tf2.git
conda create -n randlanet python=3.8
conda activate randlanet
为了匹配tensorflow2.12,修改helper_requirements.txt 中的版本信息
numpy
h5py==3.1.0
cython==0.29.15
open3d==0.17.0
pandas
scikit-learn==0.24.0
scipy
PyYAML
由于2.12版本后,没有tensorflow-gpu分支,其已经和cpu分支合并,故tensorflow安装时可直接使用命令
pip install tensorflow==2.12 -i https://pypi.tuna.tsinghua.edu.cn/simple/
作者CUDA和cuDNN是在系统安装而不是在虚拟环境中,故可另参考网上资料。
修改 randla-net-tf2/helper_tool.py 文件
import nearest_neighbors.lib.python.nearest_neighbors as nearest_neighbors
将其修改为:
import nearest_neighbors
修改 randla-net-tf2/compile_op.py 文件
python setup.py install --home="."
将其指定至conda环境目录下
python setup.py install --prefix=/home/znyzyjs/anaconda3/envs/randlanet/
将CUDA、cuDNN和tensorflow配置完成后,执行:
pip install -r helper_requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
sudo sh compile_op.sh
创建 randla-net-tf2/data 文件夹,将SemanticKITTI数据集放入,修改 randla-net-tf2/utils/data_prepare_semantickitti.py 中关于 dataset_path 和 output_path 的定义,与实际数据集目录匹配。
dataset_path = '/home/znyzyjs/randla-net-tf2/data/Semantic_kitti/dataset/sequences'
output_path = '/home/znyzyjs/randla-net-tf2/data/Semantic_kitti/dataset/sequences' + '_' + str(grid_size)
运行 utils/data_prepare_semantickitti.py。
python utils/data_prepare_semantickitti.py
训练中Batch Size的定义由helper_tool.py定义,具体参数修改依显卡硬件而定,若存在溢出报错,适当改小即可。作者使用Nvidia 4070显卡,batch size = 6 时有溢出情况,故修改为4。SemanticKITTI 数据集就只需修改 class ConfigSemanticKITTI 中的 batch size 即可。
2. 模型训练
在 main_SemanticKITTI.py 中修改 self.dataset_path ,与前文准备数据集过程中data_prepare_semantickitti.py 的 output_path 相对应。
self.dataset_path = '/home/znyzyjs/randla-net-tf2/data/Semantic_kitti/dataset/sequences_0.06'
在 randla-net-tf2 目录下开始训练:
python main_SemanticKITTI.py --mode train --gpu 0
完成训练后,开始测试:
sh jobs_test_semantickitti.sh
3. 连续点云可视化
运行 vis_SemanticKITTI.py 文件只能显示单帧点云,故创建新文件,依据 vis_SemanticKITTI.py 文件进行修改。
由于显示单帧点云使用了 ——helper_tool.py文件中的 Plot 类,故先修改 helper_tool.py 文件,注释掉 draw_pc_sem_ins() 中的绘图。
Y_semins = np.concatenate([pc_xyz[:, 0:3], Y_colors], axis=-1)
# Plot.draw_pc(Y_semins)
return Y_semins
而后创建新的 python 文件,在这里命名为 vis_pointcloud.py。
复制粘贴以下程序:(在此注意修改 dataset_path 和 predict_path 的路径)
from helper_tool import Plot
from os.path import join, dirname, abspath
from helper_tool import DataProcessing as DP
import numpy as np
import os
import pickle
import yaml
import open3d as open3d
import time
def get_file_list_test(dataset_path):
seq_list = np.sort(os.listdir(dataset_path))
test_file_list = []
for seq_id in seq_list:
seq_path = join(dataset_path, seq_id)
pc_path = join(seq_path, 'velodyne')
if int(seq_id) >= 11:
for f in np.sort(os.listdir(pc_path)):
test_file_list.append([join(pc_path, f)])
# break
test_file_list = np.concatenate(test_file_list, axis=0)
return test_file_list
def get_test_result_file_list(dataset_path):
seq_list = np.sort(os.listdir(dataset_path))
test_result_file_list = []
for seq_id in seq_list:
seq_path = join(dataset_path, seq_id)
pred_path = join(seq_path, 'predictions')
for f in np.sort(os.listdir(pred_path)):
test_result_file_list.append([join(pred_path, f)])
# break
test_file_list = np.concatenate(test_result_file_list, axis=0)
return test_file_list
if __name__ == '__main__':
dataset_path = '/home/znyzyjs/randla-net-tf2/data/Semantic_kitti/dataset/sequences'
predict_path = '/home/znyzyjs/randla-net-tf2/test/sequences'
test_list = get_file_list_test(dataset_path)
test_label_list = get_test_result_file_list(predict_path)
BASE_DIR = dirname(abspath(__file__))
# remap_lut #
data_config = join(BASE_DIR, 'utils', 'semantic-kitti.yaml')
DATA = yaml.safe_load(open(data_config, 'r'))
remap_dict = DATA["learning_map"]
max_key = max(remap_dict.keys())
remap_lut = np.zeros((max_key + 100), dtype=np.int32)
remap_lut[list(remap_dict.keys())] = list(remap_dict.values())
# remap_lut #
plot_colors = Plot.random_colors(21, seed=2)
vis = open3d.visualization.Visualizer()
vis.create_window()
pointcloud = open3d.geometry.PointCloud()
to_reset = True
vis.add_geometry(pointcloud)
for i in range(len(test_list)):
time.sleep(0.01)
pc_path = test_list[i]
labels_path = test_label_list[i]
points = DP.load_pc_kitti(pc_path)
# 用深蓝色画初始点云 #
# rpoints = np.zeros((points.shape[0],6),dtype=np.int)
# rpoints[:,0:3] = points
# rpoints[:,5] = 1
# Plot.draw_pc(rpoints)
# print("888888888888888888")
# 画对应的预测点云 #
labels = DP.load_label_kitti(labels_path, remap_lut)
Y_semins = Plot.draw_pc_sem_ins(points, labels, plot_colors)
pointcloud.points = open3d.utility.Vector3dVector(Y_semins[:, 0:3])
if Y_semins.shape[1] == 3:
open3d.visualization.draw_geometries([pointcloud])
if np.max(Y_semins[:, 3:6]) > 20: ## 0-255
pointcloud.colors = open3d.utility.Vector3dVector(Y_semins[:, 3:6] / 255.)
else:
pointcloud.colors = open3d.utility.Vector3dVector(Y_semins[:, 3:6])
vis.update_geometry(pointcloud)
if to_reset:
vis.reset_view_point(True)
to_reset = False
vis.update_renderer()
vis.poll_events()
vis.run()
而后运行文件:
python vis_pointcloud.py
即可生成连续点云,效果如下。
Randla_net点云连续可视化
4. 参考链接
在此感谢网上找到的参考资料以及数据集上传作者的贡献,欢迎大家遇到问题后反馈和讨论。