Object Detection
TensorRT
ONNX
autoware
ros2
autonomous-driving
lidar
camera
point-cloud
sensor-fusion
pointpainting
pointpillars
Instructions to use AutowareFoundation/image_projection_based_fusion with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- TensorRT
How to use AutowareFoundation/image_projection_based_fusion with TensorRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
feat: add image_projection_based_fusion v5.0 artifacts (from awf.ml.dev.web.auto/perception/models/pointpainting/v5)
Browse files- .gitignore +5 -0
- README.md +148 -0
- deploy_metadata.yaml +1 -0
- detection_class_remapper.param.yaml +38 -0
- pointpainting_ml_package.param.yaml +24 -0
- pts_backbone_neck_head_pointpainting.onnx +3 -0
- pts_voxel_encoder_pointpainting.onnx +3 -0
.gitignore
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Auto-generated TensorRT artifacts, built locally by Autoware from the ONNX
|
| 2 |
+
# files (see autoware_tensorrt_common). They are environment-specific
|
| 3 |
+
# (GPU arch + TensorRT version) and must not be committed to this repo.
|
| 4 |
+
*.engine
|
| 5 |
+
*.json
|
README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
pipeline_tag: object-detection
|
| 4 |
+
tags:
|
| 5 |
+
- autoware
|
| 6 |
+
- ros2
|
| 7 |
+
- autonomous-driving
|
| 8 |
+
- lidar
|
| 9 |
+
- camera
|
| 10 |
+
- point-cloud
|
| 11 |
+
- sensor-fusion
|
| 12 |
+
- pointpainting
|
| 13 |
+
- pointpillars
|
| 14 |
+
- tensorrt
|
| 15 |
+
- onnx
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
# PointPainting for Autoware (`image_projection_based_fusion`)
|
| 19 |
+
|
| 20 |
+
Camera-LiDAR fusion 3D object detection model for the `pointpainting_fusion` node of the
|
| 21 |
+
[`autoware_image_projection_based_fusion`](https://github.com/autowarefoundation/autoware_universe/tree/main/perception/autoware_image_projection_based_fusion)
|
| 22 |
+
package in [Autoware](https://github.com/autowarefoundation/autoware).
|
| 23 |
+
|
| 24 |
+
Following the **PointPainting** [1] approach, LiDAR points are projected onto the output of an image-only 2D
|
| 25 |
+
object detector and the class scores are appended to each point. The painted point cloud is then fed to a
|
| 26 |
+
CenterPoint-style 3D detection network with a **PointPillars** [2] voxel encoder. The model is exported as ONNX
|
| 27 |
+
and runs with TensorRT inside Autoware; the TensorRT engine is built from the ONNX files on first launch.
|
| 28 |
+
|
| 29 |
+
## Model overview
|
| 30 |
+
|
| 31 |
+
| | |
|
| 32 |
+
| --- | --- |
|
| 33 |
+
| Task | 3D object detection (oriented bounding boxes) from a LiDAR point cloud painted with 2D detection class scores |
|
| 34 |
+
| Architecture | PointPainting point decoration + PointPillars-style voxel encoder + CenterPoint-style detection head |
|
| 35 |
+
| Detected classes | `CAR`, `TRUCK`, `BUS`, `BICYCLE`, `PEDESTRIAN` |
|
| 36 |
+
| Painted classes | `CAR`, `BICYCLE`, `PEDESTRIAN` (class scores appended to each point) |
|
| 37 |
+
| Runtime | TensorRT (FP16 by default, FP32 selectable) via the `pointpainting_fusion` ROS 2 node |
|
| 38 |
+
| Format | ONNX (Autoware builds the TensorRT engine locally on first launch) |
|
| 39 |
+
| License | Apache-2.0 |
|
| 40 |
+
|
| 41 |
+
The network is split into two ONNX sub-models, matching how the node consumes them:
|
| 42 |
+
|
| 43 |
+
1. **Voxel encoder**: `pts_voxel_encoder_pointpainting.onnx`
|
| 44 |
+
- input: `input_features` -> output: `pillar_features`
|
| 45 |
+
2. **Backbone / neck / head**: `pts_backbone_neck_head_pointpainting.onnx`
|
| 46 |
+
- input: `spatial_features` -> outputs: `heatmap`, `reg`, `height`, `dim`, `rot`, `vel`
|
| 47 |
+
|
| 48 |
+
Point painting, voxelization, and post-processing (circle NMS, IoU NMS, yaw normalization, distance-based score
|
| 49 |
+
thresholding) run in the node, not in the ONNX graphs.
|
| 50 |
+
|
| 51 |
+
Key model parameters (from `pointpainting_ml_package.param.yaml`): `point_feature_size: 7` (x, y, z, time-lag
|
| 52 |
+
and the three painted class scores), `encoder_in_feature_size: 12`, `max_voxel_size: 40000`, point cloud range
|
| 53 |
+
`[-121.6, -76.8, -3.0, 121.6, 76.8, 5.0]` m, voxel size `[0.32, 0.32, 8.0]` m, `downsample_factor: 1`.
|
| 54 |
+
|
| 55 |
+
## Files
|
| 56 |
+
|
| 57 |
+
| File | Description |
|
| 58 |
+
| --- | --- |
|
| 59 |
+
| `pts_voxel_encoder_pointpainting.onnx` | Voxel encoder |
|
| 60 |
+
| `pts_backbone_neck_head_pointpainting.onnx` | Backbone/neck/head |
|
| 61 |
+
| `pointpainting_ml_package.param.yaml` | Model parameters (classes, voxel grid, score thresholds) |
|
| 62 |
+
| `detection_class_remapper.param.yaml` | Area-based class remapping (e.g. large car -> truck/trailer) |
|
| 63 |
+
| `deploy_metadata.yaml` | Version marker for this artifact set (`version: v5.0`) |
|
| 64 |
+
|
| 65 |
+
> **TensorRT engines are not distributed here.** TensorRT engines are specific to the GPU architecture and
|
| 66 |
+
> TensorRT version they are built on and are not portable, so Autoware builds them locally from the ONNX files
|
| 67 |
+
> on first launch (or via `build_only:=true`).
|
| 68 |
+
|
| 69 |
+
## Inputs and outputs (as used by the node)
|
| 70 |
+
|
| 71 |
+
**Inputs**
|
| 72 |
+
|
| 73 |
+
| Topic | Type | Description |
|
| 74 |
+
| --- | --- | --- |
|
| 75 |
+
| `input/pointcloud` | `sensor_msgs/msg/PointCloud2` | LiDAR point cloud |
|
| 76 |
+
| `input/camera_info[N]` | `sensor_msgs/msg/CameraInfo` | Camera information to project 3D points onto image planes |
|
| 77 |
+
| `input/rois[N]` | `tier4_perception_msgs/msg/DetectedObjectsWithFeature` | ROIs from each camera's 2D object detector |
|
| 78 |
+
| `input/image_raw[N]` | `sensor_msgs/msg/Image` | Images for visualization (debug) |
|
| 79 |
+
|
| 80 |
+
One `camera_info`/`rois` pair per camera; the launch file defaults to 6 cameras (`input/rois_number`).
|
| 81 |
+
|
| 82 |
+
**Outputs**
|
| 83 |
+
|
| 84 |
+
| Topic | Type | Description |
|
| 85 |
+
| --- | --- | --- |
|
| 86 |
+
| `output/objects` | `autoware_perception_msgs/msg/DetectedObjects` | Detected objects (oriented 3D boxes with class and score) |
|
| 87 |
+
| `debug/painted_pointcloud` | `sensor_msgs/msg/PointCloud2` | Painted point cloud (debug) |
|
| 88 |
+
|
| 89 |
+
## Usage in Autoware
|
| 90 |
+
|
| 91 |
+
Autoware's setup (ansible artifacts role) downloads these artifacts to
|
| 92 |
+
`~/autoware_data/ml_models/image_projection_based_fusion/`; the node then launches with, e.g.:
|
| 93 |
+
|
| 94 |
+
```bash
|
| 95 |
+
ros2 launch autoware_image_projection_based_fusion pointpainting_fusion.launch.xml \
|
| 96 |
+
model_name:=pointpainting \
|
| 97 |
+
model_path:=$HOME/autoware_data/ml_models/image_projection_based_fusion \
|
| 98 |
+
model_param_path:=$(ros2 pkg prefix autoware_image_projection_based_fusion --share)/config/pointpainting.param.yaml
|
| 99 |
+
```
|
| 100 |
+
|
| 101 |
+
Add `build_only:=true` to build the TensorRT engine from the ONNX as a one-off pre-task.
|
| 102 |
+
See the [package README](https://github.com/autowarefoundation/autoware_universe/tree/main/perception/autoware_image_projection_based_fusion)
|
| 103 |
+
for the full parameter reference, including ROI/point cloud synchronization and matching strategies.
|
| 104 |
+
|
| 105 |
+
## Training
|
| 106 |
+
|
| 107 |
+
The model was trained by TIER IV. No public training configuration, dataset description, or training code is
|
| 108 |
+
available for this model.
|
| 109 |
+
|
| 110 |
+
## Provenance and versioning
|
| 111 |
+
|
| 112 |
+
| | |
|
| 113 |
+
| --- | --- |
|
| 114 |
+
| Original source | `https://awf.ml.dev.web.auto/perception/models/pointpainting/v5/` |
|
| 115 |
+
| Source version path | `pointpainting/v5` |
|
| 116 |
+
| Tag in this repository | `v5.0` |
|
| 117 |
+
|
| 118 |
+
## Limitations
|
| 119 |
+
|
| 120 |
+
- Only the five classes above are detected, and only car, pedestrian, and bicycle class scores are painted
|
| 121 |
+
onto the points. Other road users fall outside the label set.
|
| 122 |
+
- Multi-frame painting is not implemented yet (single-frame painting only).
|
| 123 |
+
- Fusion quality depends on accurate camera-LiDAR calibration and correct per-camera timestamp offsets
|
| 124 |
+
(`rois_timestamp_offsets`), as described in the package README.
|
| 125 |
+
- Detection accuracy depends on the upstream 2D object detector that provides the ROIs.
|
| 126 |
+
|
| 127 |
+
## Citation
|
| 128 |
+
|
| 129 |
+
```bibtex
|
| 130 |
+
@inproceedings{vora2020pointpainting,
|
| 131 |
+
title = {PointPainting: Sequential Fusion for 3D Object Detection},
|
| 132 |
+
author = {Vora, Sourabh and Lang, Alex H. and Helou, Bassam and Beijbom, Oscar},
|
| 133 |
+
booktitle = {CVPR},
|
| 134 |
+
year = {2020},
|
| 135 |
+
eprint = {1911.10150}
|
| 136 |
+
}
|
| 137 |
+
@inproceedings{lang2019pointpillars,
|
| 138 |
+
title = {PointPillars: Fast Encoders for Object Detection from Point Clouds},
|
| 139 |
+
author = {Lang, Alex H. and Vora, Sourabh and Caesar, Holger and Zhou, Lubing and Yang, Jiong and Beijbom, Oscar},
|
| 140 |
+
booktitle = {CVPR},
|
| 141 |
+
year = {2019}
|
| 142 |
+
}
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
## References
|
| 146 |
+
|
| 147 |
+
- [1] Vora et al., "PointPainting: Sequential Fusion for 3D Object Detection", arXiv:1911.10150, CVPR 2020.
|
| 148 |
+
- [2] Lang et al., "PointPillars: Fast Encoders for Object Detection from Point Clouds", CVPR 2019.
|
deploy_metadata.yaml
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
version: v5.0
|
detection_class_remapper.param.yaml
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**:
|
| 2 |
+
ros__parameters:
|
| 3 |
+
allow_remapping_by_area_matrix:
|
| 4 |
+
# NOTE(kl): We turn all vehicles into trailers if they go over 3x12 [m^2].
|
| 5 |
+
# NOTE(kl): We turn cars into trucks if they have an area between 2.2 x 5.5 and 3.0 * 12.0 [m^2]
|
| 6 |
+
# row: original class. column: class to remap to
|
| 7 |
+
#UNKNOWN, CAR, TRUCK, BUS, TRAILER, MOTORBIKE, BICYCLE,PEDESTRIAN
|
| 8 |
+
[0, 0, 0, 0, 0, 0, 0, 0, #UNKNOWN
|
| 9 |
+
0, 0, 1, 0, 1, 0, 0, 0, #CAR
|
| 10 |
+
0, 0, 0, 0, 1, 0, 0, 0, #TRUCK
|
| 11 |
+
0, 0, 0, 0, 1, 0, 0, 0, #BUS
|
| 12 |
+
0, 0, 0, 0, 0, 0, 0, 0, #TRAILER
|
| 13 |
+
0, 0, 0, 0, 0, 0, 0, 0, #MOTORBIKE
|
| 14 |
+
0, 0, 0, 0, 0, 0, 0, 0, #BICYCLE
|
| 15 |
+
0, 0, 0, 0, 0, 0, 0, 0] #PEDESTRIAN
|
| 16 |
+
|
| 17 |
+
min_area_matrix:
|
| 18 |
+
#UNKNOWN, CAR, TRUCK, BUS, TRAILER, MOTORBIKE, BICYCLE, PEDESTRIAN
|
| 19 |
+
[ 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, #UNKNOWN
|
| 20 |
+
0.000, 0.000, 12.100, 0.000, 36.000, 0.000, 0.000, 0.000, #CAR
|
| 21 |
+
0.000, 0.000, 0.000, 0.000, 36.000, 0.000, 0.000, 0.000, #TRUCK
|
| 22 |
+
0.000, 0.000, 0.000, 0.000, 36.000, 0.000, 0.000, 0.000, #BUS
|
| 23 |
+
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, #TRAILER
|
| 24 |
+
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, #MOTORBIKE
|
| 25 |
+
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, #BICYCLE
|
| 26 |
+
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000] #PEDESTRIAN
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
max_area_matrix:
|
| 30 |
+
#UNKNOWN, CAR, TRUCK, BUS, TRAILER, MOTORBIKE, BICYCLE, PEDESTRIAN
|
| 31 |
+
[ 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, #UNKNOWN
|
| 32 |
+
0.000, 0.000, 36.000, 0.000, 999.999, 0.000, 0.000, 0.000, #CAR
|
| 33 |
+
0.000, 0.000, 0.000, 0.000, 999.999, 0.000, 0.000, 0.000, #TRUCK
|
| 34 |
+
0.000, 0.000, 0.000, 0.000, 999.999, 0.000, 0.000, 0.000, #BUS
|
| 35 |
+
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, #TRAILER
|
| 36 |
+
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, #MOTORBIKE
|
| 37 |
+
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, #BICYCLE
|
| 38 |
+
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000] #PEDESTRIAN
|
pointpainting_ml_package.param.yaml
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**:
|
| 2 |
+
ros__parameters:
|
| 3 |
+
model_params:
|
| 4 |
+
class_names: ["CAR", "TRUCK", "BUS", "BICYCLE", "PEDESTRIAN"]
|
| 5 |
+
paint_class_names: ["CAR", "BICYCLE", "PEDESTRIAN"]
|
| 6 |
+
point_feature_size: 7 # x, y, z, time-lag and car, pedestrian, bicycle
|
| 7 |
+
max_voxel_size: 40000
|
| 8 |
+
point_cloud_range: [-121.6, -76.8, -3.0, 121.6, 76.8, 5.0]
|
| 9 |
+
voxel_size: [0.32, 0.32, 8.0]
|
| 10 |
+
downsample_factor: 1
|
| 11 |
+
encoder_in_feature_size: 12
|
| 12 |
+
has_twist: false
|
| 13 |
+
has_variance: false
|
| 14 |
+
detection_score_thresholds:
|
| 15 |
+
# Upper bound of radial distance of 3d center_x and center_y in bounding boxes, and starting from 0
|
| 16 |
+
# [0-50m), [50.0-90m), [90.0-121.0m), [121.0-200.0m), set a very high number for the last one to be safe
|
| 17 |
+
distance_bin_upper_limits: [50.0, 90.0, 121.0, 200.0]
|
| 18 |
+
# Each list of thresholds must match with the number of upper_bounds, and each threshold corresponds to a distance bucket in the order of the upper bounds
|
| 19 |
+
min_confidence_scores:
|
| 20 |
+
CAR: [0.35, 0.35, 0.35, 0.35]
|
| 21 |
+
TRUCK: [0.35, 0.35, 0.35, 0.35]
|
| 22 |
+
BUS: [0.35, 0.35, 0.35, 0.35]
|
| 23 |
+
BICYCLE: [0.35, 0.35, 0.35, 0.35]
|
| 24 |
+
PEDESTRIAN: [0.35, 0.35, 0.35, 0.35]
|
pts_backbone_neck_head_pointpainting.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7fe62fcebe0e0f62a000d06aa94d779feb444d933671a4a3189fe01be8c19a00
|
| 3 |
+
size 20140082
|
pts_voxel_encoder_pointpainting.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3ca452ea5ca9467bf782955f75704ba8466841e275e8b8acd991b9911d53249e
|
| 3 |
+
size 7621
|