mission_convex_hull.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  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. import copy
  9. pcd = o3d.io.read_point_cloud("data/stockpile.ply")
  10. # pcd = o3d.io.read_point_cloud("../laser1.ply")
  11. # print(pcd) # 输出点云点的个数
  12. o3d.visualization.draw([pcd])
  13. print("Paint pointcloud")
  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=50,
  41. std_ratio=5.0)
  42. stockpile_pcd = stockpile_pcd.select_by_index(ind)
  43. o3d.visualization.draw([stockpile_pcd])
  44. hull, idx = stockpile_pcd.compute_convex_hull()
  45. hull.paint_uniform_color([1, 0.7, 0]) # 给凸包渲染颜色
  46. area = hull.get_surface_area() # 计算表面积
  47. volume = hull.get_volume() # 计算体积
  48. print("表面积为:", area)
  49. print("体积为:", volume)
  50. o3d.visualization.draw_geometries([stockpile_pcd, hull])