目录
安装及示例
显示obj对象,设置一种颜色:
读取转换txt
draw和draw_geometries区别
可视化完整demo
保存png
pip install open3d
插播:mayavi也可以可视化点云。
conda install mayavi
示例demo:
GitHub - isl-org/Open3D: Open3D: A Modern Library for 3D Data Processing
添加物体:
examples/python/gui/add-geometry.py
import copy
import numpy as np
import open3d as o3d
if __name__ == '__main__':
print("Testing mesh in open3d ...")
mesh = o3d.io.read_triangle_mesh("../mesh.obj")
print(mesh)
print(np.asarray(mesh.vertices))
print(np.asarray(mesh.triangles))
verts = np.asarray(mesh.vertices)
mesh.vertices = o3d.utility.Vector3dVector(verts)
mesh.compute_vertex_normals()
mesh.paint_uniform_color([0.6, 0.1, 0.5])
cords = o3d.geometry.TriangleMesh.create_coordinate_frame()
o3d.visualization.draw_geometries([mesh])
import open3d as o3d
source = o3d.io.read_point_cloud('semantic3d/birdfountain_station1_xyz_intensity_rgb.txt' ,format="xyz")
source.paint_uniform_color([0, 255, 0])
o3d.visualization.draw_geometries([source])
保存:
3.直接读取、写pcd、mesh文件
pcd = open3d.io.read_point_cloud(pcd_file_path)
open3d.io.write_point_cloud("filename.pcd",pcd)
open3d.io.write_point_cloud("aaaa.ply",pcd)
draw PointCloud,会出现菜单,按钮,但是点云不能旋转平移。
pc =open3d.geometry.PointCloud()
# pc = open3d.PointCloud()
pc.points = open3d.utility.Vector3dVector(pc_xyzrgb[:, 0:3])
#pc.points = open3d.Vector3dVector(pc_xyzrgb[:, 0:3])
if pc_xyzrgb.shape[1] == 3:
open3d.draw_geometries([pc])
return 0
if np.max(pc_xyzrgb[:, 3:6]) > 20: ## 0-255
pc.colors =[255,0,0]# open3d.utility.Vector3dVector(pc_xyzrgb[:, 3:6] *255/ 255.)
else:
pc.colors =open3d.utility.Vector3dVector(pc_xyzrgb[:, 3:6])
# open3d.visualization.draw_geometries([pc])
open3d.visualization.draw([pc])
同时显示两个物体,设置不同颜色
import math
import numpy as np
import open3d as o3d
import open3d.visualization as vis
import os
import random
import sys
sys.path.insert(1, os.path.join(sys.path[0], '..'))
import open3d_tutorial as o3dtut
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__))
def normalize(v):
a = 1.0 / math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])
return (a * v[0], a * v[1], a * v[2])
def make_point_cloud(npts, center, radius, colorize):
pts = np.random.uniform(-radius, radius, size=[npts, 3]) + center
cloud = o3d.geometry.PointCloud()
cloud.points = o3d.utility.Vector3dVector(pts)
if colorize:
colors = np.random.uniform(0.0, 1.0, size=[npts, 3])
cloud.colors = o3d.utility.Vector3dVector(colors)
return cloud
def single_object():
# No colors, no normals, should appear unlit black
cube = o3d.geometry.TriangleMesh.create_box(1, 2, 1)
vis.draw(cube)
def multi_objects():
pc_rad = 1.0
pc_nocolor = make_point_cloud(100, (0, -2, 0), pc_rad, False)
pc_color = make_point_cloud(100, (3, -2, 0), pc_rad, True)
r = 0.4
sphere_unlit = o3d.geometry.TriangleMesh.create_sphere(r)
sphere_unlit.paint_uniform_color((0.5, 0.5, 0.0)) #颜色 rgb
sphere_unlit.translate((0, 1, 0)) #位置格子
sphere_colored_unlit = o3d.geometry.TriangleMesh.create_sphere(r)
sphere_colored_unlit.paint_uniform_color((1.0, 0.0, 0.0))
sphere_colored_unlit.translate((2, 1, 0))
sphere_lit = o3d.geometry.TriangleMesh.create_sphere(r)
sphere_lit.compute_vertex_normals()
sphere_lit.translate((4, 1, 0))
sphere_colored_lit = o3d.geometry.TriangleMesh.create_sphere(r)
sphere_colored_lit.compute_vertex_normals()
sphere_colored_lit.paint_uniform_color((0.0, 1.0, 0.0))
sphere_colored_lit.translate((6, 1, 0))
big_bbox = o3d.geometry.AxisAlignedBoundingBox((-pc_rad, -3, -pc_rad),
(6.0 + r, 1.0 + r, pc_rad))
sphere_bbox = sphere_unlit.get_axis_aligned_bounding_box()
sphere_bbox.color = (1.0, 0.5, 0.0)
lines = o3d.geometry.LineSet.create_from_axis_aligned_bounding_box(
sphere_lit.get_axis_aligned_bounding_box())
lines_colored = o3d.geometry.LineSet.create_from_axis_aligned_bounding_box(
sphere_colored_lit.get_axis_aligned_bounding_box())
lines_colored.paint_uniform_color((0.0, 0.0, 1.0))
vis.draw([
pc_nocolor, pc_color, sphere_unlit, sphere_colored_unlit, sphere_lit,
sphere_colored_lit, big_bbox, sphere_bbox, lines, lines_colored
])
def actions():
SOURCE_NAME = "Source"
RESULT_NAME = "Result (Poisson reconstruction)"
TRUTH_NAME = "Ground truth"
bunny = o3dtut.get_bunny_mesh()
bunny.paint_uniform_color((1, 0.75, 0))
bunny.compute_vertex_normals()
cloud = o3d.geometry.PointCloud()
cloud.points = bunny.vertices
cloud.normals = bunny.vertex_normals
def make_mesh(o3dvis):
# TODO: call o3dvis.get_geometry instead of using bunny
mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
cloud)
mesh.paint_uniform_color((1, 1, 1))
mesh.compute_vertex_normals()
o3dvis.add_geometry({"name": RESULT_NAME, "geometry": mesh})
o3dvis.show_geometry(SOURCE_NAME, False)
def toggle_result(o3dvis):
truth_vis = o3dvis.get_geometry(TRUTH_NAME).is_visible
o3dvis.show_geometry(TRUTH_NAME, not truth_vis)
o3dvis.show_geometry(RESULT_NAME, truth_vis)
vis.draw([{
"name": SOURCE_NAME,
"geometry": cloud
}, {
"name": TRUTH_NAME,
"geometry": bunny,
"is_visible": False
}],
actions=[("Create Mesh", make_mesh),
("Toggle truth/result", toggle_result)])
def get_icp_transform(source, target, source_indices, target_indices):
corr = np.zeros((len(source_indices), 2))
corr[:, 0] = source_indices
corr[:, 1] = target_indices
# Estimate rough transformation using correspondences
p2p = o3d.pipelines.registration.TransformationEstimationPointToPoint()
trans_init = p2p.compute_transformation(source, target,
o3d.utility.Vector2iVector(corr))
# Point-to-point ICP for refinement
threshold = 0.03 # 3cm distance threshold
reg_p2p = o3d.pipelines.registration.registration_icp(
source, target, threshold, trans_init,
o3d.pipelines.registration.TransformationEstimationPointToPoint())
return reg_p2p.transformation
def selections():
source = o3d.io.read_point_cloud(SCRIPTDIR +
"/../../test_data/ICP/cloud_bin_0.pcd")
target = o3d.io.read_point_cloud(SCRIPTDIR +
"/../../test_data/ICP/cloud_bin_2.pcd")
source.paint_uniform_color([1, 0.706, 0])
target.paint_uniform_color([0, 0.651, 0.929])
source_name = "Source (yellow)"
target_name = "Target (blue)"
def do_icp_one_set(o3dvis):
# sets: [name: [{ "index": int, "order": int, "point": (x, y, z)}, ...],
# ...]
sets = o3dvis.get_selection_sets()
source_picked = sorted(list(sets[0][source_name]),
key=lambda x: x.order)
target_picked = sorted(list(sets[0][target_name]),
key=lambda x: x.order)
source_indices = [idx.index for idx in source_picked]
target_indices = [idx.index for idx in target_picked]
t = get_icp_transform(source, target, source_indices, target_indices)
source.transform(t)
# Update the source geometry
o3dvis.remove_geometry(source_name)
o3dvis.add_geometry({"name": source_name, "geometry": source})
def do_icp_two_sets(o3dvis):
sets = o3dvis.get_selection_sets()
source_set = sets[0][source_name]
target_set = sets[1][target_name]
source_picked = sorted(list(source_set), key=lambda x: x.order)
target_picked = sorted(list(target_set), key=lambda x: x.order)
source_indices = [idx.index for idx in source_picked]
target_indices = [idx.index for idx in target_picked]
t = get_icp_transform(source, target, source_indices, target_indices)
source.transform(t)
# Update the source geometry
o3dvis.remove_geometry(source_name)
o3dvis.add_geometry({"name": source_name, "geometry": source})
vis.draw([{
"name": source_name,
"geometry": source
}, {
"name": target_name,
"geometry": target
}],)
# actions=[("ICP Registration (one set)", do_icp_one_set),
# ("ICP Registration (two sets)", do_icp_two_sets)],
# show_ui=True)
def time_animation():
orig = make_point_cloud(200, (0, 0, 0), 1.0, True)
clouds = [{"name": "t=0", "geometry": orig, "time": 0}]
drift_dir = (1.0, 0.0, 0.0)
expand = 1.0
n = 20
for i in range(1, n):
amount = float(i) / float(n - 1)
cloud = o3d.geometry.PointCloud()
pts = np.asarray(orig.points)
pts = pts * (1.0 + amount * expand) + [amount * v for v in drift_dir]
cloud.points = o3d.utility.Vector3dVector(pts)
cloud.colors = orig.colors
clouds.append({
"name": "points at t=" + str(i),
"geometry": cloud,
"time": i
})
vis.draw(clouds)
def groups():
building_mat = vis.rendering.Material()
building_mat.shader = "defaultLit"
building_mat.base_color = (1.0, .90, .75, 1.0)
building_mat.base_reflectance = 0.1
midrise_mat = vis.rendering.Material()
midrise_mat.shader = "defaultLit"
midrise_mat.base_color = (.475, .450, .425, 1.0)
midrise_mat.base_reflectance = 0.1
skyscraper_mat = vis.rendering.Material()
skyscraper_mat.shader = "defaultLit"
skyscraper_mat.base_color = (.05, .20, .55, 1.0)
skyscraper_mat.base_reflectance = 0.9
skyscraper_mat.base_roughness = 0.01
buildings = []
size = 10.0
half = size / 2.0
min_height = 1.0
max_height = 20.0
for z in range(0, 10):
for x in range(0, 10):
max_h = max_height * (1.0 - abs(half - x) / half) * (
1.0 - abs(half - z) / half)
h = random.uniform(min_height, max(max_h, min_height + 1.0))
box = o3d.geometry.TriangleMesh.create_box(0.9, h, 0.9)
box.compute_triangle_normals()
box.translate((x + 0.05, 0.0, z + 0.05))
if h > 0.333 * max_height:
mat = skyscraper_mat
elif h > 0.1 * max_height:
mat = midrise_mat
else:
mat = building_mat
buildings.append({
"name": "building_" + str(x) + "_" + str(z),
"geometry": box,
"material": mat,
"group": "buildings"
})
haze = make_point_cloud(5000, (half, 0.333 * max_height, half),
1.414 * half, False)
haze.paint_uniform_color((0.8, 0.8, 0.8))
smog = make_point_cloud(10000, (half, 0.25 * max_height, half), 1.2 * half,
False)
smog.paint_uniform_color((0.95, 0.85, 0.75))
vis.draw(buildings + [{
"name": "haze",
"geometry": haze,
"group": "haze"
}, {
"name": "smog",
"geometry": smog,
"group": "smog"
}])
def remove():
def make_sphere(name, center, color, group, time):
sphere = o3d.geometry.TriangleMesh.create_sphere(0.5)
sphere.compute_vertex_normals()
sphere.translate(center)
mat = vis.rendering.Material()
mat.shader = "defaultLit"
mat.base_color = color
return {
"name": name,
"geometry": sphere,
"material": mat,
"group": group,
"time": time
}
red = make_sphere("red", (0, 0, 0), (1.0, 0.0, 0.0, 1.0), "spheres", 0)
green = make_sphere("green", (2, 0, 0), (0.0, 1.0, 0.0, 1.0), "spheres", 0)
blue = make_sphere("blue", (4, 0, 0), (0.0, 0.0, 1.0, 1.0), "spheres", 0)
yellow = make_sphere("yellow", (0, 0, 0), (1.0, 1.0, 0.0, 1.0), "spheres",
1)
bbox = {
"name": "bbox",
"geometry": red["geometry"].get_axis_aligned_bounding_box()
}
def remove_green(visdraw):
visdraw.remove_geometry("green")
def remove_yellow(visdraw):
visdraw.remove_geometry("yellow")
def remove_bbox(visdraw):
visdraw.remove_geometry("bbox")
vis.draw([red, green, blue, yellow, bbox],
actions=[("Remove Green", remove_green),
("Remove Yellow", remove_yellow),
("Remove Bounds", remove_bbox)])
if __name__ == "__main__":
# single_object()
# multi_objects()
# actions()
selections()
import open3d as o3d
import open3d.visualization.rendering as rendering
def main():
render = rendering.OffscreenRenderer(640, 480)
yellow = rendering.Material()
yellow.base_color = [1.0, 0.75, 0.0, 1.0]
yellow.shader = "defaultLit"
green = rendering.Material()
green.base_color = [0.0, 0.5, 0.0, 1.0]
green.shader = "defaultLit"
grey = rendering.Material()
grey.base_color = [0.7, 0.7, 0.7, 1.0]
grey.shader = "defaultLit"
white = rendering.Material()
white.base_color = [1.0, 1.0, 1.0, 1.0]
white.shader = "defaultLit"
cyl = o3d.geometry.TriangleMesh.create_cylinder(.05, 3)
cyl.compute_vertex_normals()
cyl.translate([-2, 0, 1.5])
sphere = o3d.geometry.TriangleMesh.create_sphere(.2)
sphere.compute_vertex_normals()
sphere.translate([-2, 0, 3])
box = o3d.geometry.TriangleMesh.create_box(2, 2, 1)
box.compute_vertex_normals()
box.translate([-1, -1, 0])
solid = o3d.geometry.TriangleMesh.create_icosahedron(0.5)
solid.compute_triangle_normals()
solid.compute_vertex_normals()
solid.translate([0, 0, 1.75])
render.scene.add_geometry("cyl", cyl, green)
render.scene.add_geometry("sphere", sphere, yellow)
render.scene.add_geometry("box", box, grey)
render.scene.add_geometry("solid", solid, white)
render.setup_camera(60.0, [0, 0, 0], [0, 10, 0], [0, 0, 1])
render.scene.scene.set_sun_light([0.707, 0.0, -.707], [1.0, 1.0, 1.0],
75000)
render.scene.scene.enable_sun_light(True)
render.scene.show_axes(True)
img = render.render_to_image()
o3d.io.write_image("test.png", img, 9)
render.setup_camera(60.0, [0, 0, 0], [0, 10, 0], [0, 0, 1])
img = render.render_to_image()
o3d.io.write_image("test2.png", img, 9)
if __name__ == "__main__":
main()