You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现点云逐点生成定半径球体并统计球内点数

三维点云固定半径邻域点计数Python实现

实现思路

  • 读取txt格式存储的点云数据,逐行解析每个点的X、Y、Z三维坐标
  • 针对不同数据规模选择计算逻辑:千级以内小数据可以直接暴力遍历计算距离,十万级以上数据用KD树空间索引加速,避免O(n²)复杂度导致计算过慢
  • 对每个点作为球心,统计三维欧氏距离小于等于指定半径的点总数(计数包含球心点本身)
  • 将每个点对应的计数结果逐行写入新的txt文件,和输入点的顺序一一对应

首先安装需要的科学计算依赖(仅优化版需要,纯Python版无依赖):
pip install numpy scipy


推荐版本:KD树加速版(支持百万级以内点云快速计算)

import numpy as np
from scipy.spatial import cKDTree
import time

# ------------------- 自定义参数区 -------------------
INPUT_TXT_PATH = "input_pointcloud.txt"  # 你的点云输入文件路径
OUTPUT_TXT_PATH = "count_result.txt"     # 计数结果输出路径
SPHERE_RADIUS = 0.5                      # 固定球体半径,按实际需求修改
# ----------------------------------------------------

if __name__ == "__main__":
    # 读取点云数据
    print("正在读取点云文件...")
    point_cache = []
    with open(INPUT_TXT_PATH, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line:
                continue  # 跳过文件里的空行
            x, y, z = map(float, line.split())
            point_cache.append([x, y, z])
    points = np.array(point_cache, dtype=np.float64)
    print(f"读取完成,共{len(points)}个点")

    # 构建KD树空间索引
    print("正在构建空间索引...")
    kdtree = cKDTree(points)

    # 批量查询半径范围内的邻域点
    print("正在统计邻域点数量...")
    start_ts = time.time()
    # workers=-1表示调用所有CPU核心并行计算
    neighbors = kdtree.query_ball_point(points, r=SPHERE_RADIUS, workers=-1)
    count_list = [len(idx_list) for idx_list in neighbors]
    print(f"统计完成,耗时{time.time() - start_ts:.2f}秒")

    # 写入结果文件
    print("正在写入结果文件...")
    with open(OUTPUT_TXT_PATH, "w", encoding="utf-8") as f:
        for cnt in count_list:
            f.write(f"{cnt}\n")
    print(f"处理完成,结果已保存到{OUTPUT_TXT_PATH}")

无依赖纯Python版(仅适合千级以内小点云测试)

这个版本不需要安装第三方库,但是点数量过万后速度会非常慢,仅做临时测试用:

# ------------------- 自定义参数区 -------------------
INPUT_TXT_PATH = "input_pointcloud.txt"
OUTPUT_TXT_PATH = "count_result.txt"
SPHERE_RADIUS = 0.5
# ----------------------------------------------------

if __name__ == "__main__":
    # 读取点云
    points = []
    with open(INPUT_TXT_PATH, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            x, y, z = map(float, line.split())
            points.append((x, y, z))
    
    radius_sq = SPHERE_RADIUS ** 2  # 用平方值比较距离,省去开根号运算提速
    count_res = []
    for cx, cy, cz in points:
        cnt = 0
        for x, y, z in points:
            dist_sq = (x-cx)**2 + (y-cy)**2 + (z-cz)**2
            if dist_sq <= radius_sq:
                cnt += 1
        count_res.append(cnt)
    
    # 写入结果
    with open(OUTPUT_TXT_PATH, "w", encoding="utf-8") as f:
        for cnt in count_res:
            f.write(f"{cnt}\n")

几个注意点:

  • 球体半径参数要和你点云的坐标单位匹配,不要出现坐标单位是米、半径填成毫米级数值的情况
  • 点云规模超过100万的话,建议先做体素下采样减少点数量再计算,否则内存占用会很高
  • 输出结果的顺序和输入点云的点顺序完全对应,不会出现错位

内容的提问来源于stack exchange,提问作者youssef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:15:39