问题
I got two point clouds and try to scale them to the same size. My first approach was to just divide the square roots from the eigenvalues:
pcl::PCA<pcl::PointNormal> pca;
pca.setInputCloud(model_cloud_ptr);
Eigen::Vector3f ev_M = pca.getEigenValues();
pca.setInputCloud(segmented_cloud_ptr);
Eigen::Vector3f ev_S = pca.getEigenValues();
double s = sqrt(ev_M[0])/sqrt(ev_S[0]);
This helps me to scale my model cloud to have approximately the same size as my segmented cloud. But the result is really not that perfect. It is a simple estimation. I tried doing it with TransformationEstimationSVDScale and also with SampleConsensusModelRegistration
like in this tutorial. But when doing this I get the message, that the number of source points/indices differs from the number of target points/indices.
What would be the best approach for me to scale the clouds to the same size, when having different numbers of points in them?
Edit I tried doing what @dspeyer proposed but this gives me a scaling factor of almost 1.0
pcl::PCA<pcl::PointNormal> pca;
pca.setInputCloud(model_cloud_ptr);
Eigen::Matrix3f ev_M = pca.getEigenVectors();
Eigen::Vector3f ev_M1 = ev_M.col(0);
Eigen::Vector3f ev_M2 = ev_M.col(1);
auto dist_M1 = ev_M1.maxCoeff()-ev_M1.minCoeff();
auto dist_M2 = ev_M2.maxCoeff()-ev_M2.minCoeff();
auto distM_max = std::max(dist_M1, dist_M2);
pca.setInputCloud(segmented_cloud_ptr);
Eigen::Matrix3f ev_S = pca.getEigenVectors();
Eigen::Vector3f ev_S1 = ev_S.col(0);
Eigen::Vector3f ev_S2 = ev_S.col(1);
auto dist_S1 = ev_S1.maxCoeff()-ev_S1.minCoeff();
auto dist_S2 = ev_S2.maxCoeff()-ev_S2.minCoeff();
auto distS_max = std::max(dist_S1, dist_S2);
double s = distS_max / distM_max;
回答1:
Seems like you should be able to:
- Project everything onto the first two eigenvectors
- Take the min and max for each
- Subtract max-min for each eigenvector/dataset pair
- Take the max of the two ranges (usually, but not always the first eigenvector -- when it isn't you'll want to rotate the final display)
- Use the ratio of those maxes as the scaling constant
回答2:
I think you were close with your idea of comparing the primary eigen vectors. I would think though that there is no need to take a square root. Ie just stick with:
double s = ev_M[0]/ev_S[0];
Another thing that may be relevant, is as I do not know the source of your cloud scaling in the first place, it may be relevant to allow axial warping. In other words take all 3 eigen vectors and scale each axis individually based on the ratio.
Also, it is critically important that if you are doing axially specific warping that you scale along the eigen vectors of the cloud to be scaled and not along xyz.
来源:https://stackoverflow.com/questions/59395218/pcl-scale-two-point-clouds-to-the-same-size