mission_stock_pile_triangularization_true_data.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import open3d as o3d
  2. import numpy as np
  3. import math
  4. from scipy.spatial import Delaunay
  5. import math
  6. from functools import reduce
  7. import sys
  8. # pcd = o3d.io.read_point_cloud("data/2box-SG-t-MnQ0zoEQIBX.ply")
  9. # pcd = o3d.io.read_point_cloud("data/4box-1-SG-t-AsSRO3iA0XT.ply")
  10. # pcd = o3d.io.read_point_cloud("data/4box-2-SG-t-cp3kSewxMKi.ply")
  11. pcd = o3d.io.read_point_cloud("data/4box-3-SG-t-kuuv0moEP0C.ply")
  12. print(pcd)
  13. axes = o3d.geometry.TriangleMesh.create_coordinate_frame()
  14. # 找出地面所在平面
  15. plane_model, inliers = pcd.segment_plane(distance_threshold=0.01,
  16. ransac_n=3,
  17. num_iterations=10000)
  18. # # 把地面上的点和其他点分开
  19. # [a, b, c, d] = plane_model
  20. # plane_pcd = pcd.select_by_index(inliers)
  21. # plane_pcd.paint_uniform_color([1.0, 0, 0])
  22. # stockpile_pcd = pcd.select_by_index(inliers, invert=True)
  23. # stockpile_pcd.paint_uniform_color([0, 0, 1.0])
  24. # o3d.visualization.draw_geometries([plane_pcd, stockpile_pcd, axes])
  25. # 移动到原点
  26. plane_pcd = plane_pcd.translate((0,0,d/c))
  27. stockpile_pcd = stockpile_pcd.translate((0,0,d/c))
  28. # 旋转至与坐标轴对齐
  29. cos_theta = c / math.sqrt(a**2 + b**2 + c**2)
  30. sin_theta = math.sqrt((a**2+b**2)/(a**2 + b**2 + c**2))
  31. u_1 = b / math.sqrt(a**2 + b**2 )
  32. u_2 = -a / math.sqrt(a**2 + b**2)
  33. rotation_matrix = np.array([[cos_theta + u_1**2 * (1-cos_theta), u_1*u_2*(1-cos_theta), u_2*sin_theta],
  34. [u_1*u_2*(1-cos_theta), cos_theta + u_2**2*(1- cos_theta), -u_1*sin_theta],
  35. [-u_2*sin_theta, u_1*sin_theta, cos_theta]])
  36. plane_pcd.rotate(rotation_matrix)
  37. stockpile_pcd.rotate(rotation_matrix)
  38. # o3d.visualization.draw_geometries([plane_pcd, stockpile_pcd, axes])
  39. # 去除噪点
  40. cl, ind = stockpile_pcd.remove_statistical_outlier(nb_neighbors=30,
  41. std_ratio=2.0)
  42. stockpile_pcd = stockpile_pcd.select_by_index(ind)
  43. # o3d.visualization.draw_geometries([stockpile_pcd])
  44. # # 降采样
  45. # downpcd = stockpile_pcd.voxel_down_sample(voxel_size=0.05)
  46. # print(downpcd)
  47. downpcd = stockpile_pcd
  48. # 三角剖分
  49. xyz = np.asarray(downpcd.points)
  50. xy_catalog = []
  51. for point in xyz:
  52. xy_catalog.append([point[0], point[1]])
  53. tri = Delaunay(np.array(xy_catalog))
  54. surface = o3d.geometry.TriangleMesh()
  55. surface.vertices = o3d.utility.Vector3dVector(xyz)
  56. surface.triangles = o3d.utility.Vector3iVector(tri.simplices)
  57. surface.paint_uniform_color([0, 0, 1.0])
  58. # o3d.visualization.draw_geometries([surface], mesh_show_wireframe=True)
  59. def get_triangles_vertices(triangles, vertices):
  60. triangles_vertices = []
  61. for triangle in triangles:
  62. new_triangles_vertices = [vertices[triangle[0]], vertices[triangle[1]], vertices[triangle[2]]]
  63. triangles_vertices.append(new_triangles_vertices)
  64. return np.array(triangles_vertices)
  65. def volume_under_triangle(triangle):
  66. p1, p2, p3 = triangle
  67. x1, y1, z1 = p1
  68. x2, y2, z2 = p2
  69. x3, y3, z3 = p3
  70. return abs((z1+z2+z3)*(x1*y2-x2*y1+x2*y3-x3*y2+x3*y1-x1*y3)/6)
  71. print('sdfjsfksldfj')
  72. volume = reduce(lambda a, b: a + volume_under_triangle(b), get_triangles_vertices(surface.triangles, surface.vertices), 0)
  73. print(f"The volume of the stockpile is: {round(volume, 4)} m3")