ApproximateVoxelGrid and VoxelGrid details

1. Preface

The online introduction of these two points mainly means that: Approximate is the center of the point cloud, and VoxelGrid is the center of gravity of the point cloud, but the point cloud itself has no quality and other attributes that can calculate the center of gravity of the point cloud, that is, the center of gravity and center of the point cloud are consistent, so what is the difference between the two? Let's introduce them one by one. Both set voxel sizes to 0.1, 0.1, 0.1

2.ApproximateVoxelGrid

Experiment with the following data (voxel size 0.1, 0.1, 0.1):

POINTS 4
DATA ascii
0.04 0.04 0.04
0.06 0.05 0.08
0.08 0.09 0.06
0.0 0.0 0.0

The results of Approximate are as follows:

POINTS 1
DATA ascii
0.044999998 0.045000002 0.044999998

3.VoxelGrid

Using the same data, the VoxelGrid method is used for testing (voxel size 0.1, 0.1, 0.1):

POINTS 1
DATA ascii
0.044999998 0.045000002 0.044999998

4. Analyze the causes

It can be seen from the above test results that the results of the two are consistent, indicating that the coordinates of voxels obtained by the two are consistent, but what are the differences between the two? Next, replace the data with bunny.pcd, which is often used, and set the voxel size to 0.1, 0.1, 0.1:
Approximate result:

POINTS 11
DATA ascii
-0.032691099 0.27162147 0.17471828
0.028832393 0.28098819 0.17515437
-0.10149693 0.3929342 0.19868037
-0.040520184 0.33333206 0.18058498
0.03307664 0.32633963 0.17715645
-0.044258013 0.27539831 0.22635823
0.026912104 0.27516812 0.22207269
-0.1028813 0.38191426 0.20612897
-0.059437286 0.34165737 0.23051687
0.030122528 0.32957068 0.22502449
-0.043324616 0.40204018 0.22569159

VoxelGrid:

POINTS 11
DATA ascii
-0.032691084 0.27162111 0.17471828
0.02883238 0.28098813 0.17515427
-0.10149693 0.3929342 0.19868039
-0.040520199 0.3333326 0.18058489
0.033076655 0.32633996 0.17715652
-0.044257991 0.27539819 0.22635801
0.02691211 0.27516836 0.22207287
-0.10288131 0.38191435 0.20612894
-0.05943713 0.34165803 0.2305164
0.030122489 0.32957044 0.22502452
-0.043324623 0.40204024 0.22569156

Although there are slight differences in the above results, it may be caused by the accuracy itself, which can not explain the substantive problem.
Next, change the voxel size to 0.01, 0.01, 0.01
Approximate:

POINTS 2933
DATA ascii
0.015469999 0.33879003 0.24076335
-0.041140001 0.36688 0.23012
-0.0284 0.33820999 0.223445
0.0055939998 0.33579403 0.24381602
-0.020129999 0.31180999 0.24129
-0.090970002 0.36248001 0.22451
-0.056759998 0.36476001 0.24166
0.00127 0.34858999 0.23391999
0.035580002 0.34290999 0.22136
0.01446 0.336575 0.24237001
-0.02244 0.33939001 0.22861999
-0.05889 0.36109 0.24214999
.
.
.

VoxelGrid:

POINTS 818
DATA ascii
-0.024225555 0.27552536 0.14696814
-0.015552045 0.27729389 0.14661342
-0.0071881819 0.27919725 0.14865817
-0.022413665 0.2823284 0.14752102
-0.014937567 0.28500649 0.14624217
-0.0050424999 0.28537068 0.14697167
0.0045101955 0.28630352 0.14812391
0.013244999 0.28799775 0.14888
-0.01018 0.29023999 0.1494
.
.
.

At this time, the huge difference between the two is reflected. Approximate is much more than VoxelGrid. Looking at the source code of approximate, you can see:

    int ix = static_cast<int> (floor (input_->points[cp].x * inverse_leaf_size_[0]));
    int iy = static_cast<int> (floor (input_->points[cp].y * inverse_leaf_size_[1]));
    int iz = static_cast<int> (floor (input_->points[cp].z * inverse_leaf_size_[2]));
    unsigned int hash = static_cast<unsigned int> ((ix * 7171 + iy * 3079 + iz * 4231) & (histsize_ - 1));
    he *hhe = &history_[hash];
    if (hhe->count && ((ix != hhe->ix) || (iy != hhe->iy) || (iz != hhe->iz))) 
    {
      flush (output, op++, hhe, rgba_index, centroid_size);
      hhe->count = 0;
      hhe->centroid.setZero ();// = Eigen::VectorXf::Zero (centroid_size);
    }

Hash and ix, iy and iz in the code are not one-to-one correspondence. When a point in the point cloud belongs to a bounding box that already has other points, and the hash calculated by this bounding box repeats the hash calculated by the previous bounding box, approve will directly calculate the bounding box and output it to the target point cloud. However, hash does not correspond to ix, iy and iz one by one, so there will be multiple points in a bounding box in the final result.
(I may not be very clear about this. The hash statement in the source code is completely confused. I don't know why to define this thing)
VoxelGrid is to keep a point in a voxel, and the result is similar to that of octree.

5. Summary

From the above analysis, it can be seen that when the voxel setting of Approximate is relatively large, it is consistent with the results of VoxelGrid; When the voxel setting is relatively small, there will be multiple points in an voxel. The threshold of voxel setting should be related to the number of bounding boxes of point cloud. If it is greater than 512, there will be multiple points in one voxel.
(about the source code of approve, I also have questions about hash. If the explanation is wrong, please point it out directly in the comment. Thank you.)

Keywords: C++

Added by ifuschini on Sun, 26 Sep 2021 04:32:26 +0300