Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

umeyama.py 1.9 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  1. import numpy as np
  2. def umeyama(src, dst, estimate_scale):
  3. """Estimate N-D similarity transformation with or without scaling.
  4. Parameters
  5. ----------
  6. src : (M, N) array
  7. Source coordinates.
  8. dst : (M, N) array
  9. Destination coordinates.
  10. estimate_scale : bool
  11. Whether to estimate scaling factor.
  12. Returns
  13. -------
  14. T : (N + 1, N + 1)
  15. The homogeneous similarity transformation matrix. The matrix contains
  16. NaN values only if the problem is not well-conditioned.
  17. References
  18. ----------
  19. .. [1] "Least-squares estimation of transformation parameters between two
  20. point patterns", Shinji Umeyama, PAMI 1991, DOI: 10.1109/34.88573
  21. """
  22. num = src.shape[0]
  23. dim = src.shape[1]
  24. # Compute mean of src and dst.
  25. src_mean = src.mean(axis=0)
  26. dst_mean = dst.mean(axis=0)
  27. # Subtract mean from src and dst.
  28. src_demean = src - src_mean
  29. dst_demean = dst - dst_mean
  30. # Eq. (38).
  31. A = np.dot(dst_demean.T, src_demean) / num
  32. # Eq. (39).
  33. d = np.ones((dim,), dtype=np.double)
  34. if np.linalg.det(A) < 0:
  35. d[dim - 1] = -1
  36. T = np.eye(dim + 1, dtype=np.double)
  37. U, S, V = np.linalg.svd(A)
  38. # Eq. (40) and (43).
  39. rank = np.linalg.matrix_rank(A)
  40. if rank == 0:
  41. return np.nan * T
  42. elif rank == dim - 1:
  43. if np.linalg.det(U) * np.linalg.det(V) > 0:
  44. T[:dim, :dim] = np.dot(U, V)
  45. else:
  46. s = d[dim - 1]
  47. d[dim - 1] = -1
  48. T[:dim, :dim] = np.dot(U, np.dot(np.diag(d), V))
  49. d[dim - 1] = s
  50. else:
  51. T[:dim, :dim] = np.dot(U, np.dot(np.diag(d), V))
  52. if estimate_scale:
  53. # Eq. (41) and (42).
  54. scale = 1.0 / src_demean.var(axis=0).sum() * np.dot(S, d)
  55. else:
  56. scale = 1.0
  57. T[:dim, dim] = dst_mean - scale * np.dot(T[:dim, :dim], src_mean.T)
  58. T[:dim, :dim] *= scale
  59. return T
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...