The Digital Forestry Toolbox (DFT) is collection of functions and tutorials for Matlab/Octave designed to help analyze remote sensing data related to forests.
Setup
- Download and uncompress the Zip or Tar archive
- If you want to use the example LAZ files included in the data folder or the external links, you must first uncompress them with LASzip
- Start Matlab/Octave
- Add the DFT folders to the Matlab/Octave search path using
addpath(genpath('path to DFT main folder'))
- Open any of the functions in Matlab/Octave and check the header for syntax and example usage
- Check the tutorials
Getting started
Reading a LAS file
Use LASread()
to import the contents of a LAS (1.0-1.4) file into a structure:
pc = LASread('myfile.las');
You can then access any of the standard LAS format blocks, e.g.:
pc.header
pc.variable_length_records
pc.record
pc.extended_variable_length_records
Displaying a 3D point cloud
To display all classes except noise points (class 7), we start by creating a logical indexing variable:
idxl_noise = ismember(pc.record.classification, 7);
We then use scatter3()
to plot non-noise points colored by return intensity:
figure
scatter3(pc.record.x(~idxl_noise), ...
pc.record.y(~idxl_noise), ...
pc.record.z(~idxl_noise), ...
6, ...
pc.record.intensity(~idxl_noise), ...
'Marker', '.');
colorbar
axis equal tight
title('Return intensity')
xlabel('X')
ylabel('Y')
ylabel('Z')
Tutorials
- Tutorial 1 - Basic point cloud manipulation and visualization
- Tutorial 2 - Individual tree crown detection using marker controlled watershed segmentation
- Tutorial 3 - Stem detection
- Tutorial 4 - Deciduous/evergreen foliage classification
License
- Unless otherwise stated in the file, the code is licensed under GNU GPL V3.
- The airborne laser scanning datasets are a courtesy of the States of Solothurn, Zürich and Geneva (Switzerland).
Reference
The Digital Forestry Toolbox was developed by Matthew Parkan (GIS Research Laboratory, EPFL) with support from the Swiss Forest and Wood Research Fund (project 2013.18).
If you use this code in your work, please consider including the following citation:
Matthew Parkan. (2018). Digital Forestry Toolbox for Matlab/Octave. DOI: 10.5281/zenodo.1213013. Available: http://mparkan.github.io/Digital-Forestry-Toolbox/.
Function and data list
Functions
The following symbols indicate GNU Octave support:
= Fully compatible
= Partially compatible
= Not compatible
Input/Output
Function | GNU Octave support | Description |
---|---|---|
LASread() |
Read 3D point cloud from ASPRS LAS (1.0-1.4) file (.las) | |
LASwrite() |
Write 3D point cloud to ASPRS LAS (1.0-1.4) file (.las) | |
HDRread() |
Read ENVI header file (.hdr) | |
SBETread() |
Read Applanix SBET trajectory file (.sbet) | |
TRJread() |
Read Terrascan TRJ trajectory file (.trj) | |
ASCread() |
Read ESRI ARC/INFO ASCII grid file (.asc) | |
ASCwrite() |
Write ESRI ARC/INFO ASCII grid file (.asc) |
Basic
Function | GNU Octave support | Description |
---|---|---|
LASclip() |
Clip 3D point cloud (LAS file) with a polygon | |
LASextent() |
Extract spatial extent of 3D point clouds (LAS files) and write result to ESRI shapefile (.shp) | |
LASmerge() |
Merge 3D point clouds (LAS files) |
Grids
Function | GNU Octave support | Description |
---|---|---|
elevationModels() |
Compute elevation models (i.e. terrain, surface, height) from a 3D classified point cloud | |
rasterize() |
Convert a 3D point cloud to a 2D raster |
Laser metrics
Function | GNU Octave support | Description |
---|---|---|
laserEchoRatio() |
Computes the echo ratio of a 3D point cloud | |
laserIntensityCorrection() |
Corrects return intensity for the sensor to target range | |
laserPulses() |
Determines the pulse number associated with the individual returns (sorted by acquisition GPS time) | |
laserTimeFormat() |
Convert GPS week time to GPS satellite time, GPS adjusted time or UTC time |
Tree metrics
Function | GNU Octave support | Description |
---|---|---|
treeStems() |
Detect individual tree stems in a 3D point cloud | |
treeWatershed() |
Extract individual tree crowns from a raster Canopy Height Model (CHM) using the (optionally marker-controlled) watershed segmentation described in Kwak et al. (2007) | |
treeMetrics() |
Computes various segment metrics based on geometry, intensity, pulse return and color characteristics |
Canopy metrics
Function | GNU Octave support | Description |
---|---|---|
canopyCover() |
Computes a canopy crown cover map using either a convolution window or the Delaunay triangulation method described in Eysn et al. (2012) | |
canopyPeaks() |
Find local maxima (peaks) coordinates in a raster Canopy Height Model (CHM) |
Utilities
Function | GNU Octave support | Description |
---|---|---|
alt2height() |
Converts 3D point cloud altitude to height above terrain | |
topoColor() |
Topological coloring (cf. Welsh and Powell, 1967) of 2D or 3D labelled points (i.e. assign distinct colors to adjacent clusters) | |
crossSection() |
Extract a 2D cross-section from a 3D point cloud | |
geomedian() |
Compute the geometric median of a an array of 3D points | |
gps2utc() |
Convert GPS satellite time (i.e. number of seconds since 1980-1-6) to UTC time | |
subsample() |
Subsample a point cloud |
Data
Airborne Laser Scanning - 3D point clouds
File | Land cover | Location | Sensor | Date |
---|---|---|---|---|
zh_2014_a.laz (external link) | Mixed forest | Zürich, Switzerland (47.58384 N, 8.76594 E, ~380 m ASL), see map | Trimble AX60 | March 10-13, 2014 |
zh_2014_b.laz (external link) | Urban, mixed forest | Zürich, Switzerland (47.37460 N, 8.56824 E, ~550 m ASL), see map | Trimble AX60 | April 2, 2014 |
so_2014_a.laz (external link) | Woodland Pasture | Solothurn, Switzerland (47.25952 N, 7.46979 E, ~830 m ASL), see map | Trimble AX60 | April 7, 2014 |
ge_2017_a.laz (external link) | Mixed forest | Geneva, Switzerland (46.29240 N, 6.13380 E, ~430 m ASL), see map | Riegl LMS-Q1560 | February 19-20, 2017 |
Airborne Laser Scanning - Rasters
File | Land cover | Location | Sensor | Date |
---|---|---|---|---|
so_2014_woodland_pasture.tif | Woodland Pasture | Solothurn, Switzerland (47.25952 N, 7.46979 E, ~830 m ASL), see map | Trimble AX60 | April 7, 2014 |
National Forest Inventories
File | Description |
---|---|
swiss_nfi_flora.xlsx | Swiss National Forest Inventory (NFI), tree species Latin/vernacular (English, French, German, Italian) names and codes |