Rotate 2d KPS
Turning a computed angle into an actual keypoint correction
- kps_data
- kps_data
Once AngleFromFace or AngleFromKps has told you how many degrees a face is off-axis, this node is what actually applies that correction to the keypoint data itself. It's worth being precise about what it rotates: this operates on kps_data - the five abstract landmark points - not on pixels. If you're also straightening the underlying photo (the typical auto_rotate.json-style workflow this pack ships an example for), you rotate the image separately and rotate the KPS here in parallel, then generate, then bring them back into alignment afterward.
The inputs and outputs that matter
kps_data(KPS_DATA) - required, fromKpsDraw,Kps3dFromImage, or any other node that outputs keypoint data.angle(default 0, range −360 to 360, step 0.1) - the rotation to apply. Usually wired straight fromAngleFromFaceorAngleFromKps's output, but nothing stops you from hardcoding a value if you're doing something deliberate, like the "randomize the pose within a small range" trick.counter_clockwise(defaulttrue) - which direction a positive angle rotates. Get this backwards and your "correction" doubles the tilt instead of fixing it, so if a rotation makes things visibly worse, flip this first before assuming your angle value is wrong.
Output: kps_data, rotated and - per the README - expanded to accommodate the new bounding shape, same as rotating a rectangular image expands its canvas. That expansion is why ComposeRotated exists later in the pipeline, to strip the extra padding back off once you're done.
Where this sits in a real workflow
The pattern this pack's example workflows use: detect the angle (AngleFromFace), rotate the pose image to straighten the face, rotate the KPS the same amount with this node so they stay in sync, run generation against the now-upright face, then rotate the result back to the original orientation and use ComposeRotated to trim the rotation padding off. Skipping the KPS rotation while still rotating the image (or vice versa) is the single easiest way to break this chain - the control image and the pose image need to describe the same orientation, or IdentityNet is conditioning on geometry that doesn't match what it's actually seeing.
Install
ComfyUI Manager: search comfyui-instantId-faceswap. Manual: git clone https://github.com/nosiu/comfyui-instantId-faceswap into custom_nodes/, pip install -r requirements.txt. No model dependency for this node specifically - it's geometry, not detection, so it runs fine with or without insightface installed.
Common issues & troubleshooting
Rotation makes the face angle worse, not better. Check counter_clockwise first - it's the most common source of a rotation going the wrong way, and it's an easy setting to overlook since the default might not match the direction convention you expect.
Keypoints end up outside the visible canvas after rotating. Expected, to a degree - rotation genuinely expands the bounding area, which is exactly what the "and expands it" part of this node's behavior means. If it's excessive, double-check you're not accidentally applying the angle twice somewhere in the graph (once via this node, once via an image-rotate step using the same angle value in the wrong direction).
Not sure whether you even need this node. If your reference face is already reasonably upright, skip the whole angle-detect-and-rotate chain entirely - it exists for tilted references, not as a mandatory step in every workflow.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| kps_data | KPS_DATA | — | |
| angle | FLOAT | 0.0-360–360 | — |
| counter_clockwise | BOOLEAN | true | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| kps_data | KPS_DATA | — |