Pointcloud ICP registration

I would like to share how to used dynamo to registration cloudpoint (if you search for patern of point cloud into a big point cloud) this post will help you to detect point cloud patern into big pointcloud

i use unsupervised machen learning Open3d packedge.

http://www.open3d.org/docs/release/tutorial/pipelines/icp_registration.html#Point-to-point-ICP

1- select a patern point cloud


(rail track patern)
2-select target point cloud

3- run Dynamo to detect the this patern into the target point cloud


in this example i used it to detect the rail track and convert it to dynamo node

"""
this code write by Ramiz Mohareb
enramiz@yahoo.com
07-02-2022
Important! This code will only work with Dynamo versions
that are able to run cPython3 and have the following additional 
python packages installed.

Packages required:
numpy

"""

import random
import numpy as np
import clr
import open3d

#libraries used
import numpy as np
import open3d as o3d

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import matplotlib.pyplot as plt


filepath=IN[0]


import numpy as np
import open3d as o3d


filepath=IN[0]
segment_models={}
segments={}
inliers={}
inlier_cloud={}

Outt=[]
Outt2=[]
Outt3=[]
dec_meshL=[]
max_plane_idx=1
point_cloud= np.loadtxt(filepath,skiprows=1)



#Format to open3d usable objects
pcd = o3d.geometry.PointCloud()

pcd.points = o3d.utility.Vector3dVector(point_cloud[:,:3])
#pcd.colors = o3d.utility.Vector3dVector(point_cloud[:,3:6]/255)
#pcd.normals = o3d.utility.Vector3dVector(point_cloud[:,6:9])


#source=pcd.voxel_down_sample(voxel_size=0.01)


OUT =pcd


"""

this code write by Ramiz Mohareb
enramiz@yahoo.com
07-02-2022
Important! This code will only work with Dynamo versions
that are able to run cPython3 and have the following additional 
python packages installed.

Packages required:
numpy

"""

import random
import numpy as np
import clr
import open3d
import copy
#libraries used
import numpy as np
import open3d as o3d

import trimesh

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import matplotlib.pyplot as plt











Outt=[]
# ICP algortihm requires a good initial allignment to converge efficiently.
trans_init = np.asarray([[1, 0, 0, 0],
                         [0, 1, 0, 0],
                        [0, 0, 1, 0], [0, 0, 0, 1]])

source1 = IN[0]
target1 = IN[1]
source2 = copy.deepcopy(source1).translate((-3572567.317, -5363546.02427989, -502.8697))

target = copy.deepcopy(target1).translate((-3572567.317, -5363546.02427989, -502.8697))

#source = copy.deepcopy(source2).translate((30,10 ,10))

source=source2
New_target=target
New_source=source
                                      
criteria = o3d.pipelines.registration.ICPConvergenceCriteria(max_iteration=10000)
# Down-sampling voxel-size. If voxel_size < 0, original scale is used.
voxel_size = -1


reg_p2p = o3d.pipelines.registration.registration_icp(source, New_target,1000, trans_init,o3d.pipelines.registration.TransformationEstimationPointToPoint(),criteria)

#Outt.append(np.asarray(reg_p2p.transformation).tolist())
#draw_registration_result(source, target, reg_p2p.transformation)
New_source = copy.deepcopy(source).transform(reg_p2p.transformation)

dists = target.compute_point_cloud_distance(New_source)
dists = np.asarray(dists)
ind = np.where(dists > 0.1)[0]
New_target = New_target.select_by_index(ind)
    

##source = copy.deepcopy(New_source).translate((30,30 ,30))

OUT =New_source,New_target#,np.asarray(New_target.points).tolist(),np.asarray(New_source.points).tolist()


"""
this code write by Ramiz Mohareb
enramiz@yahoo.com
07-02-2022
Important! This code will only work with Dynamo versions
that are able to run cPython3 and have the following additional 
python packages installed.

Packages required:
numpy

"""

import random
import numpy as np
import clr
import open3d
import copy
#libraries used
import numpy as np
import open3d as o3d

import trimesh

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import matplotlib.pyplot as plt

OUTT=[]
OUTT2=[]
Fitt=[]

# ICP algortihm requires a good initial allignment to converge efficiently.
trans_init = np.asarray([[1, 0, 0, 0],
                         [0, 1, 0, 0],
                        [0, 0, 1, 0], [0, 0, 0, 1]])

source = IN[0]
target = IN[1]

New_source={}
TO={}
New_target={}
New_target[0]=target
New_source[0]=source
                                      
criteria = o3d.pipelines.registration.ICPConvergenceCriteria(max_iteration=100000)
# Down-sampling voxel-size. If voxel_size < 0, original scale is used.
voxel_size = -1

for i in range(10):
    reg_p2p = o3d.pipelines.registration.registration_icp(New_source[i], New_target[i],10, trans_init,o3d.pipelines.registration.TransformationEstimationPointToPoint(),criteria)

#Outt.append(np.asarray(reg_p2p.transformation).tolist())
#draw_registration_result(source, target, reg_p2p.transformation)
    New_source[i+1] = copy.deepcopy(New_source[i]).transform(reg_p2p.transformation)
    
    dists = New_target[i].compute_point_cloud_distance(New_source[i+1])
    dists = np.asarray(dists)
    ind = np.where(dists > 0.1)[0]
    ind2 = np.where(dists < 0.1)[0]
    New_target[i+1] = New_target[i].select_by_index(ind)    
    OUTT.append(New_source[i+1])
    OUTT2.append(New_target[i].select_by_index(ind2))
    
    evaluation = o3d.pipelines.registration.evaluate_registration(
    New_source[i+1], New_target[i+1] , 0.2, trans_init)
    Fitt.append(evaluation)


OUT =OUTT,Fitt,OUTT2#,#New_target,New_source #,np.asarray(New_source.points).tolist(),np.asarray(New_target.points).tolist()


UPDATE

also you can convert the point cloud to revit element mesh



"""

this code write by Ramiz Mohareb
enramiz@yahoo.com
07-02-2022
Important! This code will only work with Dynamo versions
that are able to run cPython3 and have the following additional 
python packages installed.

Packages required:
numpy

"""

import random
import numpy as np
import clr
import open3d

#libraries used
import numpy as np
import open3d as o3d

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import matplotlib.pyplot as plt




import numpy as np
import open3d as o3d

segment_models={}
segments={}
inliers={}
inlier_cloud={}

Outt=[]
Outt2=[]
Outt3=[]
dec_meshL=[]
max_plane_idx=1


downpcd=IN[0]


    
    
distances = downpcd.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radius = 1 * avg_dist
    
    #computing the mehs

bpa_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(downpcd,o3d.utility.DoubleVector([1*radius, radius*2])) 
#dec_mesh1 = bpa_mesh.filter_smooth_simple(number_of_iterations=1)
dec_mesh1 = bpa_mesh.filter_smooth_taubin(number_of_iterations=10)
dec_mesh3=dec_mesh1
dec_mesh3.remove_degenerate_triangles()
dec_mesh3.remove_duplicated_triangles()
dec_mesh3.remove_duplicated_vertices()
dec_mesh3.remove_non_manifold_edges()
   # Outt.append(np.asarray(segments[i].Points).tolist())
Outt2.append(np.asarray(dec_mesh3.triangles).tolist())
Outt3.append(np.asarray(dec_mesh3.vertices).tolist())
 
 
OUT = Outt2,Outt3




Point_Cloud_ICP_Track4.dyn (37.8 KB)

These posts are really great! Have you considered authoring a package on the Dynamo Package manager to allow easier reuse and distribution?

@jacob.small thank you for your comment
think about that. To publish dynamo pakedge service infrastructure project: point cloud, access civil 3d api from dynamo revit, access sofistik analysis API, Sap2000 API and link anaysis with the BrIM model. maybe before Autodesk universty 2022.


Definitely a BIG lift, but it would be really cool to see. I’d vote for it as an AU class… no pressure. :slight_smile:

Awesome !! It will be so useful dynamo packages to any structural engineer specially … Go ahead and good luck always.

4 Likes

Ramiz Mohareb,

I will be conducting a presentation regarding point clouds for civil engineering design at the American Public Works Association, Spring Conference, Emerging Professionals track. Do you mind if I mention the work you shared here in my presentation if I credit you?

Sure you can

@jacob.small @WrightEngineering I will publish Dynamo package for pointcloud node at the end of next weak.

Hi Ramiz,

Great work from you! Really impressive.
Did you publish your Dynamo package already?

Thank you in advance for your answer!

Hi Redrai

not yet, sorry for late