R Lidar Voxel Calculation – Using lidR to Calculate the Number of Null Voxels

laslidarlidrrvoxel

I have a number of LAS files (750+). I am using the package lidR to extract different metrics. I am using the following function to calculate the number of voxels in each files that contain a LiDAR return.

files <- list.files(path= "path/to/files")

O = lapply(files, function(x) { 
  las <- readLAS(x, select = "xyzc", filter = "-drop_z_below 0 -drop_class 1 2 6 7 18")
  las_voxel <- voxelize_points(las, 1.0) # Creating 1.0^3 voxels
  coverage <- npoints(las_voxel) # number of voxels containing >= 1 LiDAR return
  return(data.frame(file = x, coverage)
})

I wish to calculate the percentage of voxels that contain vegetation. I am wondering if it is possible to calculate the number of null voxels – i.e., those with 0 LiDAR returns – within this function? I have come stuck when trying to use voxel_metrics: Using lidR to calculate null voxels

Best Answer

You must define better what you mean by number of voxels with 0 points. Because there are virtually an infinite of them above the point cloud. So I guess you want to set a threshold. But what is this thresholds?

  1. The highest point in your 750 files?
  2. The highest point of each file?
  3. An arbitrary value?

Iĺl suppose you want the solution number 2. You can adapt for your needs. First you must know that voxel_metrics() has an argument all_voxels (the question you linked is older than this option)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las <- readLAS(LASfile)
vox_size = 8
vm <- voxel_metrics(las, ~length(Z), vox_size, all_voxels = TRUE) 
sum(is.na(vm$V1))
#> 1622

But I don't think it is an optimal idea. With a resolution of 1m it will likely generate more voxels than points. You can simply compute the number of voxels

las_voxel <- voxelize_points(las, vox_size)
coverage <- npoints(las_voxel)
nX = diff(range(las_voxel$X))/vox_size + 1
nY = diff(range(las_voxel$Y))/vox_size + 1
nZ = diff(range(las_voxel$Z))/vox_size + 1
nV = nX*nY*nZ
nV - coverage
#> 1622
Related Question