运行环境
外部依赖库
- 安装PotreeConvert-develop:PotreeConverter-develop.zip
- 安装python open3D_0.19.0库
- 安装pothon laspy_2.6.1库
- 安装opencv_4.10.0
依赖环境
- 安装cmake3.21.0版本
- 安装clang15
- 安装python3.11
potreeConvert安装验证
使用如上PotreeConverter-develop.zip文件,解压后按照如下步骤安装
https://github.com/potree/PotreeConverter
验证方式:
1、上传如下las点云文件
2、potreeConvert安装完成后,执行
./PotreeConverter {las文件目录}/1727342319750106112.las -o {输出目录}
3、执行成功则显示如下,并且输出目录输出potree的4个文件,如下图
python相关库安装完成后验证
1、上传任意pcd文件
2、执行python脚本,传入输入文件和输出目录即可
import os
import sys
import open3d as o3d
import laspy
import numpy as np
def pcd2las(pcd_dir, las_dir):
if not os.path.exists(las_dir):
os.makedirs(las_dir)
for file in os.listdir(pcd_dir):
if file.endswith(".pcd"):
# 文件转换
pcd = o3d.io.read_point_cloud(pcd_dir.rstrip("/") + "/" + file) # 待转换的pcd文件
las_file = laspy.create(file_version="1.4", point_format=3)
# 假设 PCD 文件包含坐标和颜色信息,但不包含强度信息
points = np.asarray(pcd.points)
colors = np.asarray(pcd.colors)
# 创建 LAS 文件
las_file.x = points[:, 0]
las_file.y = points[:, 1]
las_file.z = points[:, 2]
las_file.write(las_dir.rstrip("/") + "/" + file.split(".")[0] + ".las")
pcd_dir = sys.argv[1]
las_dir = sys.argv[2]
pcd2las(pcd_dir, las_dir)
2、转化流程
pcd_2_potree.py
import json
import os
import sys
import open3d as o3d
import laspy
def pcd2potree(pcd_dir, desc_dir, potreeConvert):
if not os.path.exists(pcd_dir):
print(f'pcd文件夹不存在:{pcd_dir}')
return 1;
if os.path.exists(desc_dir):
#清空目录
os.system(f"rm -rf '{desc_dir}'")
print('desc_dir目录已存在,删除重建')
#重建目录
os.makedirs(desc_dir)
os.makedirs(os.path.dirname(desc_dir.rstrip("/") + "/las/"))
for file in os.listdir(pcd_dir):
if file.endswith(".pcd"):
# 文件转换
# pcd = o3d.io.read_point_cloud(pcd_dir.rstrip("/") + "/" + file) # 待转换的pcd文件
pcd = o3d.t.io.read_point_cloud(pcd_dir.rstrip("/") + "/" + file)
las_file = laspy.create(file_version="1.4", point_format=3)
# 假设 PCD 文件包含坐标和颜色信息,但不包含强度信息
points = pcd.point['positions'].numpy()
# 创建 LAS 文件
las_file.x = points[:, 0]
las_file.y = points[:, 1]
las_file.z = points[:, 2]
#强度信息
if 'intensity' in pcd.point:
intensity = pcd.point["intensity"].numpy()
las_file.intensity = intensity[:, 0]
las_path = desc_dir.rstrip("/") + "/las/" + file.split(".")[0] + ".las"
las_file.write(las_path)
#将las转为potree
potree_dir = desc_dir.rstrip("/") + "/potree/" + file.split(".")[0];
if potreeConvert is not None:
code = os.system(f"cd {potreeConvert} && ./PotreeConverter '{las_path}' -o '{potree_dir}'")
else:
code = os.system(f"PotreeConverter '{las_path}' -o '{potree_dir}'")
if code != 0:
print(f'转化异常:{code}')
return code
print(f'任务全部转化成功,desc_path:{desc_dir.rstrip("/")}/potree/')
return 0
'''
python3 pcd_2_potree.py {pcd文件所在目录} {结果potree存放目录} {PotreeConvert插件所在目录}
{PotreeConvert插件所在目录}:在配置了环境变量情况下可不输入
例如:python3 pcd_2_potree.py /bev_pcd /bev_potree /usr/local/bin
'''
if __name__ == '__main__':
pcd_dir = '/Users/huan2.liu/Downloads/pcd/'#sys.argv[1]
desc_dir = '/Users/huan2.liu/Downloads/pcd_desc'#sys.argv[2]
potreeConvert = '/Users/huan2.liu/PotreeConverter-develop/build/'#None
if len(sys.argv) > 3:
potreeConvert = sys.argv[3]
pcd2potree(pcd_dir, desc_dir, potreeConvert)
# for path, dir_list, file_list in os.walk("/Users/huan2.liu/Downloads/cache/PL656_event_dfdi_console_manual_event_20240926-171845_0/potree/"):
# print(f"===>{path}")
# update_metadata(path)
python3 pcd_2_potree.py {pcd文件所在目录} {结果potree存放目录} {PotreeConvert插件所在目录}
#{PotreeConvert插件所在目录}在配置了环境变量情况下可不输入
#例如:python3 pcd_2_potree.py /bev_pcd /bev_potree /usr/local/bin
输出:
3、potree可视化
1、安装nodejs
根据实际情况安装即可
2、下载potree并编译:
执行:
git clone https://gitee.com/jslibs/potree.git
在项目目录下新建build文件夹
cd potree && mkdir ./build
nodejs编译
npm install
执行完成后得到
3、加载potree项目
在potree项目目录下执行
mkdir ./pointclouds/data_converted
将转化后的potree文件copy进该文件夹
将以下html文件放入./examples文件夹下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Potree Viewer</title>
<link rel="stylesheet" type="text/css" href="../build/potree/potree.css">
<link rel="stylesheet" type="text/css" href="../libs/jquery-ui/jquery-ui.min.css">
<link rel="stylesheet" type="text/css" href="../libs/openlayers3/ol.css">
<link rel="stylesheet" type="text/css" href="../libs/spectrum/spectrum.css">
<link rel="stylesheet" type="text/css" href="../libs/jstree/themes/mixed/style.css">
</head>
<body>
<script src="../libs/jquery/jquery-3.1.1.min.js"></script>
<script src="../libs/spectrum/spectrum.js"></script>
<script src="../libs/jquery-ui/jquery-ui.min.js"></script>
<script src="../libs/other/BinaryHeap.js"></script>
<script src="../libs/tween/tween.min.js"></script>
<script src="../libs/d3/d3.js"></script>
<script src="../libs/proj4/proj4.js"></script>
<script src="../libs/openlayers3/ol.js"></script>
<script src="../libs/i18next/i18next.js"></script>
<script src="../libs/jstree/jstree.js"></script>
<script src="../build/potree/potree.js"></script>
<script src="../libs/plasio/js/laslaz.js"></script>
<!-- INCLUDE ADDITIONAL DEPENDENCIES HERE -->
<!-- INCLUDE SETTINGS HERE -->
<div class="potree_container" style="position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; ">
<div id="potree_render_area" style="background-image: url('../build/potree/resources/images/background.jpg');"></div>
<div id="potree_sidebar_container"> </div>
</div>
<script type="module">
window.viewer = new Potree.Viewer(document.getElementById("potree_render_area"));
viewer.setEDLEnabled(true);
viewer.setFOV(60);
viewer.setPointBudget(1_000_000);
viewer.loadSettingsFromURL();
viewer.setBackground("skybox");
viewer.loadGUI(() => {
viewer.setLanguage('zh');
$("#menu_appearance").next().show();
$("#menu_clipping").next().show();
viewer.toggleSidebar();
});
// Load and add point cloud to scene
Potree.loadPointCloud("../pointclouds/data_converted/metadata.json", "Dechen Cave", e => {
let scene = viewer.scene;
let pointcloud = e.pointcloud;
let material = pointcloud.material;
material.size = 0.7;
material.pointSizeType = Potree.PointSizeType.ADAPTIVE;
material.shape = Potree.PointShape.CIRCLE;
material.activeAttributeName = "elevation";
//material.rgbGamma = 0.67;
//console.log(JSON.stringify(material.shape));
scene.addPointCloud(pointcloud);
viewer.fitToScreen();
});
</script>
</body>
</html>
nodejs启动potree
cd ./build/potree && npm start
打开网页: