4

Suppose we have a sequence of .pcd files in the directory point_clouds:

01.pcd
02.pcd
...
10.pcd

I am trying to visualize those files as a video (and potentially save them as a *mp4/avi). I tried two methods:

  1. Inspired by the Non-blocking visualization guide, this is the code I made:
import open3d as o3d
from pathlib import Path

pcs_path = Path("point_clouds")
pcd = o3d.io.read_point_cloud(str(pcs_path.joinpath("01.pcd")))

vis = o3d.visualization.Visualizer()
vis.create_window()
vis.add_geometry(pcd)

for p in pcs_path.iterdir():
    pcd = o3d.io.read_point_cloud(str(p))
    
    vis.update_geometry(pcd)
    vis.poll_events()
    vis.update_renderer()

vis.destroy_window()

The issue is that the video is stuck on the very first point cloud, without changing. I was wondering if I should update the pcd "inplace".

  1. I used the draw_geometries_with_custom_animation(...) method:
list_of_pcs = [o3d.io.read_point_cloud(str(p)) for p in pcs_path.iterdir()]
o3d.visualization.draw_geometries_with_custom_animation(list_of_pcs)

The issue here is that instead of a sequence, all point clouds are shown simultaneously.

dranaivo
  • 41
  • 3

2 Answers2

2

I couldn't get update_geometry to work, even following code that worked perfectly for others. My work around was to add a new geometry each time, which lets you get an animation, although it is a bit jittery:

import open3d as o3d
from natsort import natsorted
import os
import time

input_dir = "C:\Users\me\imagedir"
input_files = natsorted(os.listdir(input_dir))
    
# read first ply file
pcd = o3d.io.read_point_cloud(os.path.join(input_dir, input_files[0]))
vis_transform = [[1,0,0,0],[0,-1,0,0],[0,0,-1,0],[0,0,0,1]] # transforms to make viewpoint match camera perspective
pcd.transform(vis_transform)

# getting open3d to display the video
vis = o3d.visualization.Visualizer()
vis.create_window()

# iterate through remaining files     
for input_file in input_files[1:]:
    input_file = os.path.join(input_dir, input_file)
    
    # remove previous pointcloud and add new one    
    vis.remove_geometry(pcd,False)
    pcd = o3d.io.read_point_cloud(input_file) # Read the point cloud
    pcd.transform(vis_transform)
        
    # add pcd to visualizer
    vis.add_geometry(pcd)
    vis.poll_events()
    vis.update_renderer()
    time.sleep(0.005) # makes display a little smoother (display will not match fps of video)

vis.destroy_window()
Breadman10
  • 81
  • 6
0

If still relevant i would like to add to the answer. The solution that worked for me was to create an instance of a Pointcloud, add it as a geometry to the Visualizer and update the geometry.points attribute of this Pointlcoud instance each loop iteration. This solves the problem of removing and adding geometries each time and doesnt stutter. This sounds like, what you meant with "inplace".

I can't provide a MWE as it was very project specific and would take a long time to recreate.