Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
e3d4098
add nvblox_interfer link to nvblox_datasets
gogojjh Oct 28, 2022
0407275
add output time explanation
gogojjh Oct 28, 2022
1c698a5
add oslidar_impl and test_oslidar
gogojjh Oct 30, 2022
d291130
write fusionportable.cpp: load depth_image and z_image, image_loader,…
gogojjh Oct 31, 2022
8f243f4
[executables] define virtual function
gogojjh Nov 1, 2022
679045b
[executables] define virtual function
gogojjh Nov 1, 2022
6d0f43d
[executables] define virtual function
gogojjh Nov 1, 2022
1839063
[executables] use OSLidar in TSDF integration and view_calculator
gogojjh Nov 1, 2022
73c5b18
[TSDF integration] add comments and meet problems in integration
gogojjh Nov 1, 2022
4a7f06d
meet bugs in view_calculator
gogojjh Nov 2, 2022
4b40905
projective_tsdf_integrator and view_calculator: add cuda memory operator
gogojjh Nov 3, 2022
2655077
correct the lidar model
gogojjh Nov 3, 2022
ba0eea0
successfully run on FusionPortable dataset, but cannot get correct re…
gogojjh Nov 3, 2022
3bb2b24
add fuser_lidar to split out camera-based integration and lidar-based…
gogojjh Nov 3, 2022
b60df8e
fix the angle calculation of oslidar_impl
gogojjh Nov 3, 2022
0cc07a9
address the lidar_impl
gogojjh Nov 3, 2022
0e3dfb9
add README
gogojjh Nov 3, 2022
eaf5397
compute the minimum and maximum angle of ouster
gogojjh Nov 4, 2022
0e927c4
fix the intrinsics of the OSLidar model, and successfully got TSDF re…
gogojjh Nov 5, 2022
2cdfed7
add explanation of processing OSLidar in README.md
gogojjh Nov 5, 2022
59b86e4
add explanation of processing OSLidar in README.md
gogojjh Nov 5, 2022
975546a
add color integration
gogojjh Nov 14, 2022
147a3a9
add color integration
gogojjh Nov 14, 2022
b3045ad
add different voxel update method
gogojjh Nov 18, 2022
79e771e
add test_normal_image but not really fix
gogojjh Nov 19, 2022
01a991a
finish test_normal_image
gogojjh Nov 19, 2022
ac65cb4
add normal_image_computation but not finish
gogojjh Nov 19, 2022
6f72246
successfullly compile and run the computeNormalImage
gogojjh Nov 20, 2022
579d292
add normal data retrieval
gogojjh Nov 21, 2022
71c89c2
add different voxel_dis_method
gogojjh Nov 21, 2022
0b485fd
add non-projective distance implementation, but not test
gogojjh Nov 22, 2022
ef28f7e
add non-projective distance implementation, but not test
gogojjh Nov 22, 2022
84e1e3b
add non-projective distance implementation, and successfully test
gogojjh Nov 22, 2022
24ddbd9
add non-projective distance implementation, and successfully test
gogojjh Nov 22, 2022
0a530f6
add non-projective distance implementation, and successfully test
gogojjh Nov 22, 2022
0472265
add obstacle_output_path, but not test
gogojjh Nov 23, 2022
efb8eb0
add the output of obstacle map
gogojjh Nov 23, 2022
27dea7a
add non-projective distance implementation, and successfully test
gogojjh Nov 23, 2022
4d1d1e1
add experimental results on 20220216_escalator_day and 20220226_campu…
gogojjh Nov 25, 2022
521cd80
add experimental results on 20220216_escalator_day and 20220226_campu…
gogojjh Nov 25, 2022
38726d0
format the cuda/conversions
gogojjh Nov 25, 2022
57b573c
add the tsdf integration with the KITTI dataset
gogojjh Nov 26, 2022
f2497f8
add the tsdf integration with the KITTI dataset
gogojjh Nov 26, 2022
d0c2b1e
[README.md] add data download link
gogojjh Nov 28, 2022
02680c4
[weight averaging] fix the linear weight of voxel_dis_method=6
gogojjh Nov 29, 2022
066eec5
add test with dynamic objects
gogojjh Nov 29, 2022
cff7706
add comments in projective_color_integrator
gogojjh Nov 30, 2022
b6774fc
add template function in color_integration
gogojjh Nov 30, 2022
0daefec
add camera_pinhole
gogojjh Dec 1, 2022
b80beba
add kitti.cpp and parse camera file for kitti data
gogojjh Dec 1, 2022
7a48111
perform color integration in the KITTI odometry seq07
gogojjh Dec 3, 2022
2ce1a3b
add kitti.cpp and parse camera file for kitti data
gogojjh Dec 3, 2022
b5b1d5d
add kitti.cpp and parse camera file for kitti data
gogojjh Dec 4, 2022
9433101
successfully compile and run tests files && modify jjiao->gogojjh
gogojjh Dec 4, 2022
5357622
successfully compile and run tests files && modify jjiao->gogojjh
gogojjh Dec 4, 2022
b97a44f
successfully compile and run tests files && modify jjiao->gogojjh
gogojjh Dec 4, 2022
99e75e9
update README.md: add the link of the KITTI and FusionPortable dataset
gogojjh Dec 4, 2022
717ffa9
update README.md: add the link of the KITTI and FusionPortable dataset
gogojjh Dec 4, 2022
5717740
update README.md: add the link of the KITTI and FusionPortable dataset
gogojjh Dec 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@
*docs/_build
*docs/doxyoutput
*docs/api

# test
test*
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,87 @@
# Nvblox-modify

#### Code Pipeline of NVBlox

1. Data loader

2. Frame integration

1. After loading data (the code API): Fuser::integrateFrame(const int frame_number)

2. RgbdMapper::integrateOSLidarDepth -> ProjectiveTsdfIntegrator::integrateFrame -> ProjectiveTsdfIntegrator::integrateFrameTemplate

> * set <code>voxel_size</code> and <code>truncation_distance</code>
> * set <code>truncation_distance_m = truncation_distance_vox * voxel_size</code>
> * Identify blocks given the camera view: <code>view_calculator_.getBlocksInImageViewRaycast</code>
> * <code>getBlocksByRaycastingPixels</code>: Raycasts through (possibly subsampled) pixels in the image, use the kernal function
> * <code>*void* combinedBlockIndicesInImageKernel</code>: retrieve visiable block by raycasting voxels, done in GPU
>
>
> * TSDF integration given block indices: <code>integrateBlocksTemplate</code>
>
> * <code>ProjectiveTsdfIntegrator::integrateBlocks</code>: block integration for the OSLidar, use the kernal function
> * <code>integrateBlocksKernel</code>: TSDF integration for each block, done in GPU
> * <code>projectThreadVoxel</code>: convert blocks' indices into coordinates, retrieve voxels from the block, and project them onto the image to check whether they are visible or not
> * <code>interpolateOSLidarImage</code>: linear interpolation of depth images given float coordinates
> * ```const Index2D u_M_rounded = u_px.array().round().cast<int>();```
> * ```u_M_rounded.x() < 0 || u_M_rounded.y() < 0 || u_M_rounded.x() >= cols || u_M_rounded.y() >= rows)```: check bounds
> * <code>updateVoxel</code>: update the TSDF values of all visible voxels.

3. Weight averaging methods
```
Projective distance:
1: constant weight, truncate the fused_distance
2: constant weight, truncate the voxel_distance_measured
3: linear weight, truncate the voxel_distance_measured
4: exponential weight, truncate the voxel_distance_measured
Non-Projective distance:
5: weight and distance derived from VoxField
6: linear weight, distance derived from VoxField
```

3. Output data
1. Mesh map
2. ESDF map
3. Obstacle map: points from the ESDF map whose distance is smaller than a threshold

4. Global planning test

--------------------------
### Demo with [KITTI](https://www.cvlibs.net/datasets/kitti) dataset

1. Prepare data:
* Download test data

* [2011_09_30_drive_0027_sync](http://gofile.me/72EEc/NGdCJrzA5)

2. Run the NVBlox

```../script/run_fuse_kitti.sh```

* [Experiments on NVBlox with the KITTI dataset](docs/experiments_kitti.md)

--------------------------
### Demo with the [FusionPortable](https://ram-lab.com/file/site/multi-sensor-dataset) dataset

##### Demo

1. Download test data

* [20220226_campus_road_day](http://gofile.me/72EEc/MDghPwECu)

3. Run the NVBlox:

```../script/run_fuse_fusionportable.sh```

4. We can view the output mesh using the Open3D viewer.

```python3 ../../visualization/visualize_mesh.py 20220216_garden_day_mesh.ply```

* [Tricks to preprocess OSLiDAR points](docs/preprocess_OSLiDAR.md)
* [Experiments on NVBlox and VDBMapping](docs/experiments_fusionportable.md)

--------------------------
--------------------------
# nvblox
Signed Distance Functions (SDFs) on NVIDIA GPUs.

Expand Down Expand Up @@ -49,6 +133,7 @@ cmake .. && make && cd tests && ctest
```

## Run an example

In this example we fuse data from the [3DMatch dataset](https://3dmatch.cs.princeton.edu/). First let's grab the dataset. Here I'm downloading it to my dataset folder `~/dataset/3dmatch`.
```
wget http://vision.princeton.edu/projects/2016/3DMatch/downloads/rgbd-datasets/sun3d-mit_76_studyroom-76-1studyroom2.zip -P ~/datasets/3dmatch
Expand Down Expand Up @@ -158,3 +243,7 @@ export OPENBLAS_CORETYPE=ARMV8

# License
This code is under an [open-source license](LICENSE) (Apache 2.0). :)

# Reference
[1] Parallel Banding Algorithm to Compute Exact Distance Transform with the GPU
> compute EDT with the GPU
84 changes: 84 additions & 0 deletions docs/.~experiments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
### Experimental Results

##### Reconstruction results (voxel_size = 0.1)

* Sequence: 20220216_garden_day, *2000* frames
* Projective distance
* NVBlox (constant weight, truncate fused_distance):
Point cloud distance [m]: 0.0713986; Coverage [%]: 0.648376
* NVBlox (constant weight, truncate measured_distance):
Point cloud distance [m]: 0.070609; Coverage [%]: 0.716344
* NVBlox (linear weight, truncate fused_distance):
Point cloud distance [m]: 0.0687769; Coverage [%]: 0.73421
* NVBlox (exp weight, truncate fused_distance):
Point cloud distance [m]: 0.0690283; Coverage [%]: 0.714388

* Non-Projective distance
* NVBlox (non-projective distance, truncate fused_distance): (distance_th = 10.0m)
Point cloud distance [m]: 0.0480275; Coverage [%]: 0.388869
* NVBlox (non-projective distance, truncate fused_distance): (distance_th = 30.0m)
Point cloud distance [m]: 0.058146; Coverage [%]: 0.631758
* NVBlox (non-projective distance, truncate fused_distance): (distance_th = 50.0m)
Point cloud distance [m]: 0.057562; Coverage [%]: 0.651013

* VDBMapping:
Point cloud distance [m]: 0.074576; Coverage [%]: 0.724301

* Sequence: 20220216_canteen_day, *2600* frames
* Non-Projective distance
* NVBlox (non-projective distance, truncate fused_distance): (distance_th = 70.0m)
Point cloud distance [m]: 0.102588; Coverage [%]: 0.602803

* Sequence: 20220225_building_day, *2300* frames
* Non-Projective distance
* NVBlox (non-projective distance, truncate fused_distance): (distance_th = 70.0m)
Point cloud distance [m]: 0.0704632; Coverage [%]: 0.574235

* Sequence: 20220216_escalator_day, *3200* frames
* Projective distance
* NVBlox (linear weight, truncate fused_distance):
Point cloud distance [m]: 0.615201; Coverage [%]: 0.649969

* Non-Projective distance
* NVBlox (non-projective distance, truncate fused_distance): (distance_th = 70.0m)
Point cloud distance [m]: 0.0526527; Coverage [%]: 0.629851
* NVBlox (non-projective distance, linear weight, truncate fused_distance): (distance_th = 70.0m)
Point cloud distance [m]: 0.0602039; Coverage [%]: 0.641247

##### Computation time (voxel_size = 0.1)
* Sequence: 20220216_garden_day
* Normal computation with a GPU: 0.7ms per frame
* NVBLox: 14.2ms per frame (total 2000)
* VDBMapping: 384.062 ms per frame (total 2500)

* Sequence: 20220216_canteen_day
* Normal computation with a GPU: 0.01ms per frame
* NVBLox: 3ms per frame (total 2600)

* Sequence: 20220226_campus_road_day
* NVBLox: 5ms per frame (total 2000)

#### Appendix

**Reconstruction results of NVBLox on 20220216_garden_day (voxel_size = 0.1)**
<p align="center">
<center><img src="images/20220216_garden_day_mesh_img.png" width="450" /></center>
<br>
<center><img src="images/20220216_garden_day_mesh_img_eval_error.png" width="450" /></center>
</p>

**Reconstruction results of NVBLox on 20220225_building_day (voxel_size = 0.1)**
<p align="center">
<center><img src="images/20220225_building_day_mesh_img.png" width="450" /></center>
<br>
<center><img src="images/20220225_building_day_mesh_img_eval_error.png" width="450" /></center>
</p>

**Reconstruction results of NVBLox on other sequences (voxel_size = 0.1)**
<p align="center">
<center><img src="images/20220216_escalator_day.png" width="450" /></center>
<br>
<center><img src="images/20220226_campus_road_day.png" width="450" /></center>
</p>


12 changes: 12 additions & 0 deletions docs/.~experiments_kitti.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
### Experimental Results

#### Appendix

**Reconstruction results of NVBLox on 2011_09_30_drive_0027_sync (voxel_size = 0.1)**
<p align="center">
<center><img src="images/2011_09_30_drive_0027_sync_mesh_closeview.png" width="450" /></center>
<br>
<center><img src="images/2011_09_30_drive_0027_sync_mesh.png" width="450" /></center>
<br>
<center><img src="images/kitti_global_path.png" width="450" /></center>
</p>
14 changes: 14 additions & 0 deletions docs/code_review_voxfield_panmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## VoxField



## Panmap

Process semantic point cloud

```c++
conversions.h - inline void convertPointcloud
1. define Label
2. give label specific definitions
```

89 changes: 89 additions & 0 deletions docs/experiments_fusionportable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
## Experiments

### Reconstruction results

###### Weight averaging methods (TSDF integration):
```
Projective distance:
1: constant weight, truncate the fused_distance
2: constant weight, truncate the voxel_distance_measured
3: linear weight, truncate the voxel_distance_measured
4: exponential weight, truncate the voxel_distance_measured
Non-Projective distance:
5: weight and distance derived from VoxField
6: linear weight, distance derived from VoxField
```

###### Weight averaging methods (Color integration):
```
1: constant weight, truncate the voxel_distance_measured
2: linear weight, truncate the voxel_distance_measured
3: exponential weight, truncate the voxel_distance_measured
4: sensor distance weight
5: linear weight * sensor distance weight
```

###### Scene reconstruction results (voxel_size = 0.1)
| Sequence | Algorithm | Method | Point cloud distance | Coverage [%] |
| :------- | :-------- | :----- | :------------------- | :------------|
| 20220216_garden_day (2000) | NVBlox | 1 | 0.0713986 | 0.648376 |
| 20220216_garden_day (2000) | NVBlox | 2 | 0.070609 | 0.716344 |
| 20220216_garden_day (2000) | NVBlox | 3 | 0.0687769 | 0.73421 |
| 20220216_garden_day (2000) | NVBlox | 4 | 0.0690283 | 0.714388 |
| 20220216_garden_day (2000) | NVBlox | 5 | 0.0480275 | 0.388869 |
| 20220216_garden_day (2000) | NVBlox | 5 | 0.058146 | 0.631758 |
| 20220216_garden_day (2000) | NVBlox | 5 | 0.057562 | 0.651013 |
| 20220216_garden_day (2000) | NVBlox | 6 | 0.0607844 | 0.689476 |
| 20220216_garden_day (2000) | VDBMapping | 3 | 0.074576 | 0.724301 |
| 20220216_canteen_day (2600) | NVBlox | 5 (70m) | 0.102588 | 0.602803 |
| 20220225_building_day (2300) | NVBlox | 5 (70m) | 0.0704632 | 0.574235 |
| 20220216_escalator_day (3200) | NVBlox | 3 | 0.615201 | 0.649969 |
| 20220216_escalator_day (3200) | NVBlox | 5 (70m) | 0.0526527 | 0.629851 |
| 20220216_escalator_day (3200) | NVBlox | 6 (50m) | 0.0585957 | 0.641295 |

###### Computation time (voxel_size = 0.1)
| Sequence | Algorithm/ Module | Time per frame |
| :------- | :-------- | :----- |
| 20220216_garden_day | Normal computation | 0.7ms |
| 20220216_garden_day | NVBLox | 14.2ms (2000) |
| 20220216_garden_day | VDBMapping | 384.062ms (2500) |
| 20220216_canteen_day | Normal computation | 0.01ms |
| 20220216_canteen_day | NVBLox | 3ms (2600) |
| 20220226_campus_road_day | NVBLox | 5ms (2000) |

###### Figures

Reconstruction of NVBLox on 20220216_garden_day (voxel_size = 0.1)
<p align="center">
<center><img src="images/20220216_garden_day_mesh_img.png" width="40%" /></center>
<br>
<center><img src="images/20220216_garden_day_mesh_img_eval_error.png" width="40%" /></center>
</p>

Reconstruction of NVBLox on 20220225_building_day (voxel_size = 0.1)
<p align="center">
<center><img src="images/20220225_building_day_mesh_img.png" width="40%" /></center>
<br>
<center><img src="images/20220225_building_day_mesh_img_eval_error.png" width="40%" /></center>
</p>

Reconstruction of NVBLox on other sequences (voxel_size = 0.1)
<p align="center">
<center><img src="images/20220216_escalator_day_mesh.png" width="40%" /></center>
<br>
<center><img src="images/20220226_campus_road_day_mesh.png" width="40%" /></center>
</p>

Obstacle information (voxel_size = 0.1)
<p align="center">
<center><img src="images/20220226_campus_road_day_obs.png" width="40%" /></center>
</p>

Reconstruction of NVBLox on 20221126_lab_static (voxel_size = 0.05) with dynamic objcts
<p align="center">
<center><img src="images/20221126_lab_static_1.png" width="40%" />100 frames</center>
<br>
<center><img src="images/20221126_lab_static_2.png" width="40%" />150 frames</center>
<br>
<center><img src="images/20221126_lab_static_3.png" width="40%" />600 frames</center>
</p>
15 changes: 15 additions & 0 deletions docs/experiments_kitti.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
### Experimental Results

#### Appendix

**Reconstruction results of NVBLox on 2011_09_30_drive_0027_sync (voxel_size = 0.1)**
<p align="center">
<center><img src="images/2011_09_30_drive_0027_sync_mesh_closeview.png" width="450" /></center>
<br>
<center><img src="images/2011_09_30_drive_0027_sync_mesh.png" width="450" /></center>
<br>
<center><img src="images/kitti_global_path.png" width="450" /></center>
<br>
<center><img src="images/kitti_color_mesh.png" width="450" /></center>
</p>

Binary file added docs/images/2011_09_30_drive_0027_sync_mesh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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/images/20220216_escalator_day_mesh.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/images/20220216_garden_day_mesh_img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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/images/20220225_building_day_mesh_img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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/images/20220226_campus_road_day_mesh.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/images/20220226_campus_road_day_obs.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/images/20221126_lab_static_1.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/images/20221126_lab_static_2.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/images/20221126_lab_static_3.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/images/kitti_color_mesh.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/images/kitti_global_path.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/images/ouster_angle_after_filter.jpg
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/images/ouster_angle_before_filter.jpg
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/images/voxfield_result.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions docs/preprocess_OSLiDAR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
### Tricks to preprocessing OSLiDAR points

### Explanation

The perfect intrinsic model of a LiDAR should be (like VLP, Hesai):

* The elevation angle (angle between ray and +z) of each line increases evenly
* The azimuth angle of each point at one line (2pi - angle between ray and +x) increases evenly

But the intrinsics of the OSLiDAR are unstable. This means that the conversion between a point cloud and a range image is not lossless. Especially, near points may have large noise. We analyze the angle characters of OSLiDAR:

<p align="center">
<center><img src="images/ouster_angle_before_filter.jpg" width="70%" /></center><br>
</p>


We need to preprocess the OSLiDAR points. For each line, we only keep points if their length is within <code>[scan_min, scan_max]</code>. And then we compute the mean elevation angle of the first line and last line as the starting and ending elevation angle. We analyze the angle characters of OSLiDAR with filtered points:

<p align="center">
<center><img src="images/ouster_angle_after_filter.jpg" width="70%" /></center>
</p>
### Code to generate range images from point clouds of OSLiDAR

```c++
cv::Mat depth_img(num_elevation_divisions, num_azimuth_divisions,
CV_16UC1, cv::Scalar(0));
for (const auto &pt : input_cloud) {
float r = sqrt(pt.x * pt.x + pt.y * pt.y + pt.z * pt.z);
if (r <= SCAN_MIN || r >= SCAN_MAX) continue;
float elevation_angle_rad = acos(pt.z / r);
float azimuth_angle_rad = M_PI - atan2(pt.y, pt.x);
int row_id = round((elevation_angle_rad - start_elevation_rad) /
rads_per_pixel_elevation);
if (row_id < 0 || row_id > num_azimuth_divisions - 1) continue;
int col_id = round(azimuth_angle_rad / rads_per_pixel_azimuth);
if (col_id >= 2048) col_id -= 2048;
float dep = r * default_scale_factor;
if (dep > std::numeric_limits<uint16_t>::max()) continue;
if (dep < 0.0f) continue;
depth_img.at<uint16_t>(row_id, col_id) = uint16_t(dep);
}
```

### Code to generate point clouds from range images for OSLiDAR

```c++
pcl::PointCloud<pcl::PointXYZ> output_cloud;
for (size_t row_id = 0; row_id < depth_img.rows; row_id++) {
for (size_t col_id = 0; col_id < height_img.cols; col_id++) {
float dep = depth_img.at<float>(row_id, col_id);
float elevation_angle_rad =
row_id * rads_per_pixel_elevation + start_elevation_rad;
float z = height_img.at<float>(row_id, col_id);
float r = sqrt(dep * dep - z * z);
float azimuth_angle_rad = M_PI - float(col_id) * rads_per_pixel_azimuth;
float x = r * cos(azimuth_angle_rad);
float y = r * sin(azimuth_angle_rad);
pcl::PointXYZ pt;
pt.x = x;
pt.y = y;
pt.z = z;
output_cloud.push_back(pt);
}
}

```

Loading