如何将.stcm文件转换为点云或CSV?现有Python脚本报错求助
解决.stcm转CSV/点云格式及laspy报错问题
先修复laspy 2.x的API兼容问题
你碰到的报错是因为代码用了laspy 1.x的旧API,而当前安装的是laspy 2.x,两者API不兼容。把laspy相关代码改成2.x的标准写法:
import laspy # laspy 2.x正确读取LAS/LAZ的方式 with laspy.open("test.las") as in_file: point_cloud = in_file.read() x = point_cloud.x y = point_cloud.y z = point_cloud.z # laspy 2.x写入LAS文件的方式 header = laspy.LasHeader(point_format=point_cloud.point_format, version="1.4") with laspy.open("output.las", mode="w", header=header) as out_file: out_file.write_points(point_cloud)
但核心问题是:laspy仅支持LAS/LAZ格式,无法直接读取.stcm文件,这才是你代码跑不通的根本原因。
处理.stcm文件的核心步骤
.stcm是部分激光雷达厂商的自定义输出格式,需要先解析它的二进制结构才能提取点云数据,以下是通用处理思路:
1. 解析.stcm二进制数据(需结合厂商格式文档)
如果没有官方解析库,可以用numpy直接读取二进制数据,需先确认.stcm的结构(比如是否有文件头、每个点的字节数、数据类型顺序)。示例代码:
import numpy as np # 读取文件二进制内容 with open("test.stcm", "rb") as f: raw_data = f.read() # 假设文件前1024字节是头信息,后面是每个点的x/y/z浮点数据(float32类型) # 跳过文件头,解析点数据 point_buffer = raw_data[1024:] point_data = np.frombuffer(point_buffer, dtype=np.float32) # 转换为N×3的点云数组 points = point_data.reshape(-1, 3) x, y, z = points[:, 0], points[:, 1], points[:, 2]
注意:文件头长度、数据类型需根据你的激光雷达厂商文档调整,不能直接套用示例中的数值。
2. 转换为CSV格式
用numpy或pandas直接保存即可:
# 用numpy保存 np.savetxt("output.csv", points, delimiter=",", header="x,y,z", comments="") # 或用pandas(需先安装pandas) import pandas as pd df = pd.DataFrame(points, columns=["x", "y", "z"]) df.to_csv("output.csv", index=False)
3. 转换为PLY/LAS点云格式
推荐用open3d处理,安装和使用都比pcl更简单:
import open3d as o3d # 创建open3d点云对象 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points) # 保存为PLY格式 o3d.io.write_point_cloud("output.ply", pcd) # 若要保存为LAS格式,用laspy 2.x header = laspy.LasHeader(point_format=3, version="1.4") header.scales = [0.001, 0.001, 0.001] # 设置坐标精度 header.offset = [x.min(), y.min(), z.min()] with laspy.open("output.las", mode="w", header=header) as out_file: out_file.write_points([laspy.ScaleAwarePointRecord.from_numpy(points, header)])
4. 原PCL代码的修正(若坚持使用PCL)
确保解析得到正确的点云数组后,修正PCL的API调用:
import pcl import numpy as np # 将解析后的points数组转为PCL支持的float32类型 cloud = pcl.PointCloud(points.astype(np.float32)) # 统计滤波 filter_obj = cloud.make_statistical_outlier_filter() filter_obj.set_mean_k(50) filter_obj.set_std_dev_mul_thresh(1.0) cloud_filtered = filter_obj.filter() # 保存滤波后的点云 pcl.io.save_point_cloud("filtered_output.ply", cloud_filtered)
关键提示
- 必须拿到你的激光雷达对应的.stcm格式文档,明确文件结构,否则无法正确解析数据。
- 如果厂商提供了官方转换工具,优先使用官方工具将.stcm转成LAS/PLY等通用格式后再处理。
内容的提问来源于stack exchange,提问作者Mubashir
相关产品推荐
相关产品推荐

