Python计算点云的均值、方差、标准差、凸点(顶点)、质心和去中心化

发布于:2025-08-31 ⋅ 阅读:(20) ⋅ 点赞:(0)

今天我们分享点云几个特征的计算方法,介绍如下:

1. 点云的均值

        1.1 原理
                点云的均值是指点云中所有点的平均位置,它表示点云的中心位置。均值的计算公式为:
                        mu = frac{1}{N} sum_{i=1}^{N} x_i ]
        其中,( x_i ) 是第 ( i ) 个点的坐标,( N ) 是点的总数。

        1.2 实现步骤
                1)读取点云数据:从文件中读取点云数据。
                2)提取点云坐标:将点云对象中的点数据提取为 numpy 数组。
                3)计算均值:使用 numpy 的 mean 函数计算点云坐标的均值。

2. 点云的方差

        2.1原理
                方差描述点云中点到均值的平均距离的平方,表示点云的离散程度。方差的计算公式为:
                        sigma^2 = frac{1}{N} sum_{i=1}^{N} (x_i - mu)^2 ]

        2.2 实现步骤
                1)读取点云数据:从文件中读取点云数据。
                2)提取点云坐标:将点云对象中的点数据提取为 numpy 数组。
                3)计算均值:使用 numpy 的 mean 函数计算点云坐标的均值。
                4)计算方差:使用 numpy 的 var 函数计算点云坐标的方差。

3. 点云的标准差

        3.1 原理
                标准差是方差的平方根,也表示点云的离散程度,但与原始数据的尺度一致。标准差的计算公式为:
                        sigma = sqrt{sigma^2}

        3.2 实现步骤
                1)读取点云数据:从文件中读取点云数据。
                2)提取点云坐标:将点云对象中的点数据提取为 numpy 数组。
                3)计算均值:使用 numpy 的 mean 函数计算点云坐标的均值。
                4)计算方差:使用 numpy 的 var 函数计算点云坐标的方差。
                5)计算标准差:使用 numpy 的 std 函数计算点云坐标的标准差。

4. 点云的凸包

        4.1 原理
                凸包是指在实向量空间 \( \mathbb{R}^n \) 中的一组点 ( X ) 的凸包或凸包络是包含 ( X ) 的最小凸集。通俗地说就是包围一组散点的最小凸多边形。三维点云的凸包是包含所有点的最小凸集,Open3D 中的 `compute_convex_hull` 函数实现了计算凸包的方法。

        4.2 实现步骤
                1)读取点云数据:从文件中读取点云数据。
                2)计算凸包:使用 Open3D 的 `compute_convex_hull` 函数计算点云的凸包。
                3)可视化凸包:使用 Open3D 可视化计算得到的凸包。

5. 点云的质心

        5.1 原理
                在 Open3D 中,计算点云 \( Q \) 的质心(中心点)是一个常见的操作。质心是点云所有点的平均位置,可以通过简单地计算点云中所有点的平均值来得到。点云质心的计算是点云处理中一个基本且重要的步骤。质心不仅是点云的几何中心,还在许多实际应用中起着重要作用,包括点云对齐、归一化、重心调整、特征提取、可视化和机器人导航等。通过计算质心,可以更有效地处理和分析点云数据,提升点云处理任务的精度和效率。

        5.2 实现步骤
                1)提取点云数据:将点云数据表示为一组三维坐标点( (x_i, y_i, z_i)),其中( i = 1, 2, ..., N) 表示点的索引,(N) 为点云中的点数。
                2)计算各个坐标轴上的平均值:
                   -( x ) 坐标的平均值(bar{x} = frac{1}{N} sum_{i=1}^{N} x_i )
                   - ( y ) 坐标的平均值(bar{y} = frac{1}{N} sum_{i=1}^{N} y_i )
                   - ( z ) 坐标的平均值(bar{z} = frac{1}{N} sum_{i=1}^{N} z_i )
                3)质心坐标:质心坐标为 ( (bar{x}, bar{y}, bar{z}) ),即点云中所有点坐标的平均值。

6. 点云的去中心化

        6.1 原理
                在 Open3D 中,计算去质心后的点云 \( Q \) 是一个常见的操作,尤其是在点云配准、对齐和归一化过程中。去质心操作是将点云的质心平移到原点,使得点云数据相对于原点对称分布。

        6.2 实现步骤
                1)读取点云数据:读取点云文件。
                2)计算质心:计算点云中所有点的质心。
                3)平移点云:将点云中所有点平移,使质心位于原点。
                4)可视化去质心后的点云:使用 Open3D 可视化去质心后的点云。

本次我们的数据,你猜猜————————————猜对啦!兔砸,哈哈哈

一、各种特征计算程序

import open3d as o3d
import numpy as np
import os
import tkinter as tk
from tkinter import messagebox

# ===== 唯一需要修改的地方:你的点云完整路径 =====
PCD_PATH = r'E:/CSDN/规则点云/bunny.pcd'
# =====================================================

if not os.path.isfile(PCD_PATH):
    messagebox.showerror("错误", f"找不到点云:\n{PCD_PATH}")
    exit()

pcd = o3d.io.read_point_cloud(PCD_PATH)
if not pcd.has_points():
    messagebox.showerror("错误", "点云为空或读取失败")
    exit()

pts = np.asarray(pcd.points)

# -------------------- 功能封装 --------------------
def show_stats():
    mean = np.mean(pts, axis=0)
    var  = np.var(pts, axis=0)
    std  = np.std(pts, axis=0)
    messagebox.showinfo("统计量",
                        f"均值:{mean}\n"
                        f"方差:{var}\n"
                        f"标准差:{std}")

def show_convex():
    hull, _ = pcd.compute_convex_hull()
    lines = o3d.geometry.LineSet.create_from_triangle_mesh(hull)
    lines.paint_uniform_color((1, 0, 0))
    o3d.visualization.draw_geometries([pcd, lines], window_name="Convex Hull")

def show_centroid():
    c = np.mean(pts, axis=0)
    frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.1)
    frame.translate(c)
    o3d.visualization.draw_geometries([pcd, frame], window_name="Centroid")

def center_and_save():
    c = np.mean(pts, axis=0)
    centered = o3d.geometry.PointCloud()
    centered.points = o3d.utility.Vector3dVector(pts - c)
    if pcd.has_colors():
        centered.colors = pcd.colors
    if pcd.has_normals():
        centered.normals = pcd.normals
    # 需要保存的话把下面注释取消掉
    # out = os.path.join(os.path.dirname(PCD_PATH), "centered_1.pcd")
    # o3d.io.write_point_cloud(out, centered, write_ascii=True)
    # messagebox.showinfo("完成", f"已保存:\n{out}")
    # 可视化对比
    pcd.paint_uniform_color((0, 1, 0))
    centered.paint_uniform_color((1, 0, 0))
    centered.translate([0, 0.002, 0])
    o3d.visualization.draw_geometries([pcd, centered],
                                      window_name="Original vs Centered")

# -------------------- 简单 GUI --------------------
def on_click(mode):
    if mode == 1:
        show_stats()
    elif mode == 2:
        show_stats()  # 一并打印
    elif mode == 3:
        show_stats()
    elif mode == 4:
        show_convex()
    elif mode == 5:
        show_centroid()
    elif mode == 6:
        center_and_save()

root = tk.Tk()
root.title("计算小工具")
root.geometry("260x220")

tk.Label(root, text="请选择要执行的操作:", font=("微软雅黑", 12)).pack(pady=5)

for i, txt in enumerate(["1 均值", "2 方差", "3 标准差",
                         "4 凸包顶点", "5 质心", "6 去中心化"],
                        start=1):
    tk.Button(root, text=txt, width=20,
              command=lambda m=i: on_click(m)).pack(pady=2)

tk.Button(root, text="退出", width=20, command=root.quit).pack(pady=8)

root.mainloop()

二、各种特征计算结果

        本次我们为了方便操作,做了一个gui界面。可以看到,均值、方差和标准差被一块显示出来了,三个按钮的显示结果一样,凸包、质心和去中心化也很好的计算了(同学甲:那么快我看个吉尔!作者:没办法啊,平台限制大小,自己运行下看看呗。。)

就酱,下次见^-^


网站公告

今日签到

点亮在社区的每一天
去签到