(array, columns="XYZI", estimate_normals=True, colors=None, radius=10, max_nn=30)
| 407 | # convert numpy array to open3d point cloud |
| 408 | # supports 2D and 3D points, intensity and RGB colors or pcd objects (pcd.points and pcd.colors) |
| 409 | def pcd_from_np(array, columns="XYZI", estimate_normals=True, colors=None, radius=10, max_nn=30): |
| 410 | pcd = o3d.geometry.PointCloud() |
| 411 | |
| 412 | # Convert the pointcloud and colors to numpy arrays if they are not already |
| 413 | # TODO: merged from another version -> check if it's still valid |
| 414 | if not isinstance(array, np.ndarray): |
| 415 | array = np.asarray(array) |
| 416 | if colors is not None and not isinstance(colors, np.ndarray): |
| 417 | colors = np.asarray(colors) |
| 418 | |
| 419 | columns = columns.upper() |
| 420 | zeros = np.zeros((array.shape[0], 1)) |
| 421 | |
| 422 | # 3D points |
| 423 | if "XYZ" in columns: |
| 424 | points = array[:, 0:3] |
| 425 | pcd.points = o3d.utility.Vector3dVector(points) |
| 426 | color_i = 3 |
| 427 | |
| 428 | # 2D points |
| 429 | else: |
| 430 | color_i = 2 |
| 431 | if "XY" in columns: |
| 432 | pcd.points = o3d.utility.Vector3dVector(np.hstack((array[:, 0:2], zeros))) |
| 433 | elif "XZ" in columns: |
| 434 | pcd.points = o3d.utility.Vector3dVector(np.hstack((array[:, 0:1], zeros, array[:, 1:2]))) |
| 435 | elif "YZ" in columns: |
| 436 | pcd.points = o3d.utility.Vector3dVector(np.hstack((zeros, array[:, 0:2]))) |
| 437 | else: |
| 438 | raise ValueError("Unsupported point cloud type: " + type(array)) |
| 439 | |
| 440 | if estimate_normals: |
| 441 | pcd = estimate_point_normals(pcd, radius=radius, max_nn=max_nn) |
| 442 | |
| 443 | # colors |
| 444 | if "I" in columns: # ext == "XYZI" -> array.shape[1] == 4: |
| 445 | intensities = array[:, color_i] / 255 # normalize intensity values |
| 446 | |
| 447 | # convert intensity to RGBA color |
| 448 | pcd.colors = o3d.utility.Vector3dVector(np.column_stack([intensities, intensities, intensities])) |
| 449 | |
| 450 | elif "RGB" in columns: |
| 451 | pcd.colors = o3d.utility.Vector3dVector(array[:, color_i:color_i+3] / 255) |
| 452 | |
| 453 | elif colors is not None: |
| 454 | pcd.colors = o3d.utility.Vector3dVector(colors) |
| 455 | |
| 456 | return pcd |
| 457 | |
| 458 | |
| 459 | #------------------------------------------------------------------------------------------------ |
no test coverage detected