Skip to content

Commit

Permalink
docs(point_filters): add documentation for downsample mask filter
Browse files Browse the repository at this point in the history
Signed-off-by: Max SCHMELLER <[email protected]>
  • Loading branch information
mojomex committed Jan 10, 2025
1 parent c553653 commit 44c1717
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
101 changes: 101 additions & 0 deletions docs/filters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Point Filters

Point filters run for every decoded point, reducing pointcloud size right at the decode stage.
This can speed up the later parts of pointcloud processing pipelines by reducing the number of points copied between and processed by modules.

## Configuration

Filters are configured via the ROS parameter namespace `point_filters`.

```yaml
{
point_filters:
filter_type_a:
# config for filter_type_a goes here
filter_type_b:
# ...
}
```

Where each `filter_type` can be specified at most once.
The configuration options available depend on the respective filter type.

Filters can also be set during runtime, e.g. via:

```shell
ros2 param set /hesai_ros_wrapper_node point_filters.filter_type_a ...'
```
## Supported Filters
The following filter types are supported:
| Filter Name | Filter Type |
| ---------------------- | ----------------- |
| Downsample Mask Filter | `downsample_mask` |
Below, each filter type is documented in detail.
### Downsample Mask Filter
This filter takes a greyscale PNG image that represents polar coordinates (x=azimuth, y=elevation)
and downsamples the pointcloud according to the lightness values of the image's pixels.

<!-- prettier-ignore-start -->
!!! note
For ring-based sensors, `y` represents the `channel` as a proxy for `elevation`.
The image height has to be equal to the sensor's number of channels.
<!-- prettier-ignore-end -->
The input image is dithered to a boolean mask:
| Stage | Image |
| :----------------------------------------- | :---------------------------------------------------: |
| Input greyscale mask | ![Greyscale mask](filters/at128_test_roi.png) |
| Internal dithered mask generated by Nebula | ![Dithered mask](filters/at128_test_roi_dithered.png) |
The decoded points are then kept/discarded based on that mask:
| ![Pointcloud density](filters/at128_test_roi_cloud.png) | ![Pointcloud closeup](filters/at128_test_roi_cloud_closeup.png) |
| -------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| Pointcloud output (2D azimuth-elevation view, points are blurred to visualize density) | Close-up view of (bottom left of the pointcloud) |
#### Configuration Options
Configuration is done in the following format:
```yaml
downsample_mask:
path: /path/to/mask.png
```
Or, during runtime, by setting:
```shell
ros2 param set /hesai_ros_wrapper_node point_filters.downsample_mask.path /path/to/mask.png'
```

The filter can be disabled by omitting the `downsample_mask` config item, or by setting `path` to an empty string:

```shell
ros2 param set /hesai_ros_wrapper_node point_filters.downsample_mask.path ""'
```
#### Behavior
- Greyscale values are quantized to the nearest 10th (yielding 11 quantization levels in total)
- Mask resolution is dictated by the sensor's maximum FoV, the number of channels (for rotational LiDARs) and the peak angular resolution:
- For a 40-channel LiDAR with `360 deg` FoV and `0.1 deg` peak azimuth resolution, the mask has to be `(360 / 0.1, 40) = (3600, 40)` pixels
- Currently, non-rotational LiDARs are not yet supported
- Image editors like GIMP use perceptual color profiles, which can lead to unexpected results (more/less downsampling than expected). Check the generated `_dithered.png` mask to see if you are affected.
- Dithering performed by Nebula is spatial only, meaning that it stays constant over time. Decoded points are checked against the nearest pixel in the dithered mask

## Compatibility Chart

| Filter | Hesai | Robosense | Velodyne |
| --------------- | :---: | :-------: | :------: |
| Downsample Mask ||||

Compatibility:
✅: compatible
❌: incompatible
Binary file added docs/filters/at128_test_roi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/filters/at128_test_roi_cloud.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/filters/at128_test_roi_cloud_closeup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/filters/at128_test_roi_dithered.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Nebula works with ROS 2 and is the recommended sensor driver for the [Autoware](
- [Design](design.md)
- [Parameters](parameters.md)
- [Point cloud types](point_types.md)
- [Point filters](filters.md)

## Supported sensors

Expand Down
4 changes: 4 additions & 0 deletions docs/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,7 @@ This parameter is used to set this preference.
### `dual_return_distance_threshold`

For multiple returns that are close together, the points will be fused into one if they are below this threshold (in meters).

### `point_filters`

Filters that are applied while decoding the pointcloud. For the full reference, see [Point filters](filters.md).

0 comments on commit 44c1717

Please sign in to comment.