How to Calculate Point Cloud Density | Creating a Custom Transformer

Liz Sanderson
Liz Sanderson
  • Updated

FME Version

  • FME 2022.1

Introduction

Before creating models or processing a point cloud, it may be necessary to understand the density of the points within the dataset. Point cloud density is an indicator of the resolution of the data: higher density means more information (high resolution) while lower density means less information (low resolution). It is important to have an understanding of point cloud density because it may impact the quality or accuracy of further projects that will be based on point clouds such as creating DEM’s. This information may also be important to report to clients who are stakeholders.
To quickly get this information and display it in a raster format, we have created a custom transformer called the PointCloudDensityCalculator. Simply connect this to your point cloud dataset and get the results. Below we describe the inner workings of this transformer to help you understand exactly what type of processing and analysis is being done. There is also an example demonstration workspace in the Files section to the right which describes how to add color to the density raster output to give more meaning and definition to your data.

 

Step-by-step Instructions

Part 1: Creating the Custom Transformer

The series of steps below describe each of the parts of the custom PointCloudDensityCalculator and how it was made. Users do not need to re-create this as they can simply download and install the transformer to use. However, if you are interested in the inner workings or would like to understand how a custom transformer can be made, these steps will be useful to you. If you would like to open the workspace for this transformer rather than just installing it, you will have to right-click on the file and choose to edit the file in FME Workbench. Alternatively, if the transformer is already installed, you can add it to your workspace, right-click on it, and select “Edit”.

 

1. Open FME Workbench

Open FME Workbench and click New to create a new workspace.

 

2. Create Custom Transformer

To begin the creation of a custom transformer, click “Transformers” on the menu bar in FME Workbench and choose “Create Custom Transformer”. This will prompt you to enter information about the transformer in a new window. After entering the information a Transformer Input and Output will be added to the workspace.

image.png

 

3. Modifying User Parameters

Before adding any transformers, we will create a new parameter. Right-click on “User Parameters'' in the Navigator window and choose “Manage User Parameters…”

image.png

Select the ‘+’ sign from the top left and choose ‘Number’.

image.png

 

4. PIXELSIZE Parameter

In the “Parameter Identifier” window, enter “PIXELSIZE” as the name, “Density Raster Pixel Size: “ as the Prompt, and 25 as the Default Value.

image.png


5. Add a ParameterFetcher

A ParameterFetcher is now connected to the Input transformer. Change the Parameter Name to “PIXELSIZE” with the Target Attribute set to _PIXELSIZE. This will take the value that is set in the transformer parameters under “Density Raster Pixel Size:” and use it in the calculations in the next transformers.

image.png

 

6. Extract Point Cloud Bounds

Now connect a BoundsExtractor to the ParameterFetcher to identify the minimum and maximum X, Y and Z attributes.


7. Calculate the Big Tile Size

An ExpressionEvaluator can now be used to calculate the value for the New Attribute called “_big_tile_size” based on the bound values that were extracted and the PIXELSIZE parameter that was created earlier. Connect the ExpressionEvaluator to the BoundsExtractor. The Arithmetic Expression used to do this is:

ceil(abs(sqrt((@Value(_xmax)-@Value(_xmin))/@Value(_PIXELSIZE))))*@Value(_PIXELSIZE)

image.png


8. Original Point Cloud into Big Tiles

A Tiler is used to tile the point clouds. Add two Tilers to the canvas and connect one to the ExpressionEvaluator and the other to the first Tiler. We will use two tilers to do this to lessen the processing memory used. This is done by using the first Tiler to calculate large tiles that are then reduced to the assigned pixel size value rather than creating the small tiles directly. This will be done based on the attribute “_big_tile_size” that was just created. Set “_big_tile_size” as the Tile Width and Height in the parameters.

image.png

Now we will use a second Tiler to create tiles that are the user-specified size. Set the Tile Width and Height in the parameters to the User Parameter “PIXELSIZE”.

image.png

The images below show how processing memory varies between using just the “PIXELSIZE” based Tiler versus using both the “PIXELSIZE” Tiler and the “_big_tile_size” Tiler. Although the processing time is faster when you just use the one Tiler, the processing memory usage is 72% less when you use the two-tiered tiler set up. This is especially useful if the user defined pixel size is very small and the point cloud is area is very large.

Using Two Tilers with Pixel Size 25
image.png

Using One Tiler with Pixel Size 25
image.png



9. Extract the Number of Points Per Point Cloud Tile

Connect a PointCloudPropertyExtractor to the second Tiler to calculate how many points fall into each tile. This transformer automatically creates a new attribute column called “_num_points” to record the number of points.


10. Replace Point Clouds with Rectangles

Connect a BoundingBoxReplacer to the canvas and connect it to the PointCloudPropertyExtractor. Using a BoundingBoxReplacer, the tiles will be replaced with a box.


11. Force to 3D using Number of Points as Elevation

A 3DForcer is connected to the “Box” output to raise the elevation of the tiles by the number of points (_num_points) in the tile. This means tiles with more points (higher density of points) will be higher than tiles with fewer points.

image.png


12. Rasterize to Numeric Raster

We will now create a raster using the NumericRasterizer. Connect a NumericRaterizer to the output of the 3DForcer. Change the parameters so that Size Specification is set to “CellSize” and the X and Y Cell Spacing is set to the “PIXELSIZE”. The Interpretation Type should also be set to UInt32. The “Raster” output of this transformer can be connected to the “RASTER” Output transformer.

image.png


13. Final Steps

The custom transformer is now complete. You can rename the input and output ports to PointCloud and DensityRaster, respectively. The result of using the transformer will be a black and white raster where each pixel has a value that describes the point cloud density (points within the pixel). These values will vary depending on the user defined Pixel Size set under the transformer parameters. Using a raster to represent point cloud density makes it very easy to see if the area within the point cloud that you are interested in, and meets your requirements for further projects and manipulations. For example, are there enough ground points to create an accurate DEM?

 

image.png

 

Part 2: Color Coding a Point Density Raster

With a few extra transformers, we can make the raster created by the PointCloudDensityCalculator a bit more descriptive. The City of Gävle provided us with a point cloud of the city and we were able to create both a density raster and color coded density raster version of this point cloud as seen in the below images:


Point Cloud

gavel-pc.png

 

Density Raster

gavel-dr.png

 

Color Coded Raster

gavel-ccr.png

 

The demonstration below shows how a color-coded raster can be created using a point cloud for the City of Vancouver. The results show a different pattern than that seen with the City of Gävle due to a different type of scanning system being used to collect points. To re-create this workflow, follow these steps:

 

1. Read in the LAS Dataset

First, add an ASPRS Reader to read the LAS dataset for the City of Vancouver.

 

2. Add the PointCloudDensityCalculator

Next, connect the PointCloudDensityCalculator custom transformer which can be downloaded and installed from FME Hub. The raster output of this transformer is a black and white density raster.

 

3. Remove “NoData” Pixels

Connect a RasterBandNoDataRemover to the “RASTER” output. This will remove any pixels that have no data. Doing this helps to make the processing quicker and more efficient.

 

4. Create Colors to Represent Density

A RasterExpressionEvaluator can now be connected to the previous output. This transformer is critical for creating colors to represent certain pixel densities. Set the interpretation to UInt8. This is necessary as the RasterPalletteAdder which will be used only reads UInt8 values. Set the expression to:

if(A[0]==0,0,if(A[0]<100,1,if(A[0]<150,2,if(A[0]<200,3,if(A[0]<300,4,if(A[0]<400,5,if(A[0]<500,6,7)))))))


This expression creates values 0 through 7. The values are assigned based on point density per pixel. In this expression, if there are 0 points/pixel, the value is set to 0. If there are less than 100 points/pixel, the value is set to 1. If there are less than 150 points/pixel the values are set to 2, etc. If you are attempting to follow this exercise using a different point cloud, the density measurements assigned to the values will likely need to be altered to match your point cloud better. You may also use more or fewer values (ie. more or fewer colors) if you would like.

image.png

 

5. Define Colors

Connect an AttributeCreator to the “Results” of the RasterExpresionEvaluator. This transformer is used to define the colors that we will be assigning the previously set values. To do this, create a New Attribute in the parameters called “_palette”. Open the Text Editor for the Attribute Value and enter:
 

RGB24
0 255, 255, 255
1 255, 0, 0
2 255, 127, 0
3 255, 255, 0
4 127, 255, 0
5 0, 255, 0
6 60, 180, 60
7 0, 100, 0



The first line will signify that we are assigning color values to the _palette attribute. If the value is 0 (0 points/pixel), then the color will be 255,255,255 which is white. This pattern of assigning colors to values continues.


attributecreator.jpg

 

6. Set the Color Palette

From the AttributeCreator output connect a RasterPaletteAdder. The Palette Attribute should be set to “_palette”. This is the final step for assigning the colors to the pixel.

7. Add an Inspector to View Data

Now the output from the RasterPaletteAdder can be viewed in FME Data Inspector by connecting an Inspector to the “Output” port. The result should look like the last image, color coded raster.

This demonstration results in a different pattern than that seen for the City of Gävle due to the type of LiDAR scanning system used. We are still able to see much more clearly exactly where the point cloud density is high and where it is low.


Point Cloud

van-pc.jpg

 

Density Raster

van-density.jpg

 

Color Coded Raster

van-color.jpg

 

To learn more about adding color to rasters, please visit our article on Raster Calculations and Raster Palettes

 

Additional Resources

 

Data Attribution

The data used here originates from open data made available by the City of Vancouver, British Columbia. It contains information licensed under the Open Government License - Vancouver.

 

 

 

Was this article helpful?

Comments

0 comments

Please sign in to leave a comment.