File "./pointcloud_to_scene.py", line 326, in convert_pointcloud_to_mesh mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(o3d_pointcloud) RuntimeError: [Open3D ERROR] [CreateFromPointCloudPoisson] pcd has no normals
时间: 2023-09-25 20:13:16 浏览: 44
这个错误是由于使用Open3D库的create_from_point_cloud_poisson函数时,点云没有法向量导致的。这个函数需要使用法向量来估算表面重建的结果。你需要先计算点云的法向量,然后将其传递给create_from_point_cloud_poisson函数。你可以使用Open3D库的estimate_normals函数来计算点云的法向量,然后将结果传递给create_from_point_cloud_poisson函数。例如:
```
import open3d as o3d
# 读取点云数据
pcd = o3d.io.read_point_cloud("pointcloud.pcd")
# 计算法向量
pcd.estimate_normals()
# 生成三角网格
mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd)
# 保存结果
o3d.io.write_triangle_mesh("mesh.ply", mesh)
```
相关问题
o3d.io.read_point_cloud源代码
o3d.io.read_point_cloud函数是Open3D库中用于读取点云数据的函数。其源代码如下:
```python
def read_point_cloud(filename: str,
format: Optional[str] = None,
remove_nan_points: bool = True,
remove_infinite_points: bool = True,
print_progress: bool = False) -> 'open3d.geometry.PointCloud':
"""Function to read point cloud from file.
Args:
filename (str): path of the point cloud file.
format (str, optional): format of the file. If not provided, the
format will be inferred from the filename extension.
remove_nan_points (bool, optional): whether to remove NaN points.
remove_infinite_points (bool, optional): whether to remove infinite
points.
print_progress (bool, optional): whether to print progress information.
Returns:
open3d.geometry.PointCloud: an instance of the `open3d.geometry.PointCloud`
containing the point cloud data.
"""
if format is None:
format = utility._get_file_extension_lower(filename)
format = format.lower()
# Check if format is supported.
if format not in _READABLE_FORMATS:
raise ValueError(f"Unsupported file format '{format}'")
# Call the appropriate read function based on format.
if format == 'xyz':
return read_xyz(filename, remove_nan_points, remove_infinite_points,
print_progress)
elif format == 'xyzn':
return read_xyz_normal(filename, remove_nan_points,
remove_infinite_points, print_progress)
elif format == 'pts':
return read_pts(filename, remove_nan_points, remove_infinite_points,
print_progress)
elif format == 'ply':
return read_ply(filename, remove_nan_points, remove_infinite_points,
print_progress)
elif format == 'pcd':
return read_pcd(filename, remove_nan_points, remove_infinite_points,
print_progress)
elif format == 'fbx':
return read_fbx(filename, remove_nan_points, remove_infinite_points,
print_progress)
elif format == 'obj':
return read_triangle_mesh(filename).sample_points_poisson_disk(
number_of_points=0)
elif format == 'stl':
return read_triangle_mesh(filename).sample_points_poisson_disk(
number_of_points=0)
else:
raise ValueError(f"Unsupported file format '{format}'")
```
该函数首先判断文件格式是否支持,然后根据文件格式调用对应的读取函数,例如对于PLY格式的点云文件,会调用`read_ply`函数进行读取。最终返回一个`open3d.geometry.PointCloud`对象。
[ERROR] [1686123555.624064]: bad callback: <function point_cloud_callback at 0x7f1b0006db80> Traceback (most recent call last): File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 750, in _invoke_callback cb(msg) File "./pointcloud_to_scene.py", line 118, in point_cloud_callback bpa_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd, alpha) TypeError: create_from_point_cloud_alpha_shape(): incompatible function arguments. The following argument types are supported: 1. (pcd: open3d.open3d_pybind.geometry.PointCloud, alpha: float) -> open3d.open3d_pybind.geometry.TriangleMesh 2. (pcd: open3d.open3d_pybind.geometry.PointCloud, alpha: float, tetra_mesh: open3d::geometry::TetraMesh, pt_map: List[int]) -> open3d.open3d_pybind.geometry.TriangleMesh Invoked with: geometry::PointCloud with 70 points., array([ 1.08353329, -0.03247907, 0.40000001])
根据错误信息,可以看到在调用`create_from_point_cloud_alpha_shape`方法时,传递的参数类型不正确。该方法需要接收两个参数:一个`PointCloud`类型的点云数据和一个`float`类型的alpha形状参数,但是你传递了一个`numpy.ndarray`类型的alpha形状参数,导致出现了类型不匹配的错误。
要解决这个问题,你需要将alpha形状参数的数据类型转换为`float`类型。可以按照以下方式修改代码:
```python
import numpy as np
import open3d as o3d
# 定义alpha形状参数
alpha = 0.1
# 读取点云文件
pcd = o3d.io.read_point_cloud("point_cloud.ply")
# 使用alpha形状参数从点云数据创建三角网格模型
bpa_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd, alpha)
# 显示三角网格模型
o3d.visualization.draw_geometries([bpa_mesh])
```
这样就可以正确地使用alpha形状参数从点云数据创建三角网格模型了。