【Lidar】基于Python格网法计算点云体积(eg.树木体积)

news2024/11/14 21:36:51

        这两天一直不在状态,不是特别想分享文章,所以也没怎么更新。但是代码放在文件里始终不是它的归宿,只有被不断使用它才能进步,才能诠释它的意义。所以今天抽空给大家分享一下如何基于Python利用格网法计算点云的体积,我这里是做林业的点云,所以是按照树木体积编写的代码。

1 代码逻辑

        逻辑部分其实很简单,就是将三维点云数据投影至二维平面,再通过格网将二维平面切割成无数个小块,统计位于该格网中点云的最高点和最低点差值,用这个高度差值乘以格网大小,即这个格网的体积,再将所有格网体积累加即该物体的体积。类似于积分学,将无数个格网体积近似等同于物体的体积。

2 完整代码

        这里就不过多解释了,有注释!原理上面已经说明白了。

# -*- coding: utf-8 -*-
"""
@Time : 2023/9/3 14:37
@Auth : RS迷途小书童
@File :Grid method for volume calculation.py
@IDE :PyCharm
@Purpose:格网法计算点云体积并展示刨面图
"""
import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap


def grid_method(point_cloud, grid_size):
    points = np.asarray(point_cloud.points)
    # 将点云数据转换为数组
    points_x = points[:, 0]  # 获取x的数组
    points_y = points[:, 1]  # 获取y的数组
    cols_x = int(np.ceil((np.max(points_x) - np.min(points_x)) / grid_size))+1  # 计算栅格的列数
    cols_y = int(np.ceil((np.max(points_y) - np.min(points_y)) / grid_size))+1  # 计算栅格的行数
    start_x = np.min(points_x)  # 获取x的最小值作为格网的起始x
    start_y = np.min(points_y)  # 获取y的最小值作为格网的起始y
    result = 0  # 初始化体积为0
    array_show = np.zeros((cols_x, cols_y))  # 创建用来显示的数组
    for col_x in range(0, cols_x):  # 遍历格网的列
        end_x = np.min(points_x) + grid_size * (col_x+1)
        # 获取当前格网的范围
        for col_y in range(0, cols_y):  # 遍历格网的行
            end_y = np.min(points_y) + grid_size * (col_y+1)
            # 获取当前格网的范围
            mask = (points[:, 0] >= start_x) & (points[:, 0] <= end_x) & (points[:, 1] >= start_y) & (points[:, 1] <= end_y)
            # 通过格网范围筛选出落在当前网格内的点
            if np.sum(mask) > 0:
                # 如果当前网格内有点,则记录最大高度
                max_z = np.max(points[mask, 2])
                min_z = np.min(points[mask, 2])
                height = max_z - min_z  # 计算格网内的高度插差值
                # print("Max_z:",max_z)
                # print("Min_z:",min_z)
                # print("Height:",height)
                if height <= 0.0005:
                    # 记录高度差非常小的格网,原因:格网范围过小,最高点和最低点没有落在格网内
                    print("当前起始点:", start_x, start_y)
                    print("当前终止点:", end_x, end_y)
                    print("当前格网内的点云为:")
                    print(np.array([points[mask, 0], points[mask, 1], points[mask, 2]]))
                result += height * grid_size ** 2  # 将格网的体积累加
                array_show[col_x, col_y] = height
            start_y = end_y
        start_x = end_x
    return result, array_show


if __name__ == "__main__":
    pcd_path = "彭俊喜/1 - Cloud.pcd"  # 读取点云文件
    pcd = o3d.io.read_point_cloud(pcd_path)
    Grid_size = 0.1  # 设置栅格大小(根据实际情况调整)
    volume, array = grid_method(pcd, Grid_size)  # 计算树冠体积
    print("树冠体积:", volume)
    fig, ax = plt.subplots()  # 创建图形和轴对象
    cmap = LinearSegmentedColormap.from_list('white_to_red', ['white', (0.8, 0.5, 0.2), 'yellow', 'green'])
    im = ax.imshow(array, cmap=cmap)  # 绘制图像'coolwarm'
    cbar = fig.colorbar(im, ax=ax, orientation='vertical')  # 添加颜色拉伸的图例
    cbar.set_label('Colorbar Label')
    plt.savefig(r"G:\Anaconda\ProjectYOLO\yolov5-7.0\Point Cloud/1.png")  # 将图形窗口中的内容保存到指定的路径
    plt.show()  # 显示图形
    

3 效果展示

4 总结

        对于点云数据体积的计算,格网法是个不错的选择。但是要注意格网大小的选择,如果过大可能导致体积拟合大于实际值过多。如果过小,可能很多格网都在点云的缝隙之间,这就会导致拟合的体积过小。

        大家如果对点云数据的处理感兴趣可以随时留言交流。如果觉得博主的文章对你有帮助,可以给我点个赞,加个关注,我后面会更新更多点云数据处理的教程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1312876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker的资源限制及容器应用

一、docker资源限制 在使用 docker 运行容器时&#xff0c;一台主机上可能会运行几百个容器&#xff0c;这些容器虽然互相隔离&#xff0c;但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制&#xff0c;那么容器之间会互相影响&#xff0c;小的来说…

解决多卡机器CUDA Error Code 802(CUDA_ERROR_SYSTEM_NOT_READY)

解决多卡机器安装完CUDA后&#xff0c;出现802错误码&#xff1a;Fabric Manager需要和Driver具有完全一致的版本号。 现象 检查 查看service状态&#xff1a; 显示failed&#xff0c;查看nvidia-smi中的Driver版本&#xff1a; 切换版本 sudo yum list installed | grep…

BERT大模型:英语NLP的里程碑

BERT的诞生与重要性 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;大模型标志着自然语言处理&#xff08;NLP&#xff09;领域的一个重要转折点。作为首个利用掩蔽语言模型&#xff08;MLM&#xff09;在英语语言上进行预训练的模型&…

初学python的体会心得20字,初学python的体会心得2000

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;学了python的心得体会200字&#xff0c;初学python的体会心得20字&#xff0c;现在让我们一起来看看吧&#xff01; 本学期&#xff0c;我们学习了杨老师的《python语言程序设计》这门课程&#xff0c;其实早在大一期间…

【每日一题】【12.15】2415.反转二叉树的奇数层

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 2415. 反转二叉树的奇数层https://leetcode.cn/problems/reverse-odd-levels-of-binary-tree/ 今天终于碰到了一个mid题目&#x…

[Unity]关于Unity接入Appsflyer并且打点支付

首先需要去官方下载Appsflyer的UnityPackage 链接在这afPackage 然后导入 导入完成 引入此段代码 using AppsFlyerSDK; using System.Collections; using System.Collections.Generic; using UnityEngine;public class AppflysManager : MonoBehaviour {public static App…

【算法与数据结构】332、LeetCode重新安排行程

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题比较属于困难题目&#xff0c;难点在于完成机票、出发机场和到达机场之间的映射关系&#xff0c;再…

Airtest-Selenium实操小课①:爬取新榜数据

此文章来源于项目官方公众号&#xff1a;“AirtestProject” 版权声明&#xff1a;允许转载&#xff0c;但转载必须保留原链接&#xff1b;请勿用作商业或者非法用途 1. 前言 最近看到群里很多小伙伴都在用Airtest-Selenium做一些web自动化的尝试&#xff0c;正好趁此机会&…

我的NPI项目之Android 安全系列 -- Google Wallet and Secure Element(SE)

随着电子支付的兴起&#xff0c;越来越多的支付方式出现在我们的生活中。其中就有基于NFC的“碰一碰”的支付&#xff0c;支付宝的“扫一扫”支付&#xff0c;我们还知道有Google Pay(Wallet), Apple Pay(Wallet)。作为Android BSP的开发者&#xff0c;我比较关心的是Google Pa…

Backtrader 文档学习-Quickstart

Backtrader 文档学习-Quickstart 0. 前言 backtrader&#xff0c;功能十分完善&#xff0c;有完整的使用文档&#xff0c;安装相对简单&#xff08;直接pip安装即可&#xff09;。 优点是运行速度快&#xff0c;支持pandas的矢量运算&#xff1b;支持参数自动寻优运算&#x…

【Qt QML入门】Button

Button表示一个推按钮控件&#xff0c;用户可以按下或单击它。 import QtQuick import QtQuick.Window import QtQuick.ControlsWindow {id: winwidth: 800height: 600visible: truetitle: qsTr("Hello World")Button {id: btnwidth: 200height: 100anchors.centerIn…

Spring+SpringMVC+SpringBoot

Spring bean bean基础配置 bean别名配置 注意事项&#xff1a; 获取bean无论是通过id还是name获取。如果无法获取到&#xff0c;将抛出异常NoSuchBeanDefinitionException bean的作用范围配置 适合交给容器进行管理的bean 表现层对象、业务层对象、数据层对象、工具对象 不…

【数学知识】LCP42: 玩具套圈

作者推荐 【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数 本文涉及的基础知识点 优化后&#xff0c;就不需要二分了。 二分查找算法合集 题目 「力扣挑战赛」场地外&#xff0c;小力组织了一个套玩具的游戏。所有的玩具摆在平地上&#xff0c;toys…

开源BI 平台AJ-Report —— 筑梦之路

AJ-Report: AJ-Report是一个完全开源&#xff0c;拖拽编辑的可视化设计工具。三步快速完成大屏&#xff1a;配置数据源---->写SQL配置数据集---->拖拽生成大屏。让管理层随时随地掌控业务动态&#xff0c;让每个决策都有数据支撑。

[渗透测试学习] Sau - HackTheBox

首先是信息搜集&#xff0c;nmap扫一下 nmap -sV -sC -p- -v 10.10.11.224 发现存在两个端口&#xff0c;55555端口有http服务&#xff0c;访问一下 获得线索request-baskets版本为1.2.1&#xff0c;搜索发现存在漏洞 那么我们试试构造ssrf&#xff0c;create的时候bp抓包 构…

【教程】源代码加密、防泄密软件

​ 什么是代码混淆&#xff1f; 代码混淆 是一种将应用程序二进制文件转换为功能上等价&#xff0c;但人类难于阅读和理解的行为。在编译 Dart 代码时&#xff0c;混淆会隐藏函数和类的名称&#xff0c;并用其他符号替代每个符号&#xff0c;从而使攻击者难以进行逆向工程。 …

PyQt6 QFrame分割线控件

锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计46条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话版…

Vue3-20-组件-父组件给子组件传值

情景说明 当父组件使用子组件的时候&#xff0c; 我们可能会需要将某些父组件的变量值 传递 给 子组件&#xff0c;在子组件中进行使用。此时就有一个 【父组件】传值给【子组件】的动作。 这就是本文我们要讨论的问题。主要问题有两个 &#xff1a; 1、【子组件】 如何接收值…

Zoho Desk与Zendesk详细对比:热门在线客服系统之争

企业需要一款功能强大且丰富的客服系统产品为其解决客户服务的难题。对于了解过Zendesk的企业来讲&#xff0c;可能会考虑到还有哪些产品可供选择&#xff0c;便于对比选择出更合适的产品。这篇文章就为大家展现了一款和Zendesk功能相似的产品——Zoho Desk&#xff0c;在功能、…

辅助电源交流220V转5V200mA输出,不需要变压器

辅助电源交流220V转5V200mA输出&#xff0c;不需要变压器。 在当今智能家居、小家电等电子产品日益普及的时代&#xff0c;对辅助电源的需求也越来越大。一款高效、低成本、小巧封装的辅助电源芯片成为众多产品的迫切需求。今天&#xff0c;我们将为您介绍一款交流220V转5V200m…