Estimating grassy volume from terrestrial LiDAR


As part of my PhD research I have been using terrestrial LiDAR to understand woodland tree canopy traits in southern African savannas. One of the measurements I wanted to make was an estimate of the volume of grassy material below the canopy, so I could make inferences about how canopy traits affect the probability of fire. In a previous post I’ve already described how I processed the raw point cloud data to produce a .csv with XYZ point coordinates, so I’ll skip straight to how I used R to estimate grassy volume. I adapted this method from Cooper et al. (2017) .

After reading in the file with data.table::fread() the first thing was to assign each point within a cylinder of grass to 2x2 cm 2D bins in the XY plane, then I took the mean height of points within each bin and estimated the volume of the column below that mean height, assuming that the volume below the mean height was completely filled by grass material. That’s quite a big assumption to make, but for comparison between samples it seems suitable. I also have Disc Pasture Meter (DPM) measurements and biomass samples on a subset of the sample locations to cross-check the estimates from the terrestrial LiDAR.

# Read file
dat <- fread(x)

# Bin into x,y cells
dat_xy_bin <- dat %>%
  bin_x = cut(.$X, include.lowest = TRUE, labels = FALSE,
    breaks = seq(floor(min(.$X)), ceiling(max(.$X)), by = voxel_dim)),
  bin_y = cut(.$Y, include.lowest = TRUE, labels = FALSE,
    breaks = seq(floor(min(.$Y)), ceiling(max(.$Y)), by = voxel_dim)))

# Take mean height of points within a column, then estimate volume
summ <- dat_xy_bin %>%
group_by(bin_x, bin_y) %>%
summarise(volume = mean(Z, na.rm = TRUE) * voxel_dim^2)

# Sum of volumes
vol <- sum(summ$volume, na.rm = TRUE)