siavashk / pycpd

Pure Numpy Implementation of the Coherent Point Drift Algorithm
MIT License
523 stars 117 forks source link

[BUG] scale always acive #90

Closed rejuce closed 1 month ago

rejuce commented 1 month ago

I am trying to fit a 2D contour (x,y,constant) to a 3D pointcloud. I get very instable results because the scale gets varied. I know already that both have the correct scale, so scale can be fixed.

looking at the code from the init, there should be a scale parameter, which i would assume to disable scaling which I am using like this

reg = RigidRegistration(X=self.pointsNpCam, Y=self.cadNpPrealigned, s=1, scale=False) reg.scale= False self.TY, (s, R, t) = reg.register()

still I get in the End values for s, very far from 1. How can I clamp scale at 1?

is it also possible to clamp rotations around a certain axis?

rejuce commented 1 month ago

i saw in #84 that the pip version does not take account of the parameter, I reinstalled the version from the repository. If now I set scale=False

i get this errors which is a bit surpsiring.

File /opt/conda/lib/python3.11/site-packages/pycpd/rigid_registration.py:85, in RigidRegistration.update_transform(self) 82 self.A = np.dot(self.A, Yhat) 84 # Singular value decomposition as per lemma 1 of https://arxiv.org/pdf/0905.2635.pdf. ---> 85 U, , V = np.linalg.svd(self.A, full_matrices=True) 86 C = np.ones((self.D, )) 87 C[self.D-1] = np.linalg.det(np.dot(U, V))

File <__array_function__ internals>:200, in svd(*args, **kwargs)

File /opt/conda/lib/python3.11/site-packages/numpy/linalg/linalg.py:1642, in svd(a, full_matrices, compute_uv, hermitian) 1639 gufunc = _umath_linalg.svd_n_s 1641 signature = 'D->DdD' if isComplexType(t) else 'd->ddd' -> 1642 u, s, vh = gufunc(a, signature=signature, extobj=extobj) 1643 u = u.astype(result_t, copy=False) 1644 s = s.astype(_realType(result_t), copy=False)

File /opt/conda/lib/python3.11/site-packages/numpy/linalg/linalg.py:98, in _raise_linalgerror_svd_nonconvergence(err, flag) 97 def _raise_linalgerror_svd_nonconvergence(err, flag): ---> 98 raise LinAlgError("SVD did not converge")

LinAlgError: SVD did not converge

the task looks like this, the blue point cloud is to be fit to the green line, scale=1, so there is just translation and slight rotation x,y plane involved. grafik

if i turn on scale=True, i get something like that grafik

hence my question if rotation around a certain axis can be clamped

gattia commented 1 month ago

I assume this has something to do with there being many possible solutions to this problem. Eg the cylinder seems like it needs a fixed translation in xy, but then an infinite number of translations in z would work equally well. Unless there is a reason it does not make sense, I suggest duplicating the green line multiple times along the z axis. Ideally, you’d add duplicates at the min/max the cylinder is expected to be in the z axis. Sent from my iPhoneOn Sep 20, 2024, at 7:19 AM, rejuce @.> wrote: i saw in #84 that the pip version does not take account of the parameter, I reinstalled the version from the repository. If now I set scale=False i get this errors which is a bit surpsiring. File /opt/conda/lib/python3.11/site-packages/pycpd/rigid_registration.py:85, in RigidRegistration.update_transform(self) 82 self.A = np.dot(self.A, Yhat) 84 # Singular value decomposition as per lemma 1 of https://arxiv.org/pdf/0905.2635.pdf. ---> 85 U, , V = np.linalg.svd(self.A, full_matrices=True) 86 C = np.ones((self.D, )) 87 C[self.D-1] = np.linalg.det(np.dot(U, V)) File :200, in svd(args, kwargs) File /opt/conda/lib/python3.11/site-packages/numpy/linalg/linalg.py:1642, in svd(a, full_matrices, compute_uv, hermitian) 1639 gufunc = _umath_linalg.svd_n_s 1641 signature = 'D->DdD' if isComplexType(t) else 'd->ddd' -> 1642 u, s, vh = gufunc(a, signature=signature, extobj=extobj) 1643 u = u.astype(result_t, copy=False) 1644 s = s.astype(_realType(result_t), copy=False) File /opt/conda/lib/python3.11/site-packages/numpy/linalg/linalg.py:98, in _raise_linalgerror_svd_nonconvergence(err, flag) 97 def _raise_linalgerror_svd_nonconvergence(err, flag): ---> 98 raise LinAlgError("SVD did not converge") LinAlgError: SVD did not converge the task looks like this, the blue point cloud is to be fit to the green line, scale=1, so there is just translation and slight rotation x,y plane involved. grafik.png (view on web) if i turn on rotation i get something like that grafik.png (view on web) hence my question if rotation around a certain axis can be clamped

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>

rejuce commented 1 month ago

thanks for your reply.

mhm the obejct as differnt facets on differnt heights as well as variable diameter, so there should be exactly one height that fits perfectly (there is some rotation symetry thoug ). i try with higher resolution of the pointcloud and see then...

grafik grafik

gattia commented 1 month ago

I see. That’s why the rotation version seems to be a suitable fit. Essentially, I think the issue comes down to the target being a single line. If you can expand that to be multiple lines in any way, I think that will improve your results. Sent from my iPhoneOn Sep 20, 2024, at 7:51 AM, rejuce @.***> wrote: thanks for your reply. mhm the obejct as differnt facets on differnt heights as well as variable diameter, so there should be exactly one height and one rotation (its not rotation symetric) that fits perfectly. i try with higher resolution of the pointcloud and see then... grafik.png (view on web)

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>