PointCloudLibrary / pcl

Point Cloud Library (PCL)
https://pointclouds.org/
Other
9.89k stars 4.61k forks source link

[NDT Registration]Can calculate distribution map once? #5961

Closed PigBroA closed 7 months ago

PigBroA commented 7 months ago

Dear all,

I am using NDT registration for localization, let LiDAR local frame data as source cloud, and let global map(pre-built) as target cloud.

I guess NDT(in PCL) makes distribution map in "align" function, and "align" function usually operates in loop.

In my system, I don't have to change target cloud, so I think the system doesn't have to make distribution values in every loops.

Is there any solution the issue? I mean I want to calculate distribution map of target cloud once, let the distribution map hold on memory ,and then load the data to estimate transformation matrix.

Thanks for reading my question.

Please let me know how to do it or solution that already exist.

mvieth commented 7 months ago

The normal distributions of the target cloud are computed in setInputTarget. So if you call setInputTarget in the initial setup, and then alternately call setInputSource and align, the normal distributions will not be recomputed as far as I can see (though I have not tested this).

PigBroA commented 7 months ago

Dear @mvieth ,

Thanks for quick reply.

I am using pcl 1.10 version now, is this version doing same as well?

Actually, I tried 2 variations to test them, first one used voxelized target cloud, and second one used original target cloud, they have different point size. (the other conditions are all same, especially NDT resolution and source cloud size is same)

However, 2 processing time output very difference results, first case is very faster than second case(around 100 times, the value is not important), so I guess distribution map creation is on "align" function. (In loop, there are "setInputSource" and "align" function, other registration initializations are on outside of loop)

And in "align" function, we can see "computeTranformation" function and the function include distribution calculation.

Please re-check it.

Thank you very much.

mvieth commented 7 months ago

I am using pcl 1.10 version now, is this version doing same as well?

I am looking at the code on the master branch, but you can check if PCL 1.10 does the same by selecting the corresponding git branch.

However, 2 processing time output very difference results

Have you checked the processing time of a call to setInputTarget on its own? If you downsample the target cloud (fewer points), I would not be surprised if a single computation of the normal distributions is faster. It might also happen that the distribution map is different: there might be fewer cells with enough points to robustly estimate a normal distribution, which means that the overall registration process will be faster, but less precise. So just because the processing is faster if the target cloud is downsampled, does not necessarily mean that the distribution map is recomputed each time in the align function.

And in "align" function, we can see "computeTranformation" function and the function include distribution calculation.

Where does it include distribution calculation? Yes, align calls computeTransformation. But unless we are talking about different things, the normal distributions are calculated in init in ndt.h. init is not called from computeTransformation. It is called from setInputTarget and setResolution. So the normal distributions are only (re)calculated if you set/change the target cloud or the resolution.

PigBroA commented 7 months ago

Dear @mvieth ,

I am really appreciate your reply.

I have more a few questions.

Have you checked the processing time of a call to setInputTarget on its own? If you downsample the target cloud (fewer points), I would not be surprised if a single computation of the normal distributions is faster. It might also happen that the distribution map is different: there might be fewer cells with enough points to robustly estimate a normal distribution, which means that the overall registration process will be faster, but less precise. So just because the processing is faster if the target cloud is downsampled, does not necessarily mean that the distribution map is recomputed each time in the align function.

-->That means "some NDT grid be able to be ignored if the NDT grid includes a few point"?

and I just saw "align" function in ndt.hpp, I think there is no way to skip "computTransformation". Only "initCompute()" can pass "computTransformation" function, but the way can't operate anything.


template <typename PointSource, typename PointTarget, typename Scalar> inline void Registration<PointSource, PointTarget, Scalar>::align(PointCloudSource& output, const Matrix4& guess) { if (!initCompute()) return;

// Resize the output dataset output.resize(indices->size()); // Copy the header output.header = input->header; // Check if the output will be computed for all points or only a subset if (indices->size() != input->size()) { output.width = indices_->size(); output.height = 1; } else { output.width = static_cast(input->width); output.height = input->height; } output.isdense = input->is_dense;

// Copy the point data to output for (std::sizet i = 0; i < indices->size(); ++i) output[i] = (input_)[(indices_)[i]];

// Set the internal point representation of choice unless otherwise noted if (pointrepresentation && !force_norecompute) tree_->setPointRepresentation(pointrepresentation);

// Perform the actual transformation computation converged_ = false; finaltransformation = transformation_ = previoustransformation = Matrix4::Identity();

// Right before we estimate the transformation, we set all the point.data[3] values to // 1 to aid the rigid transformation for (std::sizet i = 0; i < indices->size(); ++i) output[i].data[3] = 1.0;

computeTransformation(output, guess);

deinitCompute(); }

By the way, could you please let me know distribution level access for pcl if there are?

Otherwise, can I get distribution visualization method with pcl? (any tips?)

Thank you.

mvieth commented 7 months ago

That means "some NDT grid be able to be ignored if the NDT grid includes a few point"?

I am not sure I understand what you mean

and I just saw "align" function in ndt.hpp, I think there is no way to skip "computTransformation". Only "initCompute()" can pass "computTransformation" function, but the way can't operate anything.

You mean the align function in registration.hpp? No, I did not mean that computeTransformation is skipped.

By the way, could you please let me know distribution level access for pcl if there are?

Again, I am not sure what you mean. If you want to access target_cells_, then you would have to create a subclass for NormalDistributionsTransform since it is a protected member.

Otherwise, can I get distribution visualization method with pcl? (any tips?)

NormalDistributionsTransform does not really have anything ready-to-use for visualization. When you found a way to get access to target_cells_, then you could have a look at getDisplayCloud

PigBroA commented 7 months ago

Dear @mvieth ,

Thank you very much, I'am gonna study more about procedure(NDT).

Have a good day.