Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3D point cloud visualizer #101

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions script/3d_point_cloud_visualizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import open3d as o3d
import numpy as np
import tkinter as tk
from tkinter import filedialog, messagebox
import matplotlib.pyplot as plt

def apply_color_by_attribute(cloud, attribute):
colors = plt.get_cmap('viridis')(attribute)[:, :3]
cloud.colors = o3d.utility.Vector3dVector(colors)

def voxel_downsample(cloud, voxel_size=0.05):
return cloud.voxel_down_sample(voxel_size)

def compute_statistics(cloud, options):
results = {}
points = np.asarray(cloud.points)

if options['mean']:
results['mean'] = np.mean(points, axis=0)
if options['standard_deviation']:
results['standard_deviation'] = np.std(points, axis=0)

if options['density']:
bounding_box = cloud.get_axis_aligned_bounding_box()
volume = bounding_box.volume()
results['density'] = len(points) / volume if volume > 0 else 0

return results

def compute_geometric_properties(cloud, options):
results = {}

if options['centroid']:
results['centroid'] = cloud.get_center()
if options['bounding_box']:
bounding_box = cloud.get_axis_aligned_bounding_box()
results['bounding_box'] = str(bounding_box)
results['volume'] = bounding_box.volume()

return results

def visualize_ply(file_path, downsample=False, color_map=None, stats_options=None, geom_options=None):
cloud = o3d.io.read_point_cloud(file_path)
if downsample:
cloud = voxel_downsample(cloud)

if color_map == 'depth' and cloud.has_points():
zs = np.asarray(cloud.points)[:, 2]
zs_normalized = (zs - zs.min()) / (zs.max() - zs.min())
apply_color_by_attribute(cloud, zs_normalized)

stats_results = compute_statistics(cloud, stats_options)
geom_results = compute_geometric_properties(cloud, geom_options)

o3d.visualization.draw_geometries([cloud])

output_info = '\n'.join([f"{key}: {value}" for key, value in {**stats_results, **geom_results}.items()])
messagebox.showinfo("Point Cloud Analysis Results", output_info)

def gui():
root = tk.Tk()
root.title("3D Point Cloud Visualizer")
root.geometry("400x400")

downsample_var = tk.BooleanVar()
color_map_var = tk.StringVar(value='none')

open_button = tk.Button(root, text="Open PLY File", command=lambda: open_file_dialog())
open_button.pack(pady=10)

downsample_check = tk.Checkbutton(root, text="Apply Downsampling", variable=downsample_var)
downsample_check.pack(anchor='w')

color_map_label = tk.Label(root, text="Color Map:")
color_map_label.pack(anchor='w')

color_map_menu = tk.OptionMenu(root, color_map_var, 'none', 'depth')
color_map_menu.pack(anchor='w')

# Options for statistics and geometric properties
stats_options = {'mean': tk.BooleanVar(), 'standard_deviation': tk.BooleanVar(), 'density': tk.BooleanVar()}
geom_options = {'centroid': tk.BooleanVar(), 'bounding_box': tk.BooleanVar(), 'volume': tk.BooleanVar()}

# Creating checkboxes for each option
for key in stats_options:
tk.Checkbutton(root, text=f"{key.replace('_', ' ').title()}", variable=stats_options[key]).pack(anchor='w')
for key in geom_options:
tk.Checkbutton(root, text=f" {key.replace('_', ' ').title()}", variable=geom_options[key]).pack(anchor='w')

def open_file_dialog():
file_path = filedialog.askopenfilename(title='Select a PLY File', filetypes=[('PLY Files', '*.ply')])
if file_path:
visualize_ply(file_path, downsample_var.get(), color_map_var.get(),
{k: v.get() for k, v in stats_options.items()},
{k: v.get() for k, v in geom_options.items()})

root.mainloop()

if __name__ == "__main__":
gui()
44 changes: 44 additions & 0 deletions script/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

# 3D Point Cloud Visualizer

This tool provides a simple yet powerful way to visualize and analyze 3D point cloud data.

## Features

- Load `.ply` files and visualize them in a 3D space.
- Apply voxel downsampling to simplify point clouds.
- Calculate and display various statistical measures such as mean, standard deviation, and point density.
- Compute geometric properties including the centroid and volume of the bounding box.
- Interactive GUI for easy manipulation and analysis.

## Installation

To set up the 3D Point Cloud Visualizer, you will need Python and Open3D library.


pip install open3d matplotlib tkinter


## Usage

Run the application from the command line:


python point_cloud_visualizer.py


In the GUI:

1. Click `Open PLY File` to load your point cloud data.
2. Select options for downsampling and color mapping as needed.
3. Choose the statistical and geometric properties you wish to calculate.
4. View the results and visualizations immediately.

## Contributing

We welcome contributions to this project! Please consider the following steps:


## License

Distributed under the MIT License. See `LICENSE` for more information.
Binary file added script/image1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added script/image2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added script/image3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added script/image4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.