App Note: Using Helios2+ with the Point Cloud Library for Dimensioning

Helios2+ camera setup for capturing a 3D point cloud of cardboard boxes.

A point cloud of stacked cardboard boxes on a pallet that has been labeled with dimensions, depth, and outline.

Introduction

Helios2 Time-of-flight cameras from LUCID Vision Labs produce depth measurements of a scene as point clouds, which are data consisting of points in 3D space relative to the camera. The open-source Point Cloud Library (PCL) is a powerful way to process point clouds produced by these cameras.

This App Note demonstrates the processing and display of point clouds for a dimensioning application that uses the Helios2+ camera. The code examples described below use PCL to extract surfaces from the point cloud and overlay useful information such as dimensions, depth, and bounding boxes.

The code examples are optimized for the Helios2+ camera. Although this code can be used by any camera in the Helios2 series, the parameters would have to be changed accordingly.

Overview of PCL

The Point Cloud Library (PCL) is an open-source library for point cloud processing. Its features include a simple interactive visualization of a point cloud, estimating surface normals to analyze smoothness, filtering / downsampling a point cloud, and more advanced algorithms including registration (to align point clouds) and segmentation (to break a point cloud into more recognizable segments / surfaces).

Note: The application described below is only one possible use case of PCL with our Time-of-Flight cameras. Our current examples use several features offered by PCL, and depending on your application and setup, many other features can be used in a similar way to how we demonstrate in this App Note. Examples can include using Helios2 Narrow cameras to analyze and process targets at a much closer range, or using several of our Helios2+ cameras to analyze and stitch multiple point clouds together.

PC configuration

  • Processor: i9-13th generation Intel processor
  • RAM: 32 GB
  • OS: Windows 11 Pro

Software setup

Install the Arena SDK

Download the Arena SDK from the LUCID website, and install it selecting the Developer option when prompted.

Install PCL

To install the PCL library, it is recommended to first install a package manager. PCL lists several package managers here: https://pointclouds.org/downloads/.  This application was created in Windows, and we used vcpkg. To use vcpkg to install PCL, follow the steps below:

Before you install PCL using vcpkg, ensure you have an instance of Visual Studio installed on your system. The PCL installation will fail if it cannot find an instance of Visual Studio; Visual Studio Community is a readily available choice.

  1. Navigate to the github repo for vcpkg.
  2. Git clone this repo onto your PC or download as a ZIP folder. Note: ensure the file path this folder is Git cloned to (or extracted to) does not have any spaces in it – this can affect the PCL installation later down the line.
  3. Navigate to vcpkg-master folder, and execute this through the terminal:
    .\bootstrap-vcpkg.bat
  4. Execute the following command to install PCL:
    vcpkg install pcl[vtk]

    This installs all the PCL libraries + VTK libraries (visual add-ons). Be sure to specify vtk in your installation to install the visualization capabilities offered by PCL – the default installation does not include this.

Install a point cloud coloring library

There are several third-party libraries that can be used to color point clouds. We used cppturbo, which is a header-only implementation for coloring point clouds.

This library is available here: https://github.com/tatsuya-s/cppturbo.

Update the environment variables

To link installed libraries with the Visual Studio C++ example projects, follow the steps below:

  1. Navigate to Environment variables on your system.
  2. Under ‘System variables’, add a new variable called ‘PCL_ROOT’ and set its value to the folder location of the vcpkg (e.g., C:\Users\<username>\Downloads\vcpkg if you git cloned the folder here, and C:\Users\<username>\Downloads\vcpkg-master if you installed as zip folder here).
  3. Add another variable called ‘TURBO_ROOT’ and set its value to the folder location of cppturbo-master (e.g., C:\Users\<username>\Downloads\cppturbo-master if you installed cppturbo-master here).
  4. After downloading our example zip folder, navigate to the folder Cpp_HTP_PCL\DLLs, copy its path, and add it to your PATH variable.

Camera setup

The Helios2+ camera is mounted to a frame to view several cardboard boxes stacked on a pallet. The camera is pointing downwards toward the center of the pallet and is placed about 1.8m above the pallet.

Schematic of the how the camera is set up in the cardboard box visualization application.

Code samples

The code samples described below can be downloaded here. This download also includes the related Visual Studio solution files.

The code samples for this application progressively build on each other.

Example name Description
Display View a native Helios2+point cloud live stream via the PCL Visualizer class.
Segmentation Segment a point cloud into surfaces based on user-adjustable parameters. Region Based Segmentation is used in this example and the ones below.
Dimensioning Add bounding boxes on the segmented point clouds, and label them with segment dimensions and depth from the camera.
Multithreading Improve speed by introducing separate threads for visualization and processing (surface normal estimation + segmentation + bounding box calculation)

These code examples are described in more detail below.

Display example

This example uses PCL to show the native point cloud stream, as seen by the camera.

Before using any PCL features, this example first sets Arena SDK specific parameters for optimal stream quality, such as turning on StandardHDR on the Helios2+. The example also makes certain Arena SDK parameters user-adjustable, like ConfidenceThreshold and FlyingPixel on the Helios2+, so the user can adjust them during the stream using certain keys assigned in code. This code also uses cppturbo to color the point cloud based on depth.

This example is similar to what you would see if you connected a Helios2+ to ArenaView, the Arena SDK’s built-in camera control program.

Cardboard boxes viewed with the Display code example described in the “Display example" section. The colors are based on depth.

Cardboard boxes viewed with the Display code example. The colors are based on depth.

The user-adjustable parameters are as follows:

Parameter Location
ConfidenceThreshold Arena SDK
FlyingPixel Arena SDK

The initialization step initializes the following variables:

Variables
Point Cloud: cloudNative,

Visualizer (viewer)

Sequence of operations for the Display example.

Segmentation example

This example uses PCL’s Region Growing Based Segmentation algorithm to segment surfaces on our cardboard boxes into smaller point clouds (which are referred to as segments). The example then displays this collection of identified segments, removing points not belonging to any segment, using the previous Display code example. We display PCL’s own output of this collection of segments, and so the color chosen for each segment is from PCL’s algorithm.

Cardboard boxes viewed with the Segmentation code example. The colors are generated by PCL for each segment.

Cardboard boxes viewed with the Segmentation code example. The colors are generated by PCL for each segment.

The user-adjustable parameters are as follows:

Parameter Location
ConfidenceThreshold Arena SDK
FlyingPixel Arena SDK
PointSize PCL
SmoothnessThreshold PCL
CurvatureThreshold PCL
Radius PCL

The initialization step initializes the following variables:

Variables
Point Cloud: cloudNative,

Point Cloud: cloudFiltered,

Point Cloud: cloudColoredBySegments,

Point Indices: segmentedClusters,

Visualizer (viewer)

Sequence of operations for the Segmentation example.

Dimensioning example

This example uses PCL’s computeCentroidAndOBB function to calculate an oriented bounding box for each segment identified in the previous code sample. This includes the bounding box’s centroid position, its dimensions, and the rotational matrix required for the box to fit onto this segment along its principal directions.

For this example, we iterate through all the segments (outputted from the segmentation algorithm), to determine the bounding box for each segment.

To make our example more structured, we create two structs:

  • segmentInfo: Stores the segmented point cloud, and its centroid (used for processing each segment).
  • bbInfo: Stores the information required to add a bounding box to the viewer.

Since we will add bounding boxes on our segments, we can easily identify each segment in the viewer. Therefore, we display the native output from the camera with all its points, colored with depth (output of the first example), and not the output with PCL’s own colors (output of the second example).

Cardboard boxes viewed with the Display code example described in the “Display example" section. The colors are based on depth.

Cardboard boxes viewed with the Display code example described in the “Display example” section. The colors are based on depth.

Cardboard boxes viewed with the Display code example described in the “Display example" section. The colors are based on depth.

Cardboard boxes viewed with the Dimensioning code example with the Display set to 2. The colors are based on depth.

This implementation also offers the following three display settings, which can be toggled using the keyboard.

Setting Description
Display 1 Add the bounding box + text for its dimensions + text for the depth of the segment, to the topmost segment. For all other segments, only add the text for depth.
Display 2 Add the bounding box + text for its dimensions + text for the depth of the segment, to all the segments.
Display 3 Add the text for the depth of the segment, to all the segments.

 

The user-adjustable parameters are as follows:

Parameter Location
ConfidenceThreshold Arena SDK
FlyingPixel Arena SDK
PointSize PCL
SmoothnessThreshold PCL
CurvatureThreshold PCL
Radius PCL
Fontsize PCL
Display settings (1 / 2 / 3) Internal

The initialization step initializes the following variables:

Variables
Point Cloud: cloudNative,

Point Cloud: cloudFiltered,

Point Cloud: cloudColoredBySegments,

Point Cloud: tempCluster

Point Indices: segmentedClusters,

Vector: currentSegments

Visualizer (viewer)

Sequence of operations for the Dimensioning example.

Multithreading example

The previous example performs the segmentation, bounding box calculation, and the visualization in a single thread.

To improve the speed, this example splits that code into two threads: one thread of processing, and the other for visualization. This implementation uses only a few variables that are shared across the two threads: one to store a new point cloud taken from the Helios2+(sharedCloud), and one to store the corresponding bounding box for that cloud’s segments (sharedBBs).

This sequence is outlined below:

  1. The visualization thread grabs a new point cloud and stores it in sharedCloud.
  2. The processing thread segments sharedCloud and computes bounding boxes for its segments. Once computed, the bounding boxes are stored in sharedBBs.
  3. The visualization thread iterates through sharedBBs and adds the appropriate details to each segment on the viewer.
  4. Repeat.

The user-adjustable parameters are as follows:

Parameter Location
ConfidenceThreshold Arena SDK
FlyingPixel Arena SDK
PointSize PCL
SmoothnessThreshold PCL
CurvatureThreshold PCL
Radius PCL
Fontsize PCL
Display settings (1 / 2 / 3) Internal

The initialization step initializes the following variables:

Thread Variables
Visualization thread Point Cloud: cloudNative,

 

Processing thread Point Cloud: cloudFiltered

Point Cloud: localCloud

Point Cloud: cloudColoredBySegments

Point Cloud: tempCluster

Point Indices: segmentedClusters

Vector: currentSegments

bbInfo: segmentBB

Shared (both) Point Cloud: sharedCloud

bbInfo: sharedBB

Boolean: newPointCloudAvailable

Boolean: newBoundingBoxesAvailable

Sequence of operations for the Multithreading example.

Sequence of operations for the Multithreading example.

Keyboard inputs

Keyboard inputs for the examples are shown below:

Category Setting Action Key Default value
General Parameters Parameter reset Revert all parameters to default values Z N/A
Camera position reset Revert camera position to default position C
Display options Display 1 Display bounding boxes, dimensions, depth only for the top surface

Display depth for every other box

7 N/A
Display 2 Display Bounding boxes, dimensions, depth for all surfaces 8
Display 3 Display depth for all surfaces 9
Camera parameters (Arena SDK) Confidence Threshold Increase 4 12000
Decrease 1
Flying Pixels Increase W 15
Decrease S
Point cloud parameters (PCL) Point Size Increase 6 1.0
Decrease 3
Font Size Increase A 80
Decrease D
Smoothness Threshold Increase Up arrow 7
Decrease Down arrow
Curvature Threshold Increase Right arrow 0.2
Decrease Left arrow
Radius Increase I (i) 140
Decrease K