ethz-asl / segmap

A map representation based on 3D segments
BSD 3-Clause "New" or "Revised" License
1.06k stars 394 forks source link

Using Segmatch with region growing segmenter #50

Closed Tacoma closed 6 years ago

Tacoma commented 6 years ago

Hi everyone,

First of all, thanks for making the code available, I really liked the demonstrations and want to use SegMatch myself for indoor loop-closures. I already wrote some mails to @rdube, and got very helpful answers, thanks for the tips. Maybe someone else can benefit from my results, so I want to share where I got so far.

I am using simulated and real data from an VLP-16 and have disabled ICP, instead using the ground-truth trajectory (or cartographers trajectory for the real data) with some rotational drift. For the segmentation I have switched to the region-growing segmenter and changed some parameters. Although the segmentation is not yet perfect, I already have some good results as can be seen in the following:

As my dataset I use the corridor around a lecture hall, and its reconstructed mesh: mesh Here is one of the results loop_correct

So far I noticed that the repeating structures and symmetry is less of a problem than expected, because the segments are accumulated over a long time but consequently the overlapping trajectory must be large before the loop is detected. (The trajectory goes clockwise twice around the whole lecture hall, beginning slightly before the lower left corner)

The parameters for the region-growing segmenter itself work very well, however I had to change some other parameters to filter the pointcloud before segmenting to get good results:

Even when the drift is completely disabled the resulting map still has some duplicates as can be seen here: overlaying_segments

But still the resulting trajectory with loop-closures looks very nice and I hopefully can try to close some loops in different datasets. @rdube I would also like to try the shape descriptor if you still have the trained random forest and see, if loops can be found faster and with fewer segments with it.

rdube commented 6 years ago

Hi @Tacoma thanks a lot for sharing your experience and these interesting results! I believe that can be very helpful for other people wanting to look into the region growing segmentation based on smoothness constraint. What did you use as a centroid_distance_threshold_m for filtering the duplicates? https://github.com/ethz-asl/segmatch/blob/master/laser_mapper/launch/kitti/kitti_localization.yaml#L60

FYI maintenance of the target map and removal of these duplicates will be much more robust in the newer version of segmatch to be available soon.

I could not find the random forest with the shape descriptor on my machine (as we are not using it anymore). I will have a look asap to see if we have something in our backups. If you want you could think about designing a few simple descriptor for this tasks. I would imagine that information like length of the segment along the eigen vectors lying on the plane could help with the matching. Thanks again!

Tacoma commented 6 years ago

At the moment I'm using centroid_distance_threshold_m: 1.0 because some of the smaller features are rather close. But I might test larger values and see if the map gets better.

That sounds great, I understand that the map update was probably not the focus until now and am curious about the changes.

Tacoma commented 6 years ago

So I tested different values for the centroid_distance_threshold_m and evaluated the transformation error for found loops. The results (figure) show that for small values a lot of wrong loops are found, like you already noticed. Then up to 2 meters, the results are constant with a slow decline. Visually most of the duplicates are removed from 1 meter onwards, higher values do not remove more. So I guess values between 1 and 2 are good for this kind of environment.

_histogram centroid_distance_threshold_m

rdube commented 6 years ago

@Tacoma thank you for sharing this analysis! :-)

junzhang2016 commented 6 years ago

Hi, @Tacoma thanks very much for the sharing experience. May I ask do you use the raw point cloud (which is quite sparse) as the input, or do you use the densified point cloud? Thanks.

Tacoma commented 6 years ago

I accumulate one rotation and forward it to LaserSlam, so for SegMatch, the accumulated local map from LaserSlam is used. I'm not sure what you mean by densified point cloud. Looking at your issue, I also changed the accumulated_pointcloud_topic to the velodyneScan messages, but as I'm using the region growing, I can't comment on the other parameters.

rdube commented 6 years ago

@junzhang2016 fyi the following package can be helpful in order to accumulate the Velodyne point packets into a 360deg cloud by incorporating external odometry measurements: https://github.com/ethz-asl/laser_slam/tree/master/sensor_drivers/velodyne_assembler This is particularly relevant at high translational and rotational speeds.

junzhang2016 commented 6 years ago

Thank you, @Tacoma @rdube. I understood, the raw point cloud will be accumulated by laser_slam (especially, /laser_slam/tree/master/sensor_drivers/velodyne_assembler ), so that the input of segmatch will be the accumulated point cloud.

rdube commented 6 years ago

@junzhang2016 to be more precise. In the incremental version of segmatch the point cloud will be accumulated in a dynamic voxel grid. See: https://github.com/ethz-asl/segmap/blob/master/segmatch/include/segmatch/dynamic_voxel_grid.hpp