A recent inquiry by Drone Deploy in the LAStools user forum gave us access to a nice photogrammetric point cloud for the village of Fillongley in the North Warwickshire district of England. They voted “Leave” with a whopping 66.9% according to the EU referendum results by the BBC. Before we say “Good riddance, Fillongley!” we EU-abuse this little village one last time and remove all their low noise points to create a nice Digital Terrain Model (DTM). The final result is shown below.
After downloading the data it is useful to familiarize yourself with the point number, the point density and their geo-location, which can be done with lasview, lasinfo, and lasgrid using the command lines shown below. There are around 50 million points and their density averages close to 70 points per square meter.
lasview -i 0_photogrammetry\points.laz lasinfo -i 0_photogrammetry\points.laz ^ -cd ^ -o 1_quality\fillongley.txt lasgrid -i 0_photogrammetry\points.laz ^ -step 0.50 ^ -rgb ^ -fill 1 ^ -o 1_quality\fillongley.png
The first step is to use lastile and create smaller and buffered tiles for these 50 million photogrammetry points. We use a tile size of 200 meters, request a buffer of 25 meters around every tile, and flag buffer points as withheld so they can be easily be dropped later.
lastile -i 0_photogrammetry\points.laz ^ -tile_size 200 -buffer 25 -flag_as_withheld ^ -o 2_tiles_raw\fillongley.laz -olaz
Next we use a sequence of four modules, namely lasthin, lasnoise, lasground, and lasheight with fine-tuned parameters to remove the low noise points that are typical for point clouds generated from imagery by photogrammetry software. A typical example for such noise points are shown in the image below.
lasview -i 2_tiles_raw\fillongley_596000_5815800.laz ^ -inside 596050 5815775 596150 5815825 ^ -kamera 0 -89 -1.75 0 0 1.5 ^ -point_size 3
The idea to identify those clumps of noise is to construct a surface that is sufficiently close to the ground but always above the noise so that it can be used to classify all points beneath it as noise. However, preserving true ground features without latching onto low noise points often requires several iterations of fine-tuning the parameters. We did this interactively by repeatedly running the processing on only two representative tiles until a desired outcome was achieved.
First we use lasthin to give the point the classification code 8 that is closest to the 20th percentile in elevation within every 90 cm by 90 cm cell (but only if the cells containing at least 20 points). Choosing larger step sizes or higher percentiles resulted in missing ground features. Choosing smaller step sizes or lower percentiles resulted in low noise becoming part of the final ground model.
lasthin -i 2_tiles_raw\fillongley_*.laz ^ -step 0.90 ^ -percentile 20 20 ^ -classify_as 8 ^ -odir 3_tiles_temp1 -olaz ^ -cores 4
The we run lasnoise only points on the points with classification code 8 (by ignoring those with classification code 0) and reclassify all “overly isolated” points with code 12. The check for isolation uses cells of size 200 cm by 200 cm by 50 cm and reclassifies the points in the center cell when the surrounding neighborhood of 27 cells has only 3 or fewer points in total. Changing the parameters for ‘-step_xy 2.00 -step_z 0.50 -isolated 3’ will remove noise more or less aggressive.
lasnoise -i 3_tiles_temp1\fillongley_*.laz ^ -ignore_class 0 ^ -step_xy 2.00 -step_z 0.50 -isolated 3 ^ -classify_as 12 ^ -odir 3_tiles_temp2 -olaz ^ -cores 4
Next we use lasground to ground-classify only the surviving points (that still have classification code 8) by ignoring those with classification codes 0 or 12 and set their classification code to ground (2) or non-ground (1). The temporary surface defined by the resulting ground points will be used to classify low points as noise in the next step.
lasground -i 3_tiles_temp2\fillongley_*.laz ^ -ignore_class 0 12 ^ -town -ultra_fine ^ -odir 3_tiles_temp3 -olaz ^ -cores 4
Then we use lasheight to classify all points that are 20 cm or more below the triangulated surface of temporary ground points as points as noise (7) and all others as unclassified (1).
lasheight -i 3_tiles_temp3\fillongley_*.laz ^ -classify_below -0.20 7 ^ -classify_above -0.20 1 ^ -odir 4_tiles_denoised -olaz ^ -cores 4
The progress of each step is illustrated visually in the two image sequences shown below.
Now that all noise points are classified we start a standard processing pipeline, but always ignore the noise points that are now classified with classification code 7.
The processing steps below create a 25 cm DTM raster. We first use lasthin to classify the lowest non-noise point per 25 cm by 25 cm cell. Considering only those lowest points we use lasground with options ‘-town’, ‘-extra_fine’, or ‘-bulge 0.1’. Using las2dem the resulting ground points are interpolated into a TIN and rasterized into a 25 cm DTM cutting out only the center 200 meter by 200 meter tile. We store the DTM raster as a gridded LAZ for maximal compression and finally merge these gridded LAZ files to create a hillshaded raster in PNG format with blast2dem.
lasthin -i 4_tiles_denoised\fillongley_*.laz ^ -ignore_class 7 ^ -step 0.25 ^ -lowest ^ -classify_as 8 ^ -odir 5_tiles_thinned_lowest -olaz ^ -cores 4 lasground -i 5_tiles_thinned_lowest\fillongley_*.laz ^ -ignore_class 1 7 ^ -town -extra_fine -bulge 0.1 ^ -odir 6_tiles_ground -olaz ^ -cores 4 las2dem -i 6_tiles_ground\fillongley_*.laz ^ -keep_class 2 ^ -step 0.25 ^ -use_tile_bb ^ -odir 7_tiles_dtm -olaz ^ -cores 4 blast2dem -i 7_tiles_dtm\fillongley_*.laz -merged ^ -hillshade ^ -step 0.25 ^ -o dtm_hillshaded.png
The processing steps below create a 25 cm DSM raster. We first use lasthin to classify the highest non-noise point per 25 cm by 25 cm cell. With las2dem the highest points are interpolated into a TIN and rasterized into a 25 cm DSM cutting out only the center 200 meter by 200 meter tile. Again we store the raster as gridded LAZ for maximal compression and merge these files to create a hillshaded raster in PNG format with blast2dem.
lasthin -i 4_tiles_denoised\fillongley_*.laz ^ -ignore_class 7 ^ -step 0.25 ^ -highest ^ -classify_as 8 ^ -odir 8_tiles_thinned_highest -olaz ^ -cores 4 las2dem -i 8_tiles_thinned_highest\fillongley_*.laz ^ -keep_class 8 ^ -step 0.25 ^ -use_tile_bb ^ -odir 9_tiles_dsm -olaz ^ -cores 4 blast2dem -i 9_tiles_dsm\fillongley_*.laz -merged ^ -hillshade ^ -step 0.25 ^ -o dsm_hillshaded.png