iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python中怎么实现一个Progressive Morphological Filter算法
  • 561
分享到

python中怎么实现一个Progressive Morphological Filter算法

2023-06-20 20:06:41 561人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

python中怎么实现一个Progressive Morphological Filter算法,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1. 引言机载LiD

python中怎么实现一个Progressive Morphological Filter算法,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

1. 引言

机载LiDAR可以获取快速、低成本地获取大区域的高精度地形测量值。为了获取高精度DTM/DEM需要区分测量点中的地面点(由地面直接返回)及非地面点(建筑、车、植被)。众多学者采用了各种各样的方法来进行"点云地面点滤波"。(此篇博客中也进行了相关介绍,不再骜述)

2. Morphological Filters(形态学滤波)

 2.1 膨胀/腐蚀

膨胀/腐蚀是其中的两个基础操作,通俗的说膨胀/腐蚀可以扩大/减小特征的尺寸,并以此组合为开/闭操作。针对LiDAR测量点p(x, y, z),高程 z 值在(x, y)处对应的膨胀操作可以定义为:

python中怎么实现一个Progressive Morphological Filter算法

式中:(xp, yp, zp) 代表p点的相邻点,w为操作窗口(可以为一维“线”也可以为二维“矩形/圆/其他形状等”)。膨胀操作完成后会输出p点在窗口w内具有最大高程值的近邻点。
与之类似的,腐蚀操作为在p点窗口w内找到具有最低高程值的近邻点。可以通过下式进行定义:

python中怎么实现一个Progressive Morphological Filter算法

了解膨胀/腐蚀这两个基础操作之后,可以通过对其进行简单组合来来形成开/闭操作,其中开操作为先进行腐蚀再进行膨胀操作,而闭操作为先膨胀再进行腐蚀。在LiDAR数据处理中使用了“开”操作,处理效果如下图中所示:

python中怎么实现一个Progressive Morphological Filter算法

可以从图中得知:“虚线”是先进行“腐蚀”操作所形成的表面,这个表面剔除了“树木”点,但是大型建筑物却变得不完整。“实线”是对“腐蚀”操作结果进行“膨胀”操作所形成的表面,可以看出其又恢复了大型建筑的形状。基于此,我们可以知道,“开操作”具备去除地面上的细小地物,保留大型地物的能力,这种能力对于后续处理是非常重要的。

2.2 形态学滤波

上述的“开操作”只是去除了细小地物,保留了大型地物,并没有去除所有非地面点去除,而且仅仅通过一个“开操作”也不可能实现对复杂地表的提取。因此,怎么利用好“开操作”的能力进行下一步骤的提取是进一步提升的关键。
Kilian等人提出,可以在“开操作”处理后的结果中的每一个“窗口”内找到一个“最低点”,然后此窗口内的其他点若落在“最低点”的一个高程范围内则认为是地面点。这个高程范围通常根据机载LiDAR系统扫描的精度来定义,正常为20-30cm。
此方法中有两个方面对最后的结果好坏非常重要:

滤波窗口的尺寸,如果窗口尺寸设置的比较小,则可以很好的保留地面起伏的细节,但是只能去除像汽车、树木等细小地物,而对建筑物则去除效果较差(屋顶通常被认为是地面)。相反,若窗口尺寸设置的较大,则会过度去除一些“地面点”,例如,一条道路与一条小水沟相邻,若窗口尺寸大于道路的宽度,则道路可能就会被认为是非地面点(因为小水沟中的点高程较低,会被认为是窗口内的最低点,而道路点较高,被判断为非地面点)。此外,一些局部的小山丘、沙丘都极可能被“切除”。

建筑与树木在特定/局部区域的分布。

注:一个最理想的情况是我们可以设置一个“窗口”,这个“窗口”的尺寸可以足够小,能够保留地面细节。同时,还可以足够大,能够去除建筑、汽车、树木等地物。但是,这种理想情况在实际数据集中国并不存在。

为了解决这一问题,Kilian等人继续提出了可以通过改变窗口大小来多次进行滤波。每个点都被赋予一个与窗口大小相关的权重,窗口尺寸越大,点的权重越高。这种方法虽然得到了更好一些的效果,但是没有从"point level"进行区分地面点与非地面点。("point level"区分的地面点与非地面点之后可以通过插值的方法使得DEM/DTM的生成效果更好。)

3. Progressive Morphological Filters

由上述2.2节中的分析可知,传统的形态学滤波很难通过一个固定大小的窗口去检测出各种尺寸变化的不同地物。这一问题可以通过逐渐改变窗口大小来解决。
如下图中所示,首先使用一个尺寸为l1的窗口来对原始数据进行开操作。由图中的“虚线”可以看出树木等尺寸小于l1的地物被去除,且地形特征中小于l1的部分被“切除”(山丘顶部高程被替换成了l1中的最小值),但是,尺寸大于l1的建筑物被保留了下来。接着,进行下一次迭代,窗口尺寸变为l2,对上一次的处理结果进行开操作处理,结果从“实线”中可以看出,l2大于建筑的尺寸,所以建筑也被去除,但同时山丘顶部被“切除”的范围更大。

python中怎么实现一个Progressive Morphological Filter算法

需要注意的是: 通过逐渐增加窗口尺寸解决了去除不同大小地物的问题,但是又引入了"山丘"顶部等小于窗口尺寸的地形特征部分被“切除”的问题。

为了解决这一新出现的问题,可以通过引入一个高度差阈值来解决。建筑屋顶和地面点之间的高程差是“突变”(abrupt change),而地面高程是“渐变”(gradual change)。因此,二者之间高程变化中的明显区别可以帮助我们进行区分。假设dhp,1代表原始LiDAR测量值与在任意给定p点处第一次迭代表面之间的高程差,dhT,1代表高程差阈值,则如果dhp,1 ≤ dhT,1点p就被认为是地面点,反之如果dhp,1 > dhT,1就认为点p是一个非地面点。此后,令dhmax(t),1为当前迭代中初始地面点与滤波表面之间差值的最大值,则如果选取的dhT,1 > dhmax(t),1则所有的测量值都会保留。
在第二次迭代中假设上一次滤波表面和本次滤波表面的最大高程差为dhmax(t),2,则如果dhmax(t),2 < dhT,2,则高程差值在dhmax(t),2范围内的地面点都会被保留。类似的,假设在上次迭代和本次迭代之间建筑高程差值最小为dhmin(b),2(通常近似为建筑的高度),如果dhmin(b),2 > dhT,2,则建筑就会被移除。
通常设置dhT,k为研究区域第k次迭代中建筑物的最矮高程值。以dhT,k作为阈值,对于第k次迭代中的任意点p如果dhp,k < dhT,k则将其标记为地面点,反之为非地面点。通过这种方式,不同尺寸的建筑物(树)可以随着迭代窗口尺寸的增加逐步被去除。
综上所述,Progressive Morphological Filters的详细流程如下图所示:

python中怎么实现一个Progressive Morphological Filter算法

我们可以对上图总结以下四个步骤:

  1. 加载不规则点云,划分为规则网格,在每个网格中选取高程最低点(如果网格中没有点则根据最近邻点进行插值),构建最小高程表面。

  2. 使用输入的初始滤波窗口尺寸、1)中获取的最小高程表面作为第一次迭代的参数进行第一次迭代。随后,在后续的迭代中,以前一次获取的滤波表面及3)中计算的滤波窗口尺寸作为输入。每次迭代的输出有两部分:a) 形态学滤波后得到的更加光滑的表面;b) 基于不同阈值所检测出来的非地面点。

  3. 计算新的滤波窗口尺寸及不同的高程插值阈值。重复步骤2)、步骤3)直到窗口尺寸大于预设的最大窗口。

  4. 基于去除非地面测量值的数据进行生成DEM/DTM。

注意:每一次迭代中的“开操作”实际都是作用在步骤1)所划分网格中的点,所以Progressive Morphological
Filters是"point level"来对LiDAR测量值进行滤波处理的。

3.1 参数计算(窗口尺寸/高程差阈值)

在上述步骤3)中我们要变化窗口尺寸 wk和高程差阈值 dhT,k两个参数的值,以进行下一次迭代,那么这两个值是怎么计算的呢?

3.1.1 窗口尺寸

首先是窗口尺寸 wk有两种计算方式,第一种是:

python中怎么实现一个Progressive Morphological Filter算法

式中,k为迭代次数,b是初始窗口大小(由用户进行输入),最后+1是为了保证 wk为一个奇数,窗口对称。但是,如果一个研究区域具有非常大的地物,这种增加窗口尺寸速度太慢则会耗费较多时间。因此,可以使用第二种方式,通过指数增长来改变窗口大小,计算如下式:

python中怎么实现一个Progressive Morphological Filter算法

同样的,式中k为迭代次数,b是初始窗口大小(由用户进行输入),这种方式的增长速度较第一种方式快很多。

3.1.2 高程差阈值

高程差阈值与研究区域的地形坡度密不可分,因此可以通过下式进行计算:

python中怎么实现一个Progressive Morphological Filter算法

式中,dh0为初始高程差阈值,s为坡度,c为格网大小,dhmax为最大高程差阈值。

在城市区域,树木、汽车相对于建筑的尺寸小很多,所以通常是最后滤除建筑,最大高程差阈值dhmax可以设置为一个固定值(如最矮建筑物高度)。而在山区,主要的非地面点为植被,所以并没有必要设置固定的最大高程差阈值dhmax,于是dhmax通常被设置为测区内的最大高程差。

此外,坡度s通过第k次迭代的最大高程差dhmax(t),k,以及窗口尺寸wk进行计算,如下式所示:

python中怎么实现一个Progressive Morphological Filter算法

3.2 参数输入/输出

3.2.1 参数输入

  •  原始LiDAR点云数据,每个点都由(x, y, z)进行表示

  • 划分格网大小c 参数b(计算窗口尺寸)

  • 最大窗口尺寸(判断是否停止迭代)

  • 地形坡度s

  • 初始高程差阈值dh0

  • 最大高程差值dhmax

3.2.1 参数输出
  • 地面点

  • 非地面点

 3.3 PCL官方示例代码

#include <iOStream>#include <pcl/io/pcd_io.h>#include <pcl/point_types.h>#include <pcl/filters/extract_indices.h>#include <pcl/segmentation/progressive_morphological_filter.h>intmain (int arGC, char** argv){  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);  pcl::PointIndicesPtr ground (new pcl::PointIndices);  // Fill in the cloud data  pcl::PCDReader reader;  // Replace the path below with the path where you saved your file  reader.read<pcl::PointXYZ> ("samp11-utm.pcd", *cloud);  std::cerr << "Cloud before filtering: " << std::endl;  std::cerr << *cloud << std::endl;  // Create the filtering object  pcl::ProgressiveMorphologicalFilter<pcl::PointXYZ> pmf;  pmf.setInputCloud (cloud);  pmf.setMaxwindowsize (20);  pmf.setSlope (1.0f);  pmf.setInitialDistance (0.5f);  pmf.setMaxDistance (3.0f);  pmf.extract (ground->indices);  // Create the filtering object  pcl::ExtractIndices<pcl::PointXYZ> extract;  extract.setInputCloud (cloud);  extract.setIndices (ground);  extract.filter (*cloud_filtered);  std::cerr << "Ground cloud after filtering: " << std::endl;  std::cerr << *cloud_filtered << std::endl;  pcl::PCDWriter writer;  writer.write<pcl::PointXYZ> ("samp11-utm_ground.pcd", *cloud_filtered, false);  // Extract non-ground returns  extract.setNegative (true);  extract.filter (*cloud_filtered);  std::cerr << "Object cloud after filtering: " << std::endl;  std::cerr << *cloud_filtered << std::endl;  writer.write<pcl::PointXYZ> ("samp11-utm_object.pcd", *cloud_filtered, false);  return (0);}

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网Python频道,感谢您对编程网的支持。

--结束END--

本文标题: python中怎么实现一个Progressive Morphological Filter算法

本文链接: https://www.lsjlt.com/news/299931.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python中怎么实现一个Progressive Morphological Filter算法
    python中怎么实现一个Progressive Morphological Filter算法,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1. 引言机载LiD...
    99+
    2023-06-20
  • Python中怎么正确实现一个算法
    本篇文章给大家分享的是有关Python中怎么正确实现一个算法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Python算法具体操作代码示例:# -*- co...
    99+
    2023-06-17
  • Python中怎么实现一个简单遗传算法
    今天就跟大家聊聊有关Python中怎么实现一个简单遗传算法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。遗传算法遗传算法是模仿自然选择过程的优化算法。 他们没有使用"数学技...
    99+
    2023-06-16
  • python中怎么实现一个抽样回归算法
    本篇文章为大家展示了python中怎么实现一个抽样回归算法,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。12 抽查回归算法1 算法概要讨论以下算法 线性算法线性回归RIdge 岭回归LASSO 线性...
    99+
    2023-06-19
  • Python中怎么实现一个遗传算法框架
    本篇文章给大家分享的是有关Python中怎么实现一个遗传算法框架,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。算法特点以决策变量的编码作为运算对象,使得优化过程借鉴生物学中的概...
    99+
    2023-06-17
  • Python中怎么实现一个个税计算器
    Python中怎么实现一个个税计算器,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。计税方法科普个税方法这里需要知道的知识点:个税起征点调到 5000;累积预扣法:本期应预扣...
    99+
    2023-06-16
  • C++中怎么实现一个 kmp算法
    本篇文章给大家分享的是有关C++中怎么实现一个 kmp算法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。C++ kmp算法模板参数说明const T *source 待匹配的字...
    99+
    2023-06-17
  • Java中怎么实现一个TFIDF算法
    这篇文章给大家介绍Java中怎么实现一个TFIDF算法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。算法介绍最近要做领域概念的提取,TFIDF作为一个很经典的算法可以作为其中的一步处理。计算公式比较简单,如下:预处理由...
    99+
    2023-06-02
  • Python中实现一个LZ77压缩算法
    这篇文章给大家介绍Python中实现一个LZ77压缩算法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。原理介绍:首先介绍几个专业术语。lookahead buffer(不知道怎么用中文表述,暂时称为待编码区):等待编码...
    99+
    2023-06-17
  • Python中怎么实现一个感知器分类算法
    Python中怎么实现一个感知器分类算法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。感知器算法Perceptron算法是两类(二进制)分类机器学习算法。它是一种神经网络模...
    99+
    2023-06-15
  • 怎么在react中实现一个diff算法
    这期内容当中小编将会给大家带来有关怎么在react中实现一个diff算法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。单节点Diff单节点Diff比较简单,只有key相同并且type相同的情况才会尝试复用...
    99+
    2023-06-14
  • 使用python怎么实现一个洗牌算法
    使用python怎么实现一个洗牌算法?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;3、网络爬...
    99+
    2023-06-14
  • 怎么在java中实现一个gc算法
    这期内容当中小编将会给大家带来有关怎么在java中实现一个gc算法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. ...
    99+
    2023-06-14
  • PHP中怎么实现一个排序算法
    PHP中怎么实现一个排序算法,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。< //插入排序(一维数组)  function ins...
    99+
    2023-06-17
  • C#中怎么实现一个遗传算法
    这篇文章给大家介绍C#中怎么实现一个遗传算法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C#遗传算法实现代码:using System;  using System.Colle...
    99+
    2023-06-17
  • java中怎么实现一个泛型算法
    java中怎么实现一个泛型算法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。说明有界类型参数是实现泛型算法的关键。这个方法实现简单但无法编译,因为大于号的操作符(>)...
    99+
    2023-06-20
  • Vue 2.5中怎么实现一个Diff算法
    Vue 2.5中怎么实现一个Diff算法,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1.VNode对象一个VNode的实例包含了以下属性,这...
    99+
    2024-04-02
  • Python 中怎么实现一个k-means 均值聚类算法
    Python 中怎么实现一个k-means 均值聚类算法,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。scikti-learn 将机器学习分为4个领域,分别是分...
    99+
    2023-06-02
  • 怎么实现一个random shuffle算法
    这篇文章主要介绍“怎么实现一个random shuffle算法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么实现一个random shuffle算法”文章能帮助大家解决问题。...
    99+
    2023-06-30
  • 怎么在Python中实现一个PyArmadillo计算库
    怎么在Python中实现一个PyArmadillo计算库?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。python是什么意思Python是一种跨平台的、具有解释性、编译性、...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作