Obsessed with point clouds and Python? Me too!
Recently I discovered that the USGS has tons of free lidar survey data available on The National Map. Free lidar data is great, but what’s the best way to extract the data in these files to suit your needs? There’s open source software available such as CloudCompare to help you visualize your point cloud data, but if you’re a coder and you’re not interested in visualization then it can be tedious and frustrating to extract the right data or file type. Thankfully there are plenty of libraries out there for process lidar data. Check out below to see my top 3 picks for Python libraries.
Laspy
Laspy is my favorite Python library to use for working with .las and .laz files. If you’re a fan of Numpy then you’ll be off and running in no time since Laspy works directly with Numpy arrays. I like Laspy because it’s a simple, straight forward library which allows you to do all of your basic reading and writing operations with great examples for support. I also had no installation problems with Laspy on Mac or Windows whereas with libLAS I dealt with a lot of frustration trying to get it working on Windows.
Here’s an example of some code I wrote to read a .las file from the USGS TNM then write each point to a Rhino .3dm point cloud organized by classification code. Note I did use a constants file to specify which classification codes I wanted to use.
import laspy
import numpy as np
import rhino3dm
import constants
if __name__ == '__main__':
# Get Data from Las File with Laspy
las_filepath = r'filename.las'
with laspy.open(las_filepath) as f:
for points in f.chunk_iterator(1000000000):
x, y, z, classification_codes = points.x.copy(), points.y.copy(), points.z.copy(), points.classification.copy()
pts = zip(x.tolist(), y.tolist(), z.tolist(), classification_codes.tolist())
classification_codes = np.unique(np.array(classification_codes.tolist()))
# Create Rhino 3dm file
model = rhino3dm.File3dm()
model.Settings.ModelUnitSystem = rhino3dm.UnitSystem.Feet
layers_by_classification_codes = {}
for code in classification_codes:
name = f'{code}-{constants.LAS_CLASSIFICATION_CODES[str(code)]}'
point_cloud = rhino3dm.PointCloud()
props = {
'name': name,
'idx': 0,
'point_cloud': point_cloud,
}
layers_by_classification_codes[str(code)] = props
for x, y, z, code in pts:
pt = create_rhino3dm_point(x, y, z)
layers_by_classification_codes[str(code)]['point_cloud'].Add(pt)
for code, props in layers_by_classification_codes.items():
layer = rhino3dm.Layer()
layer.Name = props['name']
layer_idx = model.Layers.Add(layer)
attrs = rhino3dm.ObjectAttributes()
attrs.LayerIndex = layer_idx
model.Objects.Add(props['point_cloud'], attrs)
model.Write(f'las_to_rhino_test.3dm', 7)
WhiteboxTools
Although lesser known, WhiteboxTools is a library that is “written in Rust and has extensive support for Python-based scripting“.
Where Laspy is great for it’s no nonsense read and write functions, WhiteboxTools offers a great range of extra functions for working with .las or .laz files.
For example, you can color a lidar point set with an image (code courtesy of WhiteboxTools):
from whitebox_tools import WhiteboxTools
wbt = WhiteboxTools()
wbt.work_dir = "/path/to/data/"
in_lidar = "lidar_data.las"
in_image = "airphoto.tif"
out_lidar = "colourized_lidar.las"
wbt.lidar_colourize(in_lidar, in_image, out_lidar)
Here’s the full list of the additional functions WhiteboxTools offers:
- BlockMaximum: Creates a block-maximum raster from an input LAS file.
- BlockMinimum: Creates a block-minimum raster from an input LAS file.
- FilterLidarScanAngles: Removes points in a LAS file with scan angles greater than a threshold.
- FindFlightlineEdgePoints: Identifies points along a flightline’s edge in a LAS file.
- FlightlineOverlap: Reads a LiDAR (LAS) point file and outputs a raster containing the number of overlapping flight lines in each grid cell.
- LidarElevationSlice: Outputs all of the points within a LiDAR (LAS) point file that lie between a specified elevation range.
- LasToAscii: Converts one or more LAS files into ASCII text files.
- LidarColourize: Adds the red-green-blue colour fields of a LiDAR (LAS) file based on an input image.
- LidarGroundPointFilter: Identifies ground points within LiDAR dataset.
- LidarIdwInterpolation: Interpolates LAS files using an inverse-distance weighted (IDW) scheme.
- LidarHillshade: Calculates a hillshade value for points within a LAS file and stores these data in the RGB field.
- LidarHistogram: Creates a histogram from LiDAR data.
- LidarInfo: Prints information about a LiDAR (LAS) dataset, including header, point return frequency, and classification data and information about the variable length records (VLRs) and geokeys.
- LidarJoin: Joins multiple LiDAR (LAS) files into a single LAS file.
- LidarKappaIndex: Performs a kappa index of agreement (KIA) analysis on the classifications of two LAS files.
- LidarNearestNeighbourGridding: Grids LAS files using nearest-neighbour scheme.
- LidarPointDensity: Calculates the spatial pattern of point density for a LiDAR data set.
- LidarPointStats: Creates several rasters summarizing the distribution of LAS point data.
- LidarRemoveDuplicates: Removes duplicate points from a LiDAR data set.
- LidarRemoveOutliers: Removes outliers (high and low points) in a LiDAR point cloud.
- LidarSegmentation: Segments a LiDAR point cloud based on normal vectors.
- LidarSegmentationBasedFilter: Identifies ground points within LiDAR point clouds using a segmentation based approach.
- LidarTile: Tiles a LiDAR LAS file into multiple LAS files.
- LidarTophatTransform: Performs a white top-hat transform on a Lidar dataset; as an estimate of height above ground, this is useful for modelling the vegetation canopy.
- NormalVectors: Calculates normal vectors for points within a LAS file and stores these data (XYZ vector components) in the RGB field.
Conclusion
Sure C and C++ have good libraries for processing .las and .laz files, but Laspy and WhiteboxTools offer integration with Numpy and great extra functions for processing your lidar data. So the next time you find yourself with a point cloud on your hands, give Laspy or WhiteboxTools a shot.
Leave a Reply