Nodes/comfyui_cv/CV ICP Register (Point Clouds)
ComfyUI Node

CV ICP Register (Point Clouds)

Refines the alignment of two 3D point clouds with iterative closest point (cv2.ppf_match_3d.ICP) and returns the 4x4 pose that maps 'model' onto 'scene' - feed it to 'CV Transform Points 3D'. ICP only POLISHES: it needs a good initial alignment (register the clouds with cv2.estimateAffine3D first) and it converges to a wrong answer from a bad start. IMPORTANT: the 'residual' output is an internal number, not a quality measure - on the shipped stereo example it reported 5e-5 for a pose that made the alignment worse. Always verify with 'CV Point Cloud Nearest Distance' (median distance must go DOWN) and branch on it with a 'Basic data handling: IfElse'. Downsample first: ICP cost grows with the cloud size.

By bmad4ever·Created 3 months ago·Updated 2 days ago· 0
CV ICP Register (Point Clouds)
  • model
  • scene
  • pose
  • residual
  • found
iterations100
tolerance0.050
rejection_scale2.5
num_levels6
Categoryimage/CV/contrib

Inputs (6)

NameTypeDefaultDescription
modelNPARRAYNx3 (or Nx6 with normals) cloud to be moved.
sceneNPARRAYMx3 (or Mx6) reference cloud to align onto.
iterationsINT1001–2000Max ICP iterations per pyramid level.
toleranceFLOAT0.0500–1Relative improvement below which iteration stops.
rejection_scaleFLOAT2.50–10Outlier rejection: correspondences farther than this many standard deviations are dropped each iteration. Lower = stricter.
num_levelsINT61–10Coarse-to-fine pyramid levels; more levels tolerate a rougher initial alignment - up to the point where the coarsest level has nothing left to fit, and then ICP DIVERGES rather than degrading. A PARTIAL scene (a model matched against the one face a depth camera can see) hits that first: measured on a 360-point model against a 176-point view, 4 levels converge and 5 diverge; on a 1363-point model against a 1335-point view, 6 converge and 8 diverge. Lower it when 'found' comes back false with a 1e10 residual.

Outputs (3)

NameTypeDescription
poseNPARRAY4x4 rigid transform mapping model -> scene (identity when found=false).
residualFLOATICP's own residual. NOT a quality measure - see the node description; use 'CV Point Cloud Nearest Distance' to judge the alignment. The ONE thing it does say: 9999999999 is cv2's divergence sentinel, and this node turns that into found=false.
foundBOOLEANFalse when ICP could not run (empty cloud, cv2 error, non-finite pose) or DIVERGED. cv2 signals divergence with a 1e10 residual while still returning 0 from registerModelToScene, so the return code alone would report success on a pose hundreds of units out - too many pyramid levels for the point count is the usual cause. Gate the transform on this with a 'Basic data handling: IfElse'.