isl-org / Open3D

Open3D: A Modern Library for 3D Data Processing
http://www.open3d.org
Other
11.17k stars 2.27k forks source link

Testing the tutorial "Pipelines (Tensor)", incompatible function arguments when try local ICP #5140

Open stepelle90 opened 2 years ago

stepelle90 commented 2 years ago

Checklist

Describe the issue

I have been trying the tutorial "Pipelines (Tensor)" -> ICP Registration on two pint cloud of three million points. The global registration runs perfect.

But as I run the second part of the code, the local registration (vanilla, but also the multi scale gave me the same issue) the registration function gives me a strange error.

The funtion flag me that the input aguments are not right. But actually they are right.

I tried to change everyting and the results doesn't change. Is it a bug or did I miss somethigs?

Thanks a lot!

Steps to reproduce the bug

import open3d as o3d
import copy
import numpy as np
import copy
import time

'''
global registration code is not included, it is the same of the tutorial. 
in the error section, the output of the previus part is reported.
'''

def draw_registration_result(source, target, transformation):
    source_temp = copy.deepcopy(source)
    target_temp = copy.deepcopy(target)
    source_temp.paint_uniform_color([1, 0.706, 0])
    target_temp.paint_uniform_color([0, 0.651, 0.929])
    source_temp.transform(transformation)
    o3d.visualization.draw([source_temp, target_temp])

treg = o3d.t.pipelines.registration

# Search distance for Nearest Neighbour Search.
max_correspondence_distance = 0.5

# Initial alignment or source to target transform.
#init_source_to_target = result_ransac.transformation   --> from global (not in the code)
init_source_to_target = o3d.core.Tensor.eye(4, o3d.core.Dtype.Float32)  --> just to test the function 

# Select the `Estimation Method`, and `Robust Kernel` (for outlier-rejection).
estimation_method = treg.TransformationEstimationPointToPoint()

# Convergence-Criteria for Vanilla ICP
criteria = treg.ICPConvergenceCriteria(relative_fitness=0.000001,
                                        relative_rmse=0.000001,
                                        max_iteration=50)
# Down-sampling voxel-size.
voxel_size = 0.2

# Save iteration wise `fitness`, `inlier_rmse`, etc. to analyse and tune result.
save_loss_log = True
s = time.time()

# CODE BREAKS HERE
registration_icp = treg.icp(source_down, target_down, max_correspondence_distance, init_source_to_target, estimation_method, criteria,voxel_size, save_loss_log)

icp_time = time.time() - s
print("Time taken by ICP: ", icp_time)
print("Inlier Fitness: ", registration_icp.fitness)
print("Inlier RMSE: ", registration_icp.inlier_rmse)

draw_registration_result(source, target, registration_icp.transformation)

Error message

:: Load two point clouds and disturb initial pose. :: Prepare point cloud :: Downsample with a voxel size 1.000. :: Estimate normal with search radius 2.000. :: Compute FPFH feature with search radius 5.000. :: Downsample with a voxel size 1.000. :: Estimate normal with search radius 2.000. :: Compute FPFH feature with search radius 5.000. :: RANSAC registration on downsampled point clouds. Since the downsampling voxel size is 1.000, we use a liberal distance threshold 1.500. Global registration took 0.787 sec.

RegistrationResult with fitness=6.322398e-01, inlier_rmse=3.790970e-01, and correspondence_set size of 10523 Access transformation to get result. Traceback (most recent call last):

TypeError: icp(): incompatible function arguments. The following argument types are supported:

  1. (source: open3d::t::geometry::PointCloud, target: open3d::t::geometry::PointCloud, max_correspondence_distance: float, init_source_to_target: open3d.cpu.pybind.core.Tensor = [[1.0 0.0 0.0 0.0], [0.0 1.0 0.0 0.0], [0.0 0.0 1.0 0.0], [0.0 0.0 0.0 1.0]] Tensor[shape={4, 4}, stride={4, 1}, Float64, CPU:0, 0x13ae7cf62f0], estimation_method: open3d.cpu.pybind.t.pipelines.registration.TransformationEstimation = TransformationEstimationPointToPoint, criteria: open3d.cpu.pybind.t.pipelines.registration.ICPConvergenceCriteria = ICPConvergenceCriteria[relativefitness=1.000000e-06, relative_rmse=1.000000e-06, maxiteration=30]., voxel_size: float = -1.0, save_loss_log: bool = False) -> open3d.cpu.pybind.t.pipelines.registration.RegistrationResult

Invoked with: PointCloud with 16644 points., PointCloud with 17280 points., 0.5, [[1.0 0.0 0.0 0.0], [0.0 1.0 0.0 0.0], [0.0 0.0 1.0 0.0], [0.0 0.0 0.0 1.0]] Tensor[shape={4, 4}, stride={4, 1}, Float32, CPU:0, 0x13ae4e8e350], TransformationEstimationPointToPoint, ICPConvergenceCriteria[relativefitness=1.000000e-06, relative_rmse=1.000000e-06, maxiteration=50]., 0.2, True

Expected behavior

The expected inputs of treg.icp() are the same of the actually inputs. I don't see any errors but the code breaks.

Open3D, Python and System information

- Operating system: Windows 10 64-bit
- Python version: Python 3.9.12 (main, Apr  4 2022, 05:22:27) [MSC v.1916 64 bit (AMD64)]
- Open3D version: output from python: 0.15.1
- Is this a remote workstation?: no
- How did you install Open3D?: pip

Additional information

No response

loke-bager commented 6 months ago

I am running into something similar. If i do not give the icp algorithm an initial transformation matrix i get it a little further.

It still does not run properly and gives the error: [Open3D Error] (int64 cdecl open3d::core::SizeVector::GetLength(void) const) D:\a\Open3D\Open3D\cpp\open3d\core\SizeVector.cpp:126: Cannot get length of a 0-dimensional shape.

Is there any solution to this?

flimdejong commented 1 month ago

Hi im currently trying to figure out how to use global registration (ransac) on tensors/ GPU. How did you do that? The global registration tutorial was about legacy pointclouds, not the tensors.