Hi everyone,
I'm working on automating a workflow in CloudCompare using Python and have encountered an interesting difference between the manual Tools > Fit > Plane tool and a plane fit implemented using Principal Component Analysis (PCA) via NumPy in my script.
I need to fit a plane to a point cloud (which is a scanned surface), then transform the cloud using the plane's parameters so the plane aligns with the Z=0 plane. Afterwards, I want to analyze the distribution of the transformed Z coordinates (specifically, the mean of absolute Z values, representing a kind of average deviation or depth). It's important for my analysis that all points in the cloud are considered for the fitting process.
If I choose the manual Fit > Plane option and then transform the point cloud with the resulting plane's matrix, the average absolute Z is ≈ 1.9xx. However, if I do this using the PCA method implemented in my script and use the matrix derived from that, the average absolute Z is ≈ 0.8xx.
Here are the two 4x4 transformation matrices obtained from the respective methods:
Script (PCA) Matrix:
[[ 0.80331824 0.59555 -0. 5.98697916]
[ -0.59554184 0.80330723 0.00523582 149.97019635]
[ 0.00311819 -0.00420603 0.99998629 1.11900961]
[ 0. 0. 0. 1. ]]
Manual Fit > Plane Matrix (copied from console):
[[ 0.99999511 0.00000656 -0.00311819 -0.00470734]
[ 0.00000656 0.99999118 0.00420603 0.00636292]
[ 0.00311819 -0.00420603 0.99998629 -0.78520048]
[ 0. 0. 0. 1. ]]
Interestingly, when I compare the fundamental plane parameters calculated by the two methods, the Normal Vector and the RMS Error are almost perfectly identical:
Normal Vector ≈ [0.0031, -0.0042, 1.0000] in both cases.
RMS Error ≈ 1.022 in both cases.
Since the normals and RMS match, the difference in the final result seems to originate from the determination of the exact plane position. My hypothesis is that the manual Tools > Fit > Plane tool might be using a robust algorithm internally (like RANSAC with default parameters?), which could explain the difference compared to the PCA method, which considers all points equally (and inherently passes through the exact centroid). I noted there are no configurable options in the Fit > Plane GUI dialog in my version.
Could someone please help clarify:
What algorithm does the standard Tools > Fit > Plane tool use internally to determine the best-fit plane?
Does it implicitly use any robustness/outlier filtering (like RANSAC) by default?
Is there any way via the pycc Python API to achieve the exact same fitting result as the manual tool?
Knowing the difference in algorithms would help me decide which method's result is appropriate for my analysis, where all points need to be considered.
My CloudCompare version is 2.13.2.
Thanks in advance for any help and information!
Best regards,
[Krinomix]
Fitting plane
Re: Fitting plane
Pretty simply algorithm, based on PCA as well (= eigenvalues and eigenvectors of the covariance matrix): see https://github.com/CloudCompare/CCCoreL ... d.cpp#L200
No RANSAC strategy or outliers removal.
And the fact that the normal is exactly the same means that you probably use more or less the same algorithm, but It's possible that you have a different way to select the X and Y directions (= 2D basis inside the plane). But it does not change the plane equation anyway. And as for the origin, there's an infinity of solutions. I just tend to think that using the gravity center, or any point close the input points, reduces numerical inaccuracy. Here, your Python algorithm seems to use something very close to (0, 0, 0) - maybe simply the projection of (0, 0, 0) onto the resulting plane. This may not give good results if the point coordinates are huge.
And I don't know what's available via the Python wrappers (you may want to ask the question on their respective github pages).
No RANSAC strategy or outliers removal.
And the fact that the normal is exactly the same means that you probably use more or less the same algorithm, but It's possible that you have a different way to select the X and Y directions (= 2D basis inside the plane). But it does not change the plane equation anyway. And as for the origin, there's an infinity of solutions. I just tend to think that using the gravity center, or any point close the input points, reduces numerical inaccuracy. Here, your Python algorithm seems to use something very close to (0, 0, 0) - maybe simply the projection of (0, 0, 0) onto the resulting plane. This may not give good results if the point coordinates are huge.
And I don't know what's available via the Python wrappers (you may want to ask the question on their respective github pages).
Daniel, CloudCompare admin