-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New feature: LiDAR-based panoptic segmentation - EfficientLPS (#359)
* Initial Commit. * Implemented MMDet interface for SemanticKitti Dataset. Implemented and tested fit() method of EfficientLpsLearner. * Implemented and tested infer() and visualize() for EfficientLpsLearner. Moved example_usage.py to its final location. * Fixed stuff_id in loading pipeline for inference (EfficientLpsLearner.pcl_to_mmdet()). Improved function signature in example_usage.py for better readability. * Fixed bug in singlegpu_sample.py configuration. * Re-Added EfficientLPS submodule. * Corrected typo in docstring. * Changed copyright notice to 2022. Added EfficientLPS submodule to skipped directories in test_license.py. * Cleaned singlegpu_sample config. * Type hints and docstrings. * Typo. * Added numpy, just in case. * Finished evaluation methods. * Docstrings and type hints. * Added ROS Node * Updated TODOs * Added type hint compatibility for pathlib's Path where required. Minor bug fixes. * Added UnitTests. * Added iterator interfaces and unittest for them. * Commented out semantic kitti dataset iterator interface test. * Finished ROS Node. * Finished READMEs. * Fixed bibtex and added Daniel Büscher to authors. * Updated to latest commit of EfficientLPS. * Verified model and test_data downloads. Cleaned TODOs. * feat: Fixed mmdet2 conflicts, learner, and added tests Fixed semantic_kitti.py and efficient_lps_learner.py for mmdet2 conflicts. Also fixed test_efficent_lps.py and added the correct configuration file for semantic_kitti dataset * feat: changed location for efficentlps submodule into opendr branch * feat: Changed install.sh for docker environment, will be reverted later * feat: Updated install.sh for docker container environment * style: ROS_DISTRO export changed * feat: Adapted ROS node for EfficientLPS * install.sh reverted back to normal * removed eagerx module (deprecated) * refactor: Renamed model key for semantickitti dataset * feat: Adding feature for ros pointcloud2 publisher * feat: Added example usage for EfficientLPS Added example_usage.py for EfficientLPS and README file. * feat: Add point cloud 2 publisher * docs: Fix README files for example usage for both PS & LPS \ * docs: Adjusted README docs for ROS nodes and learner references * bridge_update * [WIP] commit by Niclas * update submodules * feat: ROS nodes for PointCloud2 publisher and EfficientLPS ready for testing * style: Fix for PEP style * style: Changed the rosmessage of pc2 publisher * style: pep8 fixes * pep8 test skip for EfficientLPS added * Revert changes on install.sh * Fixed documentation for EfficientLPS node * remove misplaced example_usage * style: fixing typo in the comments * docs: fixing readme file of panoptic segmentation * Deleting nuscenes * Adjust dependencies * Deleting NuScenes from the learner * style: styling fix for the LPS learner * style: fix pep8 * fix: deleted nuscenes remainings * fix: fix test typo * fix: style and url fix for download method * Add license to PC2 publisher * fix: fix the clang format test, skip EfficientLPS * revert activate.sh * Rename heading * feat: Added prepare_data for semantic_kitti.py * docs: Update README for semantic kitti prepare data function * style: fix pep8 * fix: Changing copying the files from move to speed up * docs: Update Performance Evaluation * refactor: Removing uncessary dependencies and repeating imports to fix pep8 * docs: Fix for conflicting files * fix: Fixing the readme in the opendr_ws * refactor: Fixed licenses due to new year * refactor: Fix license date * docs: EfficientLPS.md changes wrt. review * docs: Add PointCloud2 bridge methods to 'opendr_ros_bridge.md' * docs: Fix documentation in 'projects/opendr_ws/src/opendr_perception/README.md' * test: Deleted not used test * fix: Fixed ROS Nodes args and dataset file check for PCL2 and EfficientLPS * docs: Update ROS nodes README.md according new PCL2 args * feat: Add argument option to demo for EfficientLPS * fix pep8 * fix: Removed "awful hack", original repo from 'EfficientLPS' should be updated * feat: Add link to demo in index.md and update submodule * docs: Update README.md for ros nodes (perception -> opendr_perception) * Add changelog entry * feat: ROS documentation improved and some fixes on ros nodes * feat: Fix unused numpy import * docs: Fix wrong revert and add necessary changes * style(efficientLPS): change the variable name to convenient one * fix(efficientLPS): Small argument input naming fix * docs: Fix documentation of EfficientPS arguments * style(efficientLPS): fix style pep8 * docs(efficientLPS): Quick fixes on documentation * Empty Commit * feat(efficientLPS): Add test data download option to PointCloud2 Publisher Node * feat(efficientLPS): Add prepare data for the EfficientLPS learner * style(efficientLPS): Fix pep8 * docs(efficientLPS): Add the test data support to documentation, delete the debug lines * refactor(efficientLPS): Change the naming of the output topic of EfficientLPS --------- Co-authored-by: Jose Arce y de la Borbolla <joseab10@gmail.com> Co-authored-by: aselimc <voedisch_local@informatik.uni-freiburg.de> Co-authored-by: Niclas <49001036+vniclas@users.noreply.github.com> Co-authored-by: Niclas Vödisch <voedisch@cs.uni-freiburg.de>
- Loading branch information
1 parent
8f4a452
commit fe34b42
Showing
34 changed files
with
2,721 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
[submodule "src/opendr/perception/panoptic_segmentation/efficient_ps/algorithm/EfficientPS"] | ||
path = src/opendr/perception/panoptic_segmentation/efficient_ps/algorithm/EfficientPS | ||
url = https://github.com/DeepSceneSeg/EfficientPS.git | ||
[submodule "src/opendr/perception/panoptic_segmentation/efficient_lps/algorithm/EfficientLPS"] | ||
path = src/opendr/perception/panoptic_segmentation/efficient_lps/algorithm/EfficientLPS | ||
url = https://github.com/robot-learning-freiburg/EfficientLPS.git | ||
branch = opendr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
## efficient_lps module | ||
|
||
Panoptic segmentation combines both semantic segmentation and instance segmentation in a single task. | ||
While distinct foreground objects, e.g., cars or pedestrians, receive instance-wise segmentation masks, background classes such as buildings or road surface are combined in class-wide labels. | ||
|
||
For this task, EfficientLPS has been included in the OpenDR toolkit. | ||
The model architecture leverages a shared backbone for efficient encoding and fusing of semantically rich multi-scale features. | ||
Two separate network heads create predictions for semantic and instance segmentation, respectively. | ||
The final panoptic fusion model combines the output of the task-specific heads into a single panoptic segmentation map. | ||
|
||
Website: [http://lidar-panoptic.cs.uni-freiburg.de](http://lidar-panoptic.cs.uni-freiburg.de) <br> | ||
Arxiv: [https://arxiv.org/abs/2102.08009](https://arxiv.org/abs/2102.08009) <br> | ||
Original GitHub repository: [https://github.com/robot-learning-freiburg/EfficientLPS](https://github.com/robot-learning-freiburg/EfficientLPS) | ||
|
||
### Class EfficientLpsLearner | ||
Bases: `engine.learners.Learner` | ||
|
||
The *EfficientLpsLearner* class is a wrapper around the EfficientLPS implementation of the original author's repository adding the OpenDR interface. | ||
|
||
The [EfficientLpsLearner](/src/opendr/perception/panoptic_segmentation/efficient_lps/efficient_lps_learner.py) class has the following public methods: | ||
#### `EfficientLpsLearner` constructor | ||
```python | ||
EfficientLpsLearner(config_file, lr, iters, batch_size, optimizer, lr_schedule, momentum, weight_decay, optimizer_config, checkpoint_after_iter, temp_path, device, num_workers, seed) | ||
``` | ||
|
||
Constructor parameters: | ||
|
||
- **config_file**: *str*\ | ||
Path to the config file that contains the model architecture and the data loading pipelines. | ||
- **lr**: *float, default=0.07*\ | ||
Specifies the learning rate used during training. | ||
- **iters**: *int, default=160*\ | ||
Specifies the number of iterations used during training. | ||
- **batch_size**: *int, default=1*\ | ||
Specifies the size of the batches used during both training and evaluation. | ||
- **optimizer**: *str, default='SGD'*\ | ||
Which optimizer to use for training. | ||
- **lr_schedule**: *dict[str, any], default=None*\ | ||
Contains additional parameters related to the learning rate. | ||
- **momentum**: *float, default=0.9*\ | ||
Specifies the momentum used by the optimizer. | ||
- **weight_decay**: *float, default=0.0001*\ | ||
Specifies the weight decay used by the optimizer. | ||
- **optimizer_config**: *dict[str, any], default=None*\ | ||
Contains additional parameters related to the optimizer. | ||
- **checkpoint_after_iter**: *int, default=1*\ | ||
Specifies the interval in epochs to save checkpoints during training. | ||
- **temp_path**: *Path*, *str, default='../eval_tmp_dir'*\ | ||
Path to a temporary folder that will be created to evaluate the model. | ||
- **device**: *str, default='cuda:0'*\ | ||
Specifies the device to deploy the model. | ||
- **num_workers**: *int, default=1*\ | ||
Specifies the number of workers used by the data loaders. | ||
- **seed**: *float, default=None*\ | ||
Specifies the seed to shuffle the data during training. | ||
|
||
#### `EfficientLpsLearner.fit` | ||
```python | ||
EfficientLpsLearner.fit(self, dataset, val_dataset, logging_path, silent) | ||
``` | ||
|
||
Parameters: | ||
|
||
- **dataset**: *object*\ | ||
Specifies the dataset used to train the model. | ||
Supported datasets are SemanticKitti and NuScenes (Future) (see [readme](../../src/opendr/perception/panoptic_segmentation/datasets/README.md)). | ||
- **val_dataset**: *object*\ | ||
If given, this dataset will be used to evaluate the current model after each epoch. | ||
Supported datasets are SemanticKitti and NuScenes (Future) (see [readme](../../src/opendr/perception/panoptic_segmentation/datasets/README.md)). | ||
- **logging_path**: *Path*, *str, default='../logging'*\ | ||
Path to store the logging files, e.g., training progress and tensorboard logs. | ||
- **silent**: *bool, default=True*\ | ||
If True, disables printing the training progress reports to STDOUT. | ||
The validation will still be shown. | ||
|
||
Return: | ||
|
||
- **results**: *dict*\ | ||
Dictionary with "train" and "val" keys containing the training progress (e.g. losses) and, if a val_dataset is provided, the evaluation results. | ||
#### `EfficientLpsLearner.eval` | ||
```python | ||
EfficientLpsLearner.eval(self, dataset, print_results) | ||
``` | ||
|
||
Parameters: | ||
|
||
- **dataset**: *object*\ | ||
Specifies the dataset used to evaluate the model. | ||
Supported datasets are SemanticKitti and NuScenes (Future) (see [readme](../../src/opendr/perception/panoptic_segmentation/datasets/README.md)). | ||
- **print_results**: *bool, default=False*\ | ||
If True, the evaluation results will be formatted and printed to STDOUT. | ||
|
||
Return: | ||
|
||
- **evaluation_results**: *dict*\ | ||
Contains the panoptic quality (PQ), segmentation quality (SQ), recognition quality (RQ) and Intersection over Union (IoU). | ||
|
||
|
||
#### `EfficientLpsLearner.pcl_to_mmdet` | ||
```python | ||
EfficientLpsLearner.pcl_to_mmdet(self, point_cloud, frame_id) | ||
``` | ||
|
||
Parameters: | ||
|
||
- **point_cloud**: *PointCloud*\ | ||
Specifies the OpenDR PointCloud object that will be converted to a MMDetector compatible object. | ||
- **frame_id**: *int, default=0*\ | ||
Number of the scan frame to be used as its filename. | ||
Inferences will use the same filename. | ||
|
||
Return: | ||
|
||
- **results**: *dict*\ | ||
An MMDetector compatible dictionary containing the PointCloud data and some additional metadata. | ||
|
||
#### `EfficientLpsLearner.infer` | ||
```python | ||
EfficientLpsLearner.infer(self, batch, return_raw_logits, projected) | ||
``` | ||
|
||
Parameters: | ||
|
||
- **batch**: *PointCloud*, *List[PointCloud]*\ | ||
Point Cloud(s) to feed to the network. | ||
- **return_raw_logits**: *bool, default=False*\ | ||
If True, the raw network output will be returned. | ||
Otherwise, the returned object will hold Tuples of Heatmaps of the OpenDR interface. | ||
- **projected**: *bool, default=False*\ | ||
If True, output will be returned as 2D heatmaps of the spherical projections of the semantic and instance labels, as well as the spherical projection of the scan's range. | ||
Otherwise, the semantic and instance labels will be returned as Numpy arrays for each point. | ||
|
||
Return: | ||
|
||
- **results**: *Tuple[Heatmap, Heatmap, Image]*,\ | ||
*Tuple[np.ndarray, np.ndarray, None]*,\ | ||
*List[Tuple[Heatmap, Heatmap, Image]]*,\ | ||
*List[Tuple[np.ndarray, np.ndarray, None]]*\ | ||
If *return_raw_logits* is True the raw network output will be returned. | ||
If *return_raw_logits* is True and *projected* is true, the predicted instance and semantic segmentation maps, as well as the scan range map will be returned. | ||
Otherwise, if *return_raw_logits* is True and *projected* is false, the predicted instance and semantic labels for each point will be returned as numpy arrays. | ||
|
||
#### `EfficientLpsLearner.save` | ||
```python | ||
EfficientLpsLearner.save(self, path) | ||
``` | ||
|
||
Parameters: | ||
|
||
- **path**: *Path*, *str*\ | ||
Specifies the location to save the current model weights. | ||
|
||
Return: | ||
|
||
- **successful**: *bool*\ | ||
Returns True if the weights could be saved. | ||
Otherwise, returns False. | ||
|
||
#### `EfficientLpsLearner.load` | ||
```python | ||
EfficientLpsLearner.load(path) | ||
``` | ||
|
||
Parameters: | ||
|
||
- **path**: *Path*, *str*\ | ||
Specifies the location to load model weights. | ||
|
||
Return: | ||
|
||
- **successful**: *bool*\ | ||
Returns True if the weights could be loaded. | ||
Otherwise, returns False. | ||
|
||
#### `EfficientLpsLearner.download` | ||
```python | ||
EfficientLpsLearner.download(path, mode, trained_on) | ||
``` | ||
|
||
Parameters: | ||
|
||
- **path**: *str*\ | ||
Specifies the location to save the downloaded file. | ||
- **mode**: *str, default='model'*\ | ||
Valid options are *'model'* to download pre-trained model weights and *'test_data'* to run the unit tests. | ||
- **trained_on**: *str, default='semantickitti'*\ | ||
Specifies which model weights to download. | ||
Pre-trained models are available for the SemanticKITTI and NuScenes (Future) datasets. | ||
|
||
Return: | ||
|
||
- **filename**: *str*\ | ||
Absolute path to the downloaded file or directory. | ||
|
||
#### `EfficientLpsLearner.visualize` | ||
```python | ||
EfficientLpsLearner.visualize(self, pointcloud, predictions, show_figure, save_figure, figure_filename, figure_size, max_inst, min_alpha, dpi) | ||
``` | ||
|
||
Parameters: | ||
|
||
- **pointcloud**: *PointCloud*\ | ||
PointCloud used for inference. | ||
- **prediction**: *Tuple[np.ndarray, np.ndarray]*\ | ||
The semantic and instance segmentation labels obtained with the `infer()` method and *projected* set to False. | ||
- **show_figure**: *bool, default=True*\ | ||
If True, the generated figure will be shown on screen. | ||
- **save_figure**: *bool, default=False*\ | ||
If True, the generated figure will be saved to disk. The **figure_filename** has to be set. | ||
- **figure_filename**: *Path*, *str, default=None*\ | ||
The path used to save the figure if **save_figure** is True. | ||
- **figure_size**: *Tuple[float, float], default=(15, 10)*\ | ||
The size of the figure in inches. | ||
- **max_inst**: *int, default=20*\ | ||
Maximum value that the instance ID can take. | ||
Used for computing the alpha value of a point. | ||
- **min_alpha**: *float, default=0.25*\ | ||
Minimum value that a point's alpha value can take, so that it is never fully transparent. | ||
- **dpi**: *int, default=600*\ | ||
Resolution of the resulting image, in Dots per Inch. | ||
- **return_pointcloud**: *Optional[bool], default=False*\ | ||
If True, returns a PointCloud object with the predicted labels as colors. | ||
- **return_pointcloud_type**: *Optional[str], default=None*\ | ||
If return_pointcloud is True, this parameter specifies the type of the returned PointCloud object. | ||
Valid options are "semantic", "instance" and "panoptic". | ||
|
||
Return: | ||
|
||
- **visualization**: *Union[PointCloud, Image]*\ | ||
OpenDR Image of the generated visualization or OpenDR PointCloud with the predicted labels. | ||
|
||
#### Performance Evaluation | ||
|
||
The speed of pointcloud per second is evaluated for the SemanticKITTI dataset: | ||
|
||
| Dataset | ~ | GeForce GTX TITAN X | ~ | Xavier AGX | | ||
|------------|-----------------|---------------------|-----------|------------| | ||
| SemanticKITTI | ~ | 0.53 | ~ | ~ | | ||
|
||
The memory and energy usage is evaluated for different datasets. | ||
An NVIDIA Jetson Xavier AGX was used as the reference platform for energy measurements. | ||
The reported memory is the max number seen during evaluation on the respective validation set. | ||
The energy is measured during the evaluation. | ||
|
||
| Dataset | Memory (MB) | Energy (Joules) - Total per inference AGX | | ||
|------------------------|-------------|-------------------------------------------| | ||
| SemanticKITTI | ~ | ~ | | ||
|
||
The performance is evaluated using three different metrics, namely Panoptic Quality (PQ), Segmentation Quality (SQ), and Recognition Quality (RQ). | ||
|
||
| Dataset | PQ | SQ | RQ | | ||
|------------|------|------|------| | ||
| SemanticKITTI | 52.5 | 72.6 | 63.1 | | ||
|
||
EfficientPS is compatible with the following platforms: | ||
|
||
| Platform | Compatibility | | ||
|----------------------------------------------|---------------| | ||
| x86 - Ubuntu 20.04 (bare installation - CPU) | ❌ | | ||
| x86 - Ubuntu 20.04 (bare installation - GPU) | ✔️ | | ||
| x86 - Ubuntu 20.04 (pip installation) | ❌ | | ||
| x86 - Ubuntu 20.04 (CPU docker) | ❌ | | ||
| x86 - Ubuntu 20.04 (GPU docker) | ✔️ | | ||
| NVIDIA Jetson Xavier AGX | ✔️ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.