Nodes/ComfyUI-JH-PixelPro/Face Warp (Delaunay per-triangle)
ComfyUI Node

Face Warp (Delaunay per-triangle)

Move a face's geometry with 468-point precision, triangle by triangle

By jetthuangai·Created 5 months ago·Updated 4 months ago· 5
Face Warp (Delaunay per-triangle)
  • image
  • src_landmarks
  • dst_landmarks
  • warped

A global warp moves your whole image. A face warp moves the face's geometry and leaves the frame alone. JHPixelProFaceWarp does the second one using the classic technique: Delaunay triangulation over dense landmarks, then a piecewise-affine warp of each triangle from its source position to a target position. Wire in the pack's JHPixelProFaceLandmarks output as src_landmarks, another landmark set as dst_landmarks, and the node bends the face toward the target shape - without the global distortion you'd get from a single affine transform on the whole image.

The mechanism is worth understanding because it explains both what it's good at and where it hurts. Delaunay triangulation covers the face with a mesh of triangles whose vertices are the 468 landmark points. Each triangle is warped independently with its own affine transform, and the triangles are stitched back. Because the warp is driven by correspondences - every source point maps to a known target point - it's precise where it matters: eyes move to eyes, mouth corners to mouth corners. That's the difference between a "morph" and a smudge.

Inputs and outputs

  • image: the source frame.
  • src_landmarks / dst_landmarks: both LANDMARKS tensors (the pack's typed output from JHPixelProFaceLandmarks). The node uses the first detected face per batch item.

Output is a single warped image, same shape as the input.

The intended uses are geometry correction after a face-aware retouch, prototype morphing / pose transfer without leaving ComfyUI, and local deformations that a single affine can't express - like changing the shape of a jaw or the width of a smile while the eyes stay pinned.

The three things to know before you trust it

  • It's CPU-only. The warp is SciPy Delaunay + OpenCV affine, not a GPU tensor kernel. Fine for a single portrait; don't plan on a batch of 4K frames.
  • Single-face scope. It processes the first face per batch item. Multi-face images need you to pre-index the face you want.
  • Needs SciPy and OpenCV. Both are in the pack's requirements.txt, so a clean install has them - but if either import fails, the node raises a clear error rather than silently degrading.

Install

ComfyUI Manager → search ComfyUI-JH-PixelPro, or:

cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt

Restart ComfyUI; it's under ComfyUI-JH-PixelPro/face. The pack wants ComfyUI ≥ 0.43.x, Python ≥ 3.10, and installs kornia, mediapipe, opencv-python-headless, scipy.

Honestly, this is the node I'd call "cool but specialized." It does one thing - piecewise-affine face warping - and it does it properly, but most people don't need to warp a face to a new landmark shape on a regular basis. When they do, it's almost always in service of something else: fixing geometry the model got wrong, or pre-deforming for a follow-up pass. Keep it in the toolkit next to JHPixelProFaceBeautyBlend, which is the node that composites the warped result back onto the frame cleanly. Together they make the pack's face geometry story complete - measurement, deformation, and seamless re-integration.

CategoryComfyUI-JH-PixelPro/face

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
src_landmarksLANDMARKS
dst_landmarksLANDMARKS

Outputs (1)

NameTypeDescription
warpedIMAGE