PointCloudLibrary / pcl

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

SampleConsensusModel computeModel results are different on windows and Linux #5946

Closed wx79889960 closed 9 months ago

wx79889960 commented 9 months ago

The fitting ball code based on pcl 1.12.1 was transplanted from Linux to windows. It was found that the fitting results of the same data were different, so the eigen version was unified. Compared with the ball parameters obtained in the first iteration, the ball parameters are still different. Thanks for your reply if there is any possible reason for this difference, sphere.pdf

mvieth commented 9 months ago

I would say the likeliest reason is that the compilers generated different machine code, perhaps because of different compiler flags (e.g. optimization flags, which can influence the accuracy of mathematical operations). The centre of your sphere is far away from the origin (0, 0, 0), which might lead to numerical instability. Another possible reason could be that you told the model to use a random seed based on the current time, so that each time you run the code, different samples are selected. However, the default is to use a fixed random seed (12345). You might also want to consider using a newer PCL version. In PCL 1.13.0, the sphere model computation was changed from single precision to double precision. This might improve the results in your case. In the end, both programs have found models with a similar number of inliers and similar coefficients, in a similar number of trials.

wx79889960 commented 9 months ago

Thank you for your response!The default seed 12345 was used in both tests in the pdf, and I tried to reproduce computeModelCoefficients using the sampling index and data used in the first iteration, I get the same results and am confused;like this:

    int array[] = { 3578,85,2754,4671 };
Eigen::Matrix4f temp;
std::cout.precision(20);
std::cout.flags(std::cout.fixed);
cv::Mat test(4, 4, CV_32FC1);
for (int i = 0; i < 4; i++)
{
    temp(i, 0) = cloudRoi->points[array[i]].x;
    temp(i, 1) = cloudRoi->points[array[i]].y;
    temp(i, 2) = cloudRoi->points[array[i]].z;
    temp(i, 3) = 1;

    test.at<float>(i, 0) = cloudRoi->points[array[i]].x;
    test.at<float>(i, 1) = cloudRoi->points[array[i]].y;
    test.at<float>(i, 2) = cloudRoi->points[array[i]].z;
    test.at<float>(i, 3) = 1;
}
float m11 = temp.determinant();
double testResult = cv::determinant(test);

for (int i = 0; i < 4; ++i)
{
    temp(i, 0) = (cloudRoi->points[array[i]].x) * (cloudRoi->points[array[i]].x) +
        (cloudRoi->points[array[i]].y) * (cloudRoi->points[array[i]].y) +
        (cloudRoi->points[array[i]].z) * (cloudRoi->points[array[i]].z);
}
float m12 = temp.determinant();

for (int i = 0; i < 4; ++i)
{
    temp(i, 1) = temp(i, 0);
    temp(i, 0) = cloudRoi->points[array[i]].x;
}
float m13 = temp.determinant();

for (int i = 0; i < 4; ++i)
{
    temp(i, 2) = temp(i, 1);
    temp(i, 1) = cloudRoi->points[array[i]].y;
}
float m14 = temp.determinant();

for (int i = 0; i < 4; ++i)
{
    temp(i, 0) = temp(i, 2);
    temp(i, 1) = cloudRoi->points[array[i]].x;
    temp(i, 2) = cloudRoi->points[array[i]].y;
    temp(i, 3) = cloudRoi->points[array[i]].z;
}
float m15 = temp.determinant();

Eigen::VectorXf model_coefficients;
model_coefficients.resize(4);
model_coefficients[0] = 0.5f * m12 / m11;
model_coefficients[1] = 0.5f * m13 / m11;
model_coefficients[2] = 0.5f * m14 / m11;
// Radius
model_coefficients[3] = std::sqrt(model_coefficients[0] * model_coefficients[0] +
    model_coefficients[1] * model_coefficients[1] +
    model_coefficients[2] * model_coefficients[2] - m15 / m11);
wx79889960 commented 9 months ago

When I debug the computeModelCoefficients interface, m12 starts to show differences, Maybe there is something else causing the difference in RandomSampleConsensus::computeModel? Eigen version is 3.3.9

wx79889960 commented 9 months ago

You are right, the difference is caused by the optimization flag. I compared the Debug of Windows and the ReleaseWithDebugInfo of Linux, so the difference is caused; Thank you very much, this question can be closed