从点云创建 DSM:网格化和可视化实用指南

今天我将向您展示如何从点云创建数字表面模型(DSM)。首先,我们将尝试了解 DSM 是什么,然后我们将进入讨论的更实际部分。

什么是 DSM?

DSM 是一个描述表面及其表面所有内容的模型。现在,为了更清楚地了解 DSM,您不仅对某些区域的地貌特征感兴趣,而且还对位于该表面的所有树木、灌木丛和大岩石感兴趣。然而,在 DTM(数字地形模型)中,只有地球表面,没有树木、岩石或灌木丛。这里我将创建一个DSM。要从点云生成数字表面模型 (DSM),第一步是将感兴趣的区域划分为网格。随后,为每个网格单元分配一个高程值,该高程值源自单元内或附近点的 3D 坐标(X、Y、Z)。此过程可全面呈现地球表面,捕获地形、建筑物和植被等特征。为了更好地理解网格化的工作原理,我将创建一个合成数据并自行实现网格化。

让我们首先导入必要的库:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import ticker, cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from scipy.spatial import cKDTree

创建网格区域和一些样本点:

# grid range in x and y direction
x = np.arange(8)
y = np.arange(8)
# creating high number of points (70) for this grid area 
# with x, y, z coordinates
xp = np.random.random(size=70)*8 - 0.5
yp = np.random.random(size=70)*8 - 0.5
zp = np.random.randint(10, size = 70)
# grid coodinates
xc = np.arange(8) # x coordinates 
yc = np.arange(8) # y coordinates
grc = np.meshgrid(xc, yc) # grid coordinates

现在,下一步我们将使用最近邻插值来找到距离网格中心最近的点:

tree = cKDTree(np.c_[xp, yp])
dd, ii = tree.query(np.c_[grc[0].ravel(), grc[1].ravel()], k=1)
x_close = xp[ii]
y_close = yp[ii]

可视化以便更好地理解:

plt.figure(figsize = (12, 12))
plt.xticks(x-0.5)
plt.yticks(y-0.5)
plt.scatter(xp, yp, label='Observed Points')
plt.scatter(grc[0], grc[1], label='Grid Centers')
plt.grid(color='k', linestyle='-', linewidth=2)
plt.xlim((-.5,7.5))
plt.ylim((-.5,7.5))



for i in range(len(ii)):
    plt.plot([grc[0].ravel()[i], xp[ii[i]]], [grc[1].ravel()[i], yp[ii[i]]], c='g')

#plt.text(-0.11, 7.5-0.31, 'A )', bbox=dict(fill=False, edgecolor='r', linewidth=1.25), fontsize=18)

plt.legend(bbox_to_anchor=(.95, 1.02), loc='upper left')

观察到蓝色点,橙色点是网格中心,绿线显示网格中心和距离该中心最近的点之间的连接。

然后,一旦为每个网格分配一个值,您就得到了栅格。让我们想象一下:

from matplotlib import ticker, cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots(1, figsize = (12, 12))
ax.set_xticks(x-0.5)
ax.set_yticks(y-0.5)
elv = zp[ii]
elv.shape = (x.shape[0], y.shape[0])
im = ax.imshow(np.flip(elv, 0), cmap=cm.get_cmap('PuBu_r', 9))
ax.grid(color='k', linestyle='-', linewidth=2)
ax.tick_params('both', bottom=False, top=False, left=False, right=False,
                labelbottom=False, labeltop=False, labelleft=False, labelright=False)
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cbar = fig.colorbar(im, ticks=np.arange(10), ax = ax, cax = cax)
cbar.ax.set_yticklabels(['0 m    ', '1 m    ', '2 m    ', '3 m     ', '4 m', '5 m', '6 m', '7 m', '8 m', '9 m'])  
cbar.ax.set_ylabel('Elevation of interpolated Points', rotation=270, fontsize=15)

上述合成点的栅格结果。

对现实世界数据进行网格化。

下一步,我将使用从 OpenTopography 下载的真实世界数据。可以从这里获取。让我们看看数据是什么样的:

来自 Colrado (OpenTopography) 的点云数据。

现在让我们对现实世界的点云数据进行网格化,但这次我将使用 scipy griddata 而不是编写自己的网格化操作:

import numpy as np
from scipy.interpolate import griddata
import matplotlib.pyplot as plt
import laspy
path = "pointsColoradowithoutBuilding.las"
las = laspy.read(path)
points = las.xyz
amplitude = las.intensity
red = las.red
green = las.green
blue = las.blue
from scipy.interpolate import griddata
import matplotlib.pyplot as plt

x = points[:, 0]
y = points[:, 1]
z = points[:, 2]

# Define grid parameters
xmin, xmax = np.nanmin(x), np.nanmax(x)
ymin, ymax = np.nanmin(y), np.nanmax(y)
grid_resolution = .5

# Create a grid
xi, yi = np.meshgrid(np.arange(xmin, xmax, grid_resolution), np.arange(ymin, ymax, grid_resolution))

# Interpolate elevation values
zi = griddata((x, y), z, (xi, yi), method='linear')
plt.figure(figsize=(10, 8))
new_zi = np.nan_to_num(zi, nan=np.nanmax(zi))
new_zi = np.clip(new_zi, a_min=None, a_max=z.max()+1)
plt.imshow(new_zi, extent=[xi.min(), xi.max(), yi.min(), yi.max()], cmap="terrain")
plt.colorbar(label='Elevation')
plt.title('Digital Elevation Model (DEM) with imshow')
plt.xlabel('X-coordinate')
plt.ylabel('Y-coordinate')
plt.show()

网格点云数据。

这里我使用 scipy 库中的线性插值进行网格化,结果看起来非常好。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分布式异步任务框架celery

Celery介绍 github地址:GitHub - celery/celery: Distributed Task Queue (development branch) 文档地址:Celery - Distributed Task Queue — Celery 5.3.6 documentation 1.1 Celery是什么 celery时一个灵活且可靠的处理大量消息的分布式系统&…

hcip复习总结1

OSI----------- 定义了数据的产生标准 。 7 层 应用 ------- 表示 会话 传输 -----Telnet - 23 ssh---22 http---80 https-443 TCP ---- 传输控制卋议。是一种面向连接的可靠的传输卋议。 UDP---- 用户数据报卋议。是一种非面向连接的丌可靠传输卋议。 保证可靠性&…

鸿蒙开发-UI-动画-页面间动画

鸿蒙开发-UI-组件导航-Navigation 鸿蒙开发-UI-组件导航-Tabs 鸿蒙开发-UI-图形-图片 鸿蒙开发-UI-图形-绘制几何图形 鸿蒙开发-UI-图形-绘制自定义图形 鸿蒙开发-UI-图形-页面内动画 鸿蒙开发-UI-图形-组件内转场动画 鸿蒙开发-UI-图形-弹簧曲线动画 文章目录 前言 一、放大缩…

Springboot+vue的医疗挂号管理系统+数据库+报告+免费远程调试

效果介绍: Springbootvue的医疗挂号管理系统,Javaee项目,springboot vue前后端分离项目 本文设计了一个基于Springbootvue的前后端分离的医疗挂号管理系统,采用M(model)V(view)C(con…

Kubernetes集群搭建 kubernetes集群安装

Kubeadm kubeadm 是 Kubernetes 社区提供的集群构建工具,它能够以最佳实践的方式部署一个最小化的可用 Kubernetes 集群。 但是 kubeadm 在设计上并未安装网络解决方案,所以需要用户自行安装第三方符合 CNI 的网络解决方案,如 flanal&#…

7个方便快速使用的Tkinter控件源码分享,赶快收藏

文章目录 7个快速使用的Tkinter控件源码分享1. 按钮 Button2. 开关 Checkbutton3. 显示文本 Label4. 带名称、数值显示的划动条5. 带标签的复选框6. 带名称的输入框7. 带名称的微调框7个快速使用的Tkinter控件源码分享 tkinter 是一个简单入手,但是功能十分强大的GUI编程库,学…

阶乘的强悍溢出技能

【题目描述】 输入n,计算S=1!+2!+3!+…+n!的末6位(不含前导0)。,n!表示 前n个正整数之积。 【样例输入】 …

[python]bar_chart_race设置日期格式

1、设置日期标签的时间格式 # 设置日期格式,默认为%Y-%m-%dbcr.bar_chart_race(df, covid19_horiz.gif, period_fmt%b %-d, %Y) 2、更改日期标签为数值 # 设置日期标签为数值bcr.bar_chart_race(df.reset_index(dropTrue), covid19_horiz.gif, interpolate_period…

基于springboot+vue的中山社区医疗综合服务平台

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

第二十八天-ES6标准入门和Flex布局

目录 1.ES6标准入门 2.ES6与JavaScript关系 3.ES6常用新特性 1.变量与常量 1.let三大特性 2.常量三大特征 2.解构赋值 1.数组解构赋值 2.对象解构赋值 3.字符串解构赋值 3.函数与箭头函数 1.函数 2.箭头函数 4.JS的面向对象编程 5.模块化 export使用 import使用…

QT界面制作

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);this->setWindowFlag(Qt::FramelessWindowHint);//接收动图QMovie *mv new QMovie(":/pictrue/th.gif…

二分查找算法(2)

852.山脉数组的峰顶索引 一、题目描述 即下标 i 前的所有元素都升序、后的所有元素都降序&#xff0c; i 是最大值 OJ题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09; 二、思路解析 三、代码 class Solution { public:int peakIndexInMountainArray(vector<in…

算法打卡day11

今日任务&#xff1a; 1&#xff09;239. 滑动窗口最大值 2&#xff09;347.前 K 个高频元素 239. 滑动窗口最大值 题目链接&#xff1a;239. 滑动窗口最大值 - 力扣&#xff08;LeetCode&#xff09; 给定一个数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移…

利用Python如何实现数据驱动的接口自动化测试

前言 大家在接口测试的过程中&#xff0c;很多时候会用到对CSV的读取操作&#xff0c;本文主要说明Python3对CSV的写入和读取。下面话不多说了&#xff0c;来一起看看详细的介绍吧。 1、需求 某API&#xff0c;GET方法&#xff0c;token,mobile,email三个参数 token为必填项…

【项目】基于YOLOv8和RotNet实现圆形滑块验证码(拼图)自动识别(通过识别中间圆形的角度实现)

TOC 一、引言 1.1 实现目标 要达到的效果是使用算法预测中间圆形的角度&#xff0c;返回给服务器&#xff0c;实现自动完成验证码的问题。要实现的内容如下图所示。 1.2 实现思路 思路1&#xff08;效果较差&#xff09;&#xff1a;以RotNet要实现的验证码识别为灵感&…

微信小程序(五十九)使用鉴权组件时原页面js自动加载解决方法(24/3/14)

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.使用覆盖函数的方法阻止原页面的自动执行方法 2.使用判断实现只有当未登录时才进行方法覆盖 源码&#xff1a; app.json {"pages": ["pages/index/index","pages/logs/logs"],…

python中如何生成词云

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 今天给大家看看&#xff0c;如何使用python实现根据记录创建生成词云 首先我们看下效果图。 一个是生成了新闻的词云&#xff0c;另一个是生成了聊天记录的词云。下面是代码&#xff1a; …

Java学习笔记(19)

双列集合 键值对 一一对应 键值对对象 entry Map Put第一次给不存在的key&#xff0c;会把键值对添加到map中&#xff0c;返回null Put给同一个key是会覆盖value的&#xff0c;返回被覆盖的值value Remove根据key删除键值对&#xff0c;返回被删除的值value Map遍历 键找值 …

python语法踩坑 | list的append操作如何从in-place改为out-of-place

背景 博主写python遇到一个问题&#xff0c;需要把对list添加元素改为非原地操作&#xff0c;即不修改原list。 但是由于列表中的元素是字典类型&#xff0c;无法直接用运算符。 于是写出了下面这行代码 query_list message_list.copy().append(one_question) 其中message…

Anaconda安装 (windowsLinux)

文章目录 Anaconda简介设置国内源pip || conda 一、Anaconda &#xff08;Windows系统&#xff09;1.1 下载及安装1.2 虚拟环境创建1.3 在Pycharm中配置conda的环境 二、Anaconda&#xff08;Linux系统&#xff09; Anaconda简介 conda是一个开源的包、环境管理器&#xff0c;可…