当前位置: 首页 > news >正文

Python实现计算点云投影面积

        本次我们分享一种基于 Open3D 的快速、稳健方法,用于从激光点云中自动提取“地面”并计算其投影面积。算法先自适应估计地面高程,再将地面点投影至水平面,随后用凸包或最小外接矩形求取面积。整个流程无需人工干预,单文件即可运行,已封装成 Python 模块与图形界面,可直接嵌入地形测绘、建筑规划、农林监测、灾害评估等应用。

一、实现流程  
1. 加载点云:支持 PCD/PLY/XYZ 等常见格式。  
2. 地面分割:采用类 Otsu 自适应阈值,自动分离地面与非地面点。  
3. 二维投影:将地面点正射投影至 XY 平面。  
4. 边界提取:提供凸包与最小旋转矩形两种策略。  
5. 面积输出:返回平方米数值,可选可视化边界与文件报告。

二、应用场景  
- 地形制图:一键估算裸露地表面积,辅助 DEM 生产。  
- 城市规划:批量计算建筑底面轮廓,快速统计容积率。  
- 农林生态:量测植被或农田冠层投影,评估生长状况与产量。  
- 灾害应急:震后/滑坡区域快速圈定受灾范围,指导救援。  
- 土方计量:开挖前后两次点云对比,自动计算实际填挖面积与体积。

三、特点  
- 零依赖 GUI:拷贝即用,无需编写代码。  
- 自动阈值:对高低起伏、植被遮挡数据依然稳健。  
- 双模式面积:凸包(精确边界)与 Min-BBox(规则轮廓)任意切换。  
- 结果可溯源:同步输出边界矢量(GeoJSON),方便导入 GIS 平台。

        本次我们使用的数据——————————————兔砸!!!(当然,任意点云都可以)

一、投影面积计算程序

import tkinter as tk
from tkinter import filedialog, messagebox
import open3d as o3d
import numpy as np
from scipy.spatial import ConvexHull
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg# ---------- 业务逻辑 ----------
def read_pcd():# """弹出文件选择框并读取点云"""# file = filedialog.askopenfilename(#     title="选择点云文件",#     filetypes=[("点云", "*.pcd *.ply *.xyz"), ("所有文件", "*.*")])# if not file:#     return Nonefile = "E:/CSDN/规则点云/bunny.pcd"pcd = o3d.io.read_point_cloud(file)if pcd.is_empty():messagebox.showerror("错误", "点云读取失败!")return Nonereturn pcddef auto_height_threshold(points):"""简单 Otsu 思想取地面阈值"""z = points[:, 2]z_min, z_max = z.min(), z.max()best_th, best_var = z_min, 0for th in np.linspace(z_min, z_max, 100):back, fore = z[z <= th], z[z > th]if fore.size == 0 or back.size == 0:continuew0, w1 = back.size / z.size, fore.size / z.sizemean0, mean1 = back.mean(), fore.mean()mean_all = w0 * mean0 + w1 * mean1inter_var = w0 * (mean0 - mean_all) ** 2 + w1 * (mean1 - mean_all) ** 2if inter_var > best_var:best_var, best_th = inter_var, threturn best_thdef calc_area(pcd, draw=False):"""返回面积,可选弹出投影图"""pts = np.asarray(pcd.points)th = auto_height_threshold(pts)ground = pts[pts[:, 2] <= th, :2]if ground.shape[0] < 3:messagebox.showerror("错误", "地面点不足 3 个!")return Nonehull = ConvexHull(ground)area = hull.volume  # 2D 凸包 volume = areaif draw:# 弹出新窗口画投影win = tk.Toplevel()win.title("地面投影与凸包")fig, ax = plt.subplots(figsize=(4, 4))ax.scatter(ground[:, 0], ground[:, 1], s=1, c='g')for simplex in hull.simplices:ax.plot(ground[simplex, 0], ground[simplex, 1], 'r-')ax.set_aspect('equal')ax.set_title(f"Convex-Hull Area = {area:.3f}")canvas = FigureCanvasTkAgg(fig, master=win)canvas.draw()canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)return area# ---------- 按钮回调 ----------
def on_convex_hull():pcd = read_pcd()if pcd is None:returnarea = calc_area(pcd, draw=False)if area is not None:messagebox.showinfo("结果", f"凸包占地面积:{area:.4f} 平方单位")def on_convex_hull_with_plot():pcd = read_pcd()if pcd is None:returnarea = calc_area(pcd, draw=True)if area is not None:# 信息已在弹窗标题passdef on_exit():root.quit()root.destroy()# ---------- GUI ----------
root = tk.Tk()
root.title("点云地面面积计算")
root.geometry("300x160")
root.resizable(False, False)btn1 = tk.Button(root, text="1. 凸包面积", width=25, command=on_convex_hull)
btn2 = tk.Button(root, text="2. 凸包面积+投影图", width=25,command=on_convex_hull_with_plot)
btn3 = tk.Button(root, text="3. 退出", width=25, command=on_exit)btn1.pack(pady=10)
btn2.pack(pady=10)
btn3.pack(pady=10)root.mainloop()

二、投影面积计算结果

        这次依然沿用以前的GUI风格(主要是太好用了,谁用谁知道)。可以看到,两种投影面积计算方法得到的投影面积差不多。因为我们选用了自适应参数,所以效果基本上是最佳的。同学们如果有兴趣,可以自己调调参数试试,可以更加记忆深刻哦。就酱,下次见^-^


文章转载自:

http://zX22xB60.gygfx.cn
http://7LHZqHug.gygfx.cn
http://bZMpunMS.gygfx.cn
http://ytDOXZos.gygfx.cn
http://KhSYESWT.gygfx.cn
http://CQ2HoC1C.gygfx.cn
http://9AEsvjEf.gygfx.cn
http://EnvVW0tH.gygfx.cn
http://IHstciyc.gygfx.cn
http://f4TwoVoJ.gygfx.cn
http://1qZIMPpg.gygfx.cn
http://dxEWoG4x.gygfx.cn
http://JWDF3nmP.gygfx.cn
http://krBIZ2uu.gygfx.cn
http://xb0tvQb0.gygfx.cn
http://f94yQWSQ.gygfx.cn
http://wZiuzUqU.gygfx.cn
http://A2IyOMPa.gygfx.cn
http://XADuA17K.gygfx.cn
http://sFSE0n1k.gygfx.cn
http://SvMvz0NI.gygfx.cn
http://EZu11yVu.gygfx.cn
http://Mdxnft22.gygfx.cn
http://IJLxcfNd.gygfx.cn
http://BYbJWW6V.gygfx.cn
http://gktGfJnq.gygfx.cn
http://R51uvxmv.gygfx.cn
http://1qzplvs2.gygfx.cn
http://Pcaul0Kt.gygfx.cn
http://gQLZr75f.gygfx.cn
http://www.dtcms.com/a/388435.html

相关文章:

  • C++底层刨析章节二:迭代器原理与实现:STL的万能胶水
  • 学习Python中Selenium模块的基本用法(14:页面打印)
  • 便携式管道推杆器:通信与电力基础设施升级中的“隐形推手”
  • leetcode 349 两个数组的交集
  • UV映射!加入纹理!
  • 车辆DoIP声明报文/识别响应报文的UDP端口规范
  • Elasticsearch 2.x版本升级指南
  • OpenCV 人脸检测、微笑检测 原理及案例解析
  • [Python编程] Python3 集合
  • [性能分析与优化]伪共享问题(perf + cpp)
  • OC-动画实现折叠cell
  • 关于层级问题
  • Linux基础命令汇总
  • getchar 和 putchar
  • 【序列晋升】35 Spring Data Envers 轻量级集成数据审计
  • 快速入门HarmonyOS应用开发(二)
  • 绿联、极空间、飞牛NAS无需安装,实现快速远程访问
  • Datawhale 理工科-大模型入门实训课程 202509 第1次作业
  • 城市治理综合管理平台
  • 《嵌入式硬件(十三):基于IMX6ULL的增强型中断周期定时器(EPIT)操作》
  • PM2 入门指南与常用命令(含 开机自启、Node.js 及 Java 服务部署)
  • 汽车多核架构中内存系统故障检测的改进算法
  • C++真的比Python更快吗?
  • 【实操分享】使用 SeeDream 4.0 进行 AI 修图——开启专属“AI 云旅拍”
  • 不依赖第三方,不销毁重建,loveqq 框架如何原生实现动态线程池?
  • Python中正则的三个基础方法
  • 最外层的项目没有父pom配置文件,有很多子模块(maven项目)导入idea中,左侧模块显示不全问题解决
  • 前端将一个 DOM 元素滚动到视口顶部
  • 前端-防重复点击/防抖的方案
  • doris数据库问题