open3D源码分析第十三篇

2021SC@SDUSC

open3D 网格和图片的应用

本篇对前面分析的Mesh和Image相关的知识进行应用。我们小组进行了讨论,结合open3D在python方面对网格和图片的实现,我们用python代码进行了一些相关算法的实现。

网格变形

算法原理

Open3D中的deform_as_rigid_as_possible函数,使用少量的约束使得三角网格变形,实现了Sorkine and M. Alexa, As-rigid-as-possible surface modeling, Symposium on Geometry processing, 2007.中的尽可能严格的算法。

以优化下面的能量函数: ∑ i = 1 ∑ j ∈ N ( i )   w i j ∣ ∣ ( p i ′ − p j ′ ) − R i ( p i − p j ) ∣ ∣ 2 \sum_{i=1}\sum_{j\in N(i)}\ w_{ij}||(p_i'-p_j')-R_i(p_i-p_j)||^2 i=1jN(i) wij(pipj)Ri(pipj)2
式中: R i R_i Ri表示要优化的旋转矩阵, p i p_i pi p j p_j pj分别表示优化前后的顶点位置, N ( i ) N(i) N(i) 表示顶点 i i i的邻域集合。 w i j w_{ij} wij权重表示余切权重。

代码实现

import open3d as o3d
import numpy as np


mesh = o3d.io.read_triangle_mesh("data//Armadillo.ply")

vertices = np.asarray(mesh.vertices)
static_ids = [idx for idx in np.where(vertices[:, 1] < -30)[0]]
static_pos = []
for id in static_ids:
    static_pos.append(vertices[id])
handle_ids = [2490]
handle_pos = [vertices[2490] + np.array((-40, -40, -40))]
constraint_ids = o3d.utility.IntVector(static_ids + handle_ids)
constraint_pos = o3d.utility.Vector3dVector(static_pos + handle_pos)

with o3d.utility.VerbosityContextManager(
        o3d.utility.VerbosityLevel.Debug) as cm:
    mesh_prime = mesh.deform_as_rigid_as_possible(constraint_ids,  # 三角网格的顶点
                                                  constraint_pos,  # 顶点优化后的位置
                                                  max_iter=50)     # 迭代次数
print('Original Mesh')
R = mesh.get_rotation_matrix_from_xyz((0, np.pi, 0))
o3d.visualization.draw_geometries([mesh.rotate(R, center=mesh.get_center())])
print('Deformed Mesh')
mesh_prime.compute_vertex_normals()
o3d.visualization.draw_geometries(
                                  [mesh_prime.rotate(R, center=mesh_prime.get_center())])

去除mesh中的噪点

算法原理

各种重建算法的结果(比如RGBD Integration 并不是只有一个三角网格而是有多个网格。一些较小的部分(相比如主物体较小)是由于噪声引起的,我们会想要移除它。Open3d实现了一个连通分量算法cluster_connected_triangles,将每个三角形分配给一个连接的三角集群,从集群中返回每一个三角形的索引triangle_cluters,和每一个集群中三角形的数量cluter_n_triangles还有集群的表面积cluster_area

代码实现

下面的代码展示cluster_connected_triangles的应用和如何使用它来删除假三角形。

import open3d as o3d
import numpy as np
import copy

mesh = o3d.io.read_triangle_mesh("bunny.ply")
vert = np.asarray(mesh.vertices)
min_vert, max_vert = vert.min(axis=0), vert.max(axis=0)
for _ in range(30):
    cube = o3d.geometry.TriangleMesh.create_box() # 生成小立方体作为噪声添加到mesh
    cube.scale(0.005, center=cube.get_center()) # 立方体参数
    cube.translate(
        (
            np.random.uniform(min_vert[0], max_vert[0]),
            np.random.uniform(min_vert[1], max_vert[1]),
            np.random.uniform(min_vert[2], max_vert[2]),
        ),
        relative=False,
    )
    mesh += cube
mesh.compute_vertex_normals()
print("Show input mesh")
o3d.visualization.draw_geometries([mesh])

print("Cluster connected triangles")
with o3d.utility.VerbosityContextManager(
        o3d.utility.VerbosityLevel.Debug) as cm:
    triangle_clusters, cluster_n_triangles, cluster_area = (
        mesh.cluster_connected_triangles())  #将每个三角形分配给一组连通的三角形
triangle_clusters = np.asarray(triangle_clusters) #返回每个三角形集群的索引
cluster_n_triangles = np.asarray(cluster_n_triangles)
cluster_area = np.asarray(cluster_area)

print("Show mesh with small clusters removed")
mesh_0 = copy.deepcopy(mesh)
triangles_to_remove = cluster_n_triangles[triangle_clusters] < 100
mesh_0.remove_triangles_by_mask(triangles_to_remove)
o3d.visualization.draw_geometries([mesh_0])

print("Show largest cluster")
mesh_1 = copy.deepcopy(mesh)
largest_cluster_idx = cluster_n_triangles.argmax()
triangles_to_remove = triangle_clusters != largest_cluster_idx
mesh_1.remove_triangles_by_mask(triangles_to_remove)
o3d.visualization.draw_geometries([mesh_1])

读取、显示、保存图片

主要函数

1、Open3D中 i m g = o 3 d . i o . r e a d i m a g e ( " y 7. p n g " ) img = o3d.io.read_image("y7.png") img=o3d.io.readimage("y7.png")实现图片图像数据的读取,支持的图片格式为jpg、png;
2、图像的大小可以很容易地使用 p r i n t ( i m g ) print(img) print(img)来获取;
3、 o 3 d . i o . w r i t e i m a g e ( " 天 使 . j p g " , i m g ) o3d.io.write_image("天使.jpg", img) o3d.io.writeimage("使.jpg",img)实现图片的保存、支持的图片格式为jpg、png;
4、 o 3 d . v i s u a l i z a t i o n . d r a w g e o m e t r i e s ( ) o3d.visualization.draw_geometries() o3d.visualization.drawgeometries()实现图片的显示。

代码实现

import open3d as o3d

print("Testing IO for images")
img = o3d.io.read_image("y7.png")  # 读取图片(支持jpg和png格式)
print(img)  # 图片大小
o3d.io.write_image("天使.jpg", img)  # 保存图片
o3d.visualization.draw_geometries([img], window_name="Open3D显示图像",
                                  width=1024, height=768,
                                  left=50, top=50,
                                  mesh_show_back_face=False)  # 显示图片

小结

本篇对前面分析的Mesh和Image相关的知识进行应用。我们小组进行了讨论,结合open3D在python方面对网格和图片的实现,我们用python代码进行了一些相关算法的实现,这使得我们对open3D在Mesh和RGBD图像等方面的应用的理解更为深刻了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值