对于三维点云数据(如pcd),如何画其表面的网格图,比如1 * 1 m的表面网格图?
话不多说,直接上python脚本,已验证。
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def grid_plot(file):
target = o3d.io.read_point_cloud(file)
points = np.asarray(target.points)
idex = np.lexsort([points[:, 2], points[:, 1], points[:, 0]])
# 按照X Y Z进行从小到大排序
points = points[idex, :]
# 计算x y z 三个维度的最值
x_min, y_min, z_min = np.amin(points, axis=0)
x_max, y_max, z_max = np.amax(points, axis=0)
print(x_min, x_max, y_min, y_max, z_min, z_max)
print(points.shape)
step = 0.1
# 计算行列
x_num =(int) (round((x_max - x_min) / step))+1
y_num =(int) (round((y_max - y_min) / step))+1
print('x-y-num:', x_num, y_num)
# 按照行列矩阵排列
X = points[:, 0].reshape(x_num, y_num)
Y = points[:, 1].reshape(x_num, y_num)
Z = points[:, 2].reshape(x_num, y_num)
print('X-Y-shape:', X.shape, Y.shape)
fig = plt.figure()
ax = Axes3D(fig)
# 行,列步长 对应网格大小 rainbow/coolwarm
ax.plot_surface(X, Y, Z, rstride=10, cstride=10, cmap=plt.get_cmap('rainbow'))
# Z轴范围
ax.set_zlim(0, 8)
plt.title("3D")
# 去除坐标轴和刻度
plt.axis('off')
plt.show()
if __name__ == "__main__":
file = '/*/test.pcd'
grid_plot(file)