从遥感数据(视觉图像和LiDAR)中提取树冠区域


13

我正在寻找一种处理遥感图像并从图像中提取单个树木的树冠区域的方法。

我既有可见波长的面影像,又有该区域的激光雷达数据。所讨论的位置是沙漠地区,因此树木的覆盖范围不如森林区域那么茂密。航拍图像的分辨率为0.5英尺乘0.5英尺。激光雷达的分辨率约为1 x 1英尺。视觉数据和激光雷达均来自亚利桑那州的皮马县数据集。我在这篇文章的末尾有一个关于航空影像类型的样本。

这个问题在ArcMap中检测单树吗?似乎是同一个问题,但似乎没有一个好的答案。

通过使用Arcmap中的Iso聚类分类,我可以获得该地区的植被类型的合理分类(以及有关总覆盖率的信息),但这几乎没有提供有关单个树木的信息。我最想要的是通过Arcmap中的栅格转多边形功能将等容集分类的输出传递给结果的结果。问题在于该方法将树木附近合并为一个多边形。

编辑:我可能应该包括有关我所拥有的更多细节。我拥有的原始数据集是:

  • 完整的las数据,以及从中生成的tiff栅格。
  • 视觉图像(如所示的示例图像,但覆盖的范围更大)
  • 手动直接测量该地区树木的子集。

从这些我生成:

  1. 地面/植被分类。
  2. DEM / DSM栅格。

航空影像样本


您拥有的数据比链接更多。您是否拥有分类的las文件,或者只有DEM / DSM栅格(哪个?)?这真的不容易与任意精度只是视觉波长做到这一点。
Michael Stimson

我可能应该包括一些关于我所拥有的更多细节。我拥有的原始数据集是:1.完整的las数据,以及从中生成的tiff栅格2.视觉图像(如所示的示例图像,但覆盖的范围更大)3.手动直接测量树中的子集该地区。从这些数据中,我得出:1.地面/植被分类2. DEM / DSM栅格
Theodore Jones

您可以使用电子认知吗?如果没有,您可以访问或知道哪些图像处理软件或编程语言?
亚伦

我没有eCognition的副本,但我将检查我实验室/大学中认识的任何人是否拥有它,因为它在此类事物中似乎很受欢迎。我精通Python,C和Java。我有一份Matlab的副本,但我对此很不满意。我可以访问此列表上的任何软件softwarelicense.arizona.edu/students,当然还有ArcGIS。
西奥多·琼斯

我在商业应用程序中有更多细节。我链接的软件列表中的一些软件包括Matlab,Mathematica,JMP和其他统计工具以及诸如Visual Studio之类的软件开发工具。
西奥多·琼斯

Answers:


10

关于光谱和激光雷达数据中的单个冠部检测,有大量文献。明智的方法,也许开始于:

Falkowski,MJ,AMS Smith,PE Gessler,AT Hudak,LA Vierling和JS Evans。(2008)。针叶林冠层覆盖对使用激光雷达数据的两种单独的树木测量算法的准确性的影响。加拿大遥感杂志34(2):338-350。

Smith AMS,EK Strand,CM Steele,DB Hann,SR Garrity,MJ Falkowski,JS Evans(2008)通过多时相空中摄影中杜松侵害的逐对象分析生产植被空间结构图。加拿大期刊遥感34(2):268-285

如果您对Wavelet方法感兴趣(Smith等,2008),我已经用Python对其进行了编码,但是它非常慢。如果您有Matlab的经验,可以在生产模式下实现。我们有两篇论文使用小波方法和NAIP RGB-NIR图像在俄勒冈州东部发现了约600万英亩的杜松侵害,因此已得到充分证明。

Baruch-Mordo,S.,JS Evans,J.Severson,JD Naugle,J.Kiesecker,J.Maestas和MJ Falkowski(2013)从树上拯救鼠尾草:一种主动的解决方案,可减少对候选人的关键威胁物种生物保护167:233-241

Poznanovic,AJ,MJ Falkowski,AL Maclean和JS Evans(2014)瞻博网络林木检测算法的准确性评估。摄影测量工程与遥感80(5):627–637

在一般的对象分解中,有一些有趣的方法可以从应用数学状态空间文献中使用多分辨率高斯过程分解整个尺度上的对象特征。我使用这些类型的模型来描述生态模型中的多尺度过程,但可以对其进行分解以分解图像对象的特征。很有趣,但是有点深奥。

Gramacy,RB和HKH Lee(2008)贝叶斯树状高斯过程模型及其在计算机建模中的应用。美国统计协会杂志,103(483):1119-1130

Kim,HM,BK Mallick和CC Holmes(2005)使用分段高斯过程分析非平稳空间数据。美国统计协会杂志,100(470):653–668


+1特别是对于选项4;由于OP具有激光雷达数据,因此值得在冠层曲面模型上运行小波方法。虽然,正如您所知,小波方法尚未真正成为主流(也许曾经)。
亚伦

为了表达“一刀切”的理想,我将开始将商业软件(例如ESRI,ERDAS)称为Big-box软件。最好的解决方案,或者根本没有解决方案,在“大型软件”中不可用。通常,人们必须将目光投向发展领域或学术界,以寻求复杂的空间分析问题的答案。这使您急忙脱离主流。幸运的是,这些社区喜欢分享。这也是为什么分析师不要依赖按钮式解决方案很重要的原因。
杰弗里·埃文斯

2
对于复杂的空间问题,我倾向于同意BBS。但是,在干旱环境中提取一种类型的植被(尤其是如果您可以访问激光雷达数据的话)是非常主流的。在这种情况下,无需通过开发一种用于简单树识别的新方法来重新发明轮子。我的想法是为什么不使用预先建立的按钮式方法,尤其是在像eCognition这样的软件包中,它非常适合自动化?
亚伦

1
我应该补充一点,电子认知具有单独的皇冠ID的功能。例如,您可以在eCog社区中找到一个使用种子生长方法的示例规则集-搜索“油棕榈树轮廓示例规则集”。集成eCog的新模板匹配算法和这种种子增长方法可能是一种非常强大的方法。
亚伦

1
我对您为Smith(2008)Wavelet方法提到的python代码感兴趣。它可以在任何地方使用吗?
Alpheus

3

要创建DHM从DEM中减去DEM,可以在Esri Raster CalculatorGDAL_CALC中完成。这会将您的所有海拔都放在“公平的竞争环境”上。

语法(用完整的路径代替DEM,DSM和DHM):

GDAL_CALC.py -A DSM -B DEM --outfile=DHM --CALC "A-B"

DHM几乎为0(或足够接近),您可以将其设为nodata值。使用栅格计算器或GDAL_CALC,您可以根据在DHM中观察到的噪声量提取比任意值更多的值。这样做的目的是减少噪声并仅突出植被的树冠-在两个“树”相邻的情况下,应将其分成两个不同的斑点。

语法(将完整路径替换为二进制和DHM,将观察值替换为值):

GDAL_CALC.py -A DHM --outfile=Binary --calc "A*(A>Value)"

现在,使用GDAL_CALC或Esri IsNull创建一个二进制栅格,可以使用GDAL_Polygonize或Esri Raster将其多边形化为Polygon

要优化多边形,请删除过小的多边形,然后将它们与RGB波段进行比较以寻找特征,在Esri中,区域统计工具会有所帮助。然后,您可以丢弃显然没有正确统计信息的多边形(根据实验和您的数据,我无法为您提供值)。

这将使您在绘制单个冠部时达到大约80%的精度。


谢谢。我看看这种方法是否能取得良好的效果。
西奥多·琼斯

您需要做一些实验以获得适当的值,我建议裁剪一些小的区域作为样本,这些样本指示(类似于)数据中的最佳/最差区域。要获取您的参数可能需要进行六次采样操作,但这仍然比手动绘制参数要好。
Michael Stimson 2014年

3

eCognition是最好的软件,我使用其他软件做到了,但是eCognition更好。以下是有关该主题的文献参考:

M.的Karlson,H。的Reese和M.的Ostwald(2014)。使用WorldView-2影像和基于地理对象的图像分析,对半干旱西非受管理的林地(绿地)中的树冠进行制图。传感器,14(12),22643-22669。

例如http://www.mdpi.com/1424-8220/14/12/22643

另外:

Zagalikis,G.,Cameron,AD和Miller,DR(2005)。数字摄影测量和图像分析技术在获取树木和林分特征中的应用。加拿大森林研究杂志,35(5),1224-1237。

例如http://www.nrcresearchpress.com/doi/abs/10.1139/x05-030#.VJmMb14gAA


您能否解释一下为什么电子认知更好?当链接消失时,仅链接答案往往会失效。
亚伦

1
eCognition是其他基于对象的图像分析软件,自从我现在不在。我使用了类似的方法。数字摄影测量和图像分析技术在获取树木和林分特征中的应用G Zagalikis,AD Cameron,DR米勒,加拿大森林研究杂志,2005,35(5):1224-1237,10.1139 / x05-030 nrcresearchpress.com/doi /abs/10.1139/x05-030#.VJmMb14gAA
Giorgos Zagalikis 2014年

1
感谢您的参考Giorgos。我认为这些评论可以很好地编辑您的答案。
亚伦

3

几年前我也遇到过同样的问题。我有一个不需要过滤的LAS数据或其他辅助数据的解决方案。如果您可以访问LiDAR数据,并且可以从不同的返回值生成DEM / DSM / DHM(此后为DEM,我不再讨论表面模型命名法的语义),那么以下脚本可能会有用。

arcpy脚本会提取3个DEM,并吐出一个森林多边形和树点shapefile。3个DEM应具有相同的空间分辨率(即1米)和范围,并代表首次返回,最后一次返回和裸土。我有非常特定的用于蔬菜提取的参数,但是可以更改这些参数以适应其他需求。我确信可以改进这个过程,因为这是我第一次认真尝试python脚本。

# Name:         Veg_Extractor.py
# Date:         2013-07-16
# Usage:        ArcMap 10.0; Spatial Analyst
# Input:        1 meter DEMs for first returns (DEM1), last returns (DEM2), and bare earth (BE)
# Output:       forest polygon (veg with height > 4m) shapefile with holes > 500m removed;
#               tree point (veg with height > 4m, crown radius of 9 cells) shapefile
# Notes:        Raises error if input raster cell sizes differ

import arcpy, os
from arcpy import env
from arcpy.sa import *

# Check out any necessary licenses
arcpy.CheckOutExtension("spatial")

# Script arguments
dem1 = arcpy.GetParameterAsText(0) #input Raster Layer, First Return DEM
dem2 = arcpy.GetParameterAsText(1) #input Raster Layer, Last Return DEM
bare_earth = arcpy.GetParameterAsText(2) #input Raster Layer, Bare Earth DEM
outForest = arcpy.GetParameterAsText(3) #shapefile
outTree = arcpy.GetParameterAsText(4) #shapefile

# Make sure cell size of input rasters are same
arcpy.AddMessage("Checking cell sizes...")
dem1Xresult = arcpy.GetRasterProperties_management(dem1, "CELLSIZEX")
dem1Yresult = arcpy.GetRasterProperties_management(dem1, "CELLSIZEY")
dem2Xresult = arcpy.GetRasterProperties_management(dem2, "CELLSIZEX")
dem2Yresult = arcpy.GetRasterProperties_management(dem2, "CELLSIZEY")
beXresult = arcpy.GetRasterProperties_management(bare_earth, "CELLSIZEX")
beYresult = arcpy.GetRasterProperties_management(bare_earth, "CELLSIZEY")
dem1X = round(float(dem1Xresult.getOutput(0)),4)
dem1Y = round(float(dem1Yresult.getOutput(0)),4)
dem2X = round(float(dem2Xresult.getOutput(0)),4)
dem2Y = round(float(dem2Yresult.getOutput(0)),4)
beX = round(float(beXresult.getOutput(0)),4)
beY = round(float(beYresult.getOutput(0)),4)
if (dem1X == dem1Y == dem2X == dem2Y == beX == beY) == True:
    arcpy.AddMessage("Cell sizes match.")
else:
    arcpy.AddMessage("Input Raster Cell Sizes:")
    arcpy.AddMessage("DEM1: (" + str(dem1X) + "," + str(dem1Y) + ")")
    arcpy.AddMessage("DEM2: (" + str(dem2X) + "," + str(dem2Y) + ")")
    arcpy.AddMessage("  BE: (" + str(beX) + "," + str(beY) + ")")
    raise Exception("Cell sizes do not match.")

# Check map units
dem1_spatial_ref = arcpy.Describe(dem1).spatialReference
dem1_units = dem1_spatial_ref.linearUnitName
dem2_spatial_ref = arcpy.Describe(dem2).spatialReference
dem2_units = dem2_spatial_ref.linearUnitName
bare_earth_spatial_ref = arcpy.Describe(bare_earth).spatialReference
bare_earth_units = bare_earth_spatial_ref.linearUnitName
if (dem1_units == dem2_units == bare_earth_units) == True:
    if dem1_units == "Meter":
        area = "500 SquareMeters" #Area variable for meter
        unit = 1 #meter
    elif (dem1_units == "Foot_US") or (dem1_units == "Foot"):
        area = "5382 SquareFeet" #Area variable for feet
        unit = 3.28084 #feet in meter
    else:
        raise Exception("Units are not 'Meter', 'Foot_US', or 'Foot'.")
else:
    raise Exception("Linear units do not match.  Check spatial reference.")

# Local variables:
(workspace, filename) = os.path.split(outForest)
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
dem1 = Raster(dem1)
dem2 = Raster(dem2)
bare_earth = Raster(bare_earth)
nbr1 = NbrRectangle(3, 3, "CELL")
nbr2 = NbrRectangle(5, 5, "CELL")
nbr3 = NbrCircle(5, "CELL")

# Give units and multiplier
arcpy.AddMessage("Linear units are " + dem1_units + ". Using multiplier of " + str(unit) + "...")

arcpy.AddMessage("Processing DEMs...")
# Process: Raster Calculator (DEM1 - BE)
ndsm_dem1 = dem1 - bare_earth

# Process: Raster Calculator (DEM1 - DEM2)
d1_d2 = dem1 - dem2

# Process: Raster Calculator
threshold_d1d2 = (d1_d2 > (0.1 * unit))  &  (ndsm_dem1 >= (4.0 * unit))

# Process: Focal Statistics (max 3x3)
focal_max1 = FocalStatistics(threshold_d1d2, nbr1, "MAXIMUM", "DATA")

# Process: Focal Statistics (majority 5x5)
focal_majority = FocalStatistics(focal_max1, nbr2, "MAJORITY", "DATA")

# Process: Con
con_ndsm_dem1 = Con(ndsm_dem1 >= (4.0 * unit), focal_majority, focal_max1)
focal_majority = None
focal_max1 = None

# Process: Focal Statistics (min 3x3)
focal_min1 = FocalStatistics(con_ndsm_dem1, nbr1, "MINIMUM", "DATA")
con_ndsm_dem1 = None

# Process: Focal Statistics (min 3x3)
veg_mask = FocalStatistics(focal_min1, nbr1, "MINIMUM", "DATA")

# Process: Focal Statistics (max R5)
focal_max2 = FocalStatistics(ndsm_dem1, nbr3, "MAXIMUM", "DATA")

arcpy.AddMessage("Calculating tree points...")
# Process: Raster Calculator
tree_points = (veg_mask == 1) & (ndsm_dem1 == focal_max2) & (ndsm_dem1 >= (4.0 * unit))
ndsm_dem1 = None
focal_max2 = None

# Process: Raster Calculator
tree_pick = Pick(tree_points == 1, 1)
tree_points = None

# Process: Raster to Polygon
arcpy.RasterToPolygon_conversion(tree_pick, workspace + "\\tree_poly.shp", "SIMPLIFY", "Value")
tree_pick = None

# Process: Feature To Point
arcpy.AddMessage("Writing tree points...")
arcpy.env.workspace = workspace #reset workspace
arcpy.env.overwriteOutput = True #reset overwrite permission
arcpy.FeatureToPoint_management(workspace + "\\tree_poly.shp", outTree, "CENTROID")

arcpy.AddMessage("Calculating forest polygons...")
# Process: Focal Statistics (max 3x3)
forests = FocalStatistics(veg_mask, nbr1, "MAXIMUM", "DATA")
veg_mask = None

# Process: Raster Calculator
forest_pick = Pick(forests == 1, 1)

# Process: Raster to Polygon
arcpy.RasterToPolygon_conversion(forest_pick, workspace + "\\forest_poly.shp", "SIMPLIFY", "Value")

# Process: Eliminate Holes > 500 sq m (5382 sq ft)
arcpy.AddMessage("Writing forest polygons...")
arcpy.EliminatePolygonPart_management(workspace + "\\forest_poly.shp", outForest, "AREA", area, "0", "CONTAINED_ONLY")

# Clean up
arcpy.AddMessage("Cleaing up...")
arcpy.Delete_management(workspace + "\\tree_poly.shp")
arcpy.Delete_management(workspace + "\\forest_poly.shp")

2

由于评论的篇幅有限,我将其发布为答案,不希望有任何积分:)。只要您拥有DEM,就可以使用非常广泛的画笔。

  1. 提取单个多边形的DEM到dem。
  2. 定义dem的极端海拔
  3. 设置zCur + =-zStep。可以通过迭代预先找到的步骤,例如“树顶单元”高程和相邻节点之间的合理下降
  4. 低于= Con(dem => zCur,int(1))
  5. 下面的分组区域。足够大,那是“树”。目视检查,初步研究在这里需要定义吗?
  6. 如果zCur> zMin转到步骤3,否则转到步骤1。

过程中的最大组数=单个多边形内的树数。其他条件,例如多边形内“树”之间的距离可能会有所帮助...使用内核进行DEM平滑也是一种选择。


我相信您指的是DSM,而不是DEM。通常,树,结构和其他垃圾不会将其变成DEM,而是DSM(负噪声类)中的功能。DSM-DEM = DHM(高度模型)。即使仅分类为地面/非地面,也可以从LiDAR数据中合理地提取所有这些数据,但是如果您拥有DEM而不是LAS,那么您将无所适从,这是一条小河,因为您追求的功能不是在那里
Michael Stimson 2014年

是的,您所描述的DHM可以。我对激光雷达知之甚少。
FelixIP
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.