|
import plotly.graph_objects as go |
|
import open3d as o3d |
|
import numpy as np |
|
import textwrap |
|
|
|
def read_pcd(pcd_path): |
|
pcd = o3d.io.read_point_cloud(pcd_path) |
|
xyz = np.asarray(pcd.points) |
|
rgb = np.asarray(pcd.colors) |
|
if not pcd.has_normals(): |
|
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=100)) |
|
normal = np.asarray(pcd.normals) |
|
return xyz, rgb, normal |
|
|
|
def render_pcd_file(pcd_path): |
|
pcd = o3d.io.read_point_cloud(pcd_path) |
|
xyz = np.asarray(pcd.points) |
|
rgb = np.asarray(pcd.colors) |
|
return render_point_cloud(xyz, rgb) |
|
|
|
def render_point_cloud(xyz, rgb, legend=None): |
|
x = xyz[:, 0] |
|
y = xyz[:, 1] |
|
z = xyz[:, 2] |
|
rgb = rgb * 255 |
|
hex_colors = [f'#{int(r):02x}{int(g):02x}{int(b):02x}' for r, g, b in rgb] |
|
|
|
fig = go.Figure(data=[go.Scatter3d(x=x, y=y, z=z, mode='markers', |
|
marker=dict(size=2, color=hex_colors, colorscale='Viridis', opacity=0.8))]) |
|
|
|
if legend: |
|
fig.add_annotation(x=0.5, y=1.25, text="<br>".join(textwrap.wrap(legend, width=30)), showarrow=False, xref="paper", yref="paper") |
|
|
|
|
|
fig.update_layout( |
|
scene=dict( |
|
xaxis=dict(title='x', showgrid=False, zeroline=False, visible=False), |
|
yaxis=dict(title='y', showgrid=False, zeroline=False, visible=False), |
|
zaxis=dict(title='z', showgrid=False, zeroline=False, visible=False), |
|
aspectmode='manual'), |
|
scene_camera=dict( |
|
up=dict(x=0, y=1, z=0), |
|
eye=dict(x=0, y=-0.9, z=2), |
|
center = dict(x=0,y=0,z=0) |
|
) |
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return fig |