新站提交
  • 网站:49052
  • 待审:1013
  • 文章:97407
  • 会员:113

本篇博客参阅Keqi Zhang的文章“A Progressive Morphological Filter for Removing Nonground Measurements From Airborne LIDAR Data”以去除大型修建、树木等常见地物。

不方便的小伙伴能够在此:资源链接下载。

1. 导言

机载LiDAR能够获取快速、低成本地获取大区域的高精度地势丈量值。为了获取高精度DTM/DEM需求差异丈量点中的地上点(由地上直接回来)及非地上点(修建、车、植被)。许多学者采用了各式各样的办法来进行"点云地上点滤波"。(此篇博客中也进行了相关介绍,不再骜述)

2. Morphological Filters(形态学滤波)

 2.1 胀大/腐蚀

胀大/腐蚀是其间的两个根底操作,浅显的说胀大/腐蚀能够扩展/减小特征的尺度,并以此组合为开/闭操作。针对LiDAR丈量点p(x, y, z),高程 z 值在(x, y)处对应的胀大操作能够界说为:

在这里刺进图片描绘

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

在这里刺进图片描绘

了解胀大/腐蚀这两个根底操作之后,能够经过对其进行简略组合来来构成开/闭操作,其间开操作为先进行腐蚀再进行胀大操作,而闭操作为先胀大再进行腐蚀。在LiDAR数据处理中运用了“开”操作,处理作用如下图中所示:

在这里刺进图片描绘

能够从图中得知:“虚线”是先进行“腐蚀”操作所构成的外表,这个外表剔除了“树木”点,可是大型修建物却变得不完整。“实线”是对“腐蚀”操作成果进行“胀大”操作所构成的外表,能够看出其又康复了大型修建的形状。根据此,咱们能够知道,“开操作”具有去除地上上的细微地物,保存大型地物的才能,这种才能关于后续处理对错常重要的。

2.2 形态学滤波

上述的“开操作”只是去除了细微地物,保存了大型地物,并没有去除一切非地上点去除,并且只是经过一个“开操作”也不或许完成对杂乱地表的提取。因而,怎样利用好“开操作”的才能进行下一过程的提取是进一步提高的要害。
Kilian等人提出,能够在“开操作”处理后的成果中的每一个“窗口”内找到一个“最低点”,然后此窗口内的其他点若落在“最低点”的一个高程规模内则以为是地上点。这个高程规模一般依据机载LiDAR体系扫描的精度来界说,正常为20-30cm。
此办法中有两个方面对最终的成果好坏非常重要:

1.滤波窗口的尺度,假如窗口尺度设置的比较小,则能够很好的保存地上崎岖的细节,可是只能去除像轿车、树木等细微地物,而对修建物则去除作用较差(房顶一般被以为是地上)。相反,若窗口尺度设置的较大,则会过度去除一些“地上点”,例如,一条路途与一条小水沟相邻,若窗口尺度大于路途的宽度,则路途或许就会被以为对错地上点(由于小水沟中的点高程较低,会被以为是窗口内的最低点,而路途点较高,被判别为非地上点)。此外,一些部分的小山丘、沙丘都极或许被“切除”。

2.修建与树木在特定/部分区域的散布。

注:一个最抱负的状况是咱们能够设置一个“窗口”,这个“窗口”的尺度能够满足小,能够保存地上细节。一起,还能够满足大,能够去除修建、轿车、树木等地物。可是,这种抱负状况在实践数据集我国并不存在。

为了处理这一问题,Kilian等人持续提出了能够经过改动窗口巨细来屡次进行滤波。每个点都被赋予一个与窗口巨细相关的权重,窗口尺度越大,点的权重越高。这种办法尽管得到了更好一些的作用,可是没有从"point level"进行差异地上点与非地上点。("point level"差异的地上点与非地上点之后能够经过插值的办法使得DEM/DTM的生成作用更好。)

3. Progressive Morphological Filters

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

在这里刺进图片描绘

需求留意的是: 经过逐渐添加窗口尺度处理了去除不同巨细地物的问题,可是又引进了"山丘"顶部等小于窗口尺度的地势特征部分被“切除”的问题。

为了处理这一新出现的问题,能够经过引进一个高度差阈值来处理。修建房顶和地上点之间的高程差是“骤变”(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则一切的丈量值都会保存。
在第2次迭代中假定上一次滤波外表和本次滤波外表的最大高程差为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的具体流程如下图所示:

在这里刺进图片描绘

咱们能够对上图总结以下四个过程:

  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有两种核算方法,第一种是:

在这里刺进图片描绘

式中,k为迭代次数,b是初始窗口巨细(由用户进行输入),最终+1是为了确保 wk为一个奇数,窗口对称。可是,假如一个研讨区域具有非常大的地物,这种添加窗口尺度速度太慢则会消耗较多时刻。因而,能够运用第二种方法,经过指数增加来改动窗口巨细,核算如下式:

在这里刺进图片描绘

相同的,式中k为迭代次数,b是初始窗口巨细(由用户进行输入),这种方法的增加速度较第一种方法快许多。

3.1.2 高程差阈值

高程差阈值与研讨区域的地势斜度密不可分,因而能够经过下式进行核算:

在这里刺进图片描绘

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

在城市区域,树木、轿车相关于修建的尺度小许多,所以一般是最终滤除修建,最大高程差阈值dhmax能够设置为一个固定值(如最矮修建物高度)。而在山区,首要的非地上点为植被,所以并没有必要设置固定的最大高程差阈值dhmax,所以dhmax一般被设置为测区内的最大高程差。

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

在这里刺进图片描绘

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>

int
main (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点云地上点滤波(Progressive Morphological Filter)算法介绍(PCL库)的文章就介绍到这了,更多相关python点云地上点滤波PCL库内容请查找脚本之家曾经的文章或持续阅读下面的相关文章期望我们今后多多支撑脚本之家!

  • 49052

    网站

  • 0

    小程序

  • 97407

    文章

  • 113

    会员

赶快注册账号,推广您的网站吧!