Nodes/comfyui_cv/CV Project Points (Sequence)
ComfyUI Node

CV Project Points (Sequence)

Projects one set of 3D object points through a whole STACK of poses - the Bx3x1 rvecs/tvecs 'CV Rapid Track (Sequence)' emits - so a tracked clip drives the drawing nodes without one 'cv2 projectPoints' per frame. Wire a depth map from 'CV Rasterize Mesh' into scene_depth and each point also gets a VISIBLE flag: a point on the far side of the model is behind the surface the camera sees, so an annotation anchored to it should be hidden rather than drawn floating over the object. That is the hidden-line removal an overlay needs to look attached instead of pasted on.

By bmad4ever·Created 3 months ago·Updated 2 days ago· 0
CV Project Points (Sequence)
  • points_3d
  • rvecs
  • tvecs
  • K
  • dist_coeffs
  • scene_depth
  • points_2d
  • visible
  • depths
hidden_pointskeep coordinates
depth_tolerance0.020
Categoryimage/CV/low-level

Inputs (8)

NameTypeDefaultDescription
points_3dNPARRAYNx3 points in the mesh's object space - annotation anchors, measurement ends, a bounding box's corners. Pick them off the model with the 'CV Pick Point On Mesh' blueprint rather than typing coordinates.
rvecsNPARRAYBx3x1 rotations (a single 3x1 works too).
tvecsNPARRAYBx3x1 translations, same length as rvecs.
KNPARRAY3x3 camera matrix of the frames.
dist_coeffsoptNPARRAYOptional lens distortion (k1, k2, p1, p2[, k3...]). Leave unwired for a pinhole camera. Note that 'CV Rasterize Mesh' is pinhole-only, so a distorted projection will NOT line up with its depth map - undistort the frames instead of mixing the two.
scene_depthoptNPARRAYOptional BxHxW (or HxW) metric depth from 'CV Rasterize Mesh'. When wired, each projected point is compared with the depth actually rendered at its pixel and reported in 'visible'.
hidden_pointsoptCOMBOkeep coordinatesWhat points_2d holds where 'visible' is 0. 'keep coordinates' returns where the point WOULD be, which is what you want for measuring or for your own gating. 'blank out (NaN)' replaces them with NaN - the drawing nodes skip non-finite points, so an overlay gets hidden-line removal for free and the rows stay index-aligned with their labels (filtering them out instead renumbers everything). Only ever differs when scene_depth is wired.
depth_toleranceoptFLOAT0.0200–1000How far BEHIND the rendered surface a point may sit and still count as visible, in scene units. An anchor picked ON the surface lands within a rasterization pixel of it, so a small tolerance (~1% of the object) absorbs that without letting far-side points through.

Outputs (3)

NameTypeDescription
points_2dNPARRAYBxNx2 float32 pixel positions, one row per pose. Slice a frame out with 'CV Index Batch' and feed 'CV Draw Points' / 'Draw Labels' / 'Draw Connections'.
visibleNPARRAYBxN uint8: 1 where the point faces the camera, by comparing its own Z with scene_depth at its pixel. All ones when scene_depth is not wired (nothing to test against) and 0 for points that fall outside the frame. Gate the drawing on it with 'CV Filter Points By Mask'.
depthsNPARRAYBxN float32 camera-space Z of each point - how far it is from the camera, in scene units. Useful to scale a label with distance, or to sort overlapping callouts back to front.