BD Face Strip Compose
Unwrap a head into a flat strip for a UV wrap
- images
- landmarks_batch
- rear_mask
- strip_image
- coverage_mask
- inpaint_mask
- status
When you need a head-wrap texture that's geometrically correct - a true cylindrical unwrap where the side of the head maps to the side of the strip - BD Face Strip Compose is the node. It stitches your 4 head-view photos (front, left, right, rear) into a single horizontal strip via a landmark-anchored cylindrical unwrap: each detected view gets TPS-warped (thin-plate spline) so its 478 MediaPipe landmarks land in strip space, a cosine-bell confidence keeps each side dominant in its own slice, and the rear photo gets split and slotted onto the strip edges.
This is the "I need it to actually unwrap correctly" option, versus BD Face Mosaic Compose, which is the faster "good enough for Qwen to finish" stitch. If your result just needs a cleanup pass from Qwen, use the mosaic; if you need a real longitude/latitude unwrap, this is the one.
What comes out
Three outputs and a diagnostic:
- strip_image - the stitched composite (default 4096×1024).
- coverage_mask - where the strip has any data at all.
- inpaint_mask - where Qwen should paint: low-coverage areas plus the seams between the rear slots and the adjacent side views. This is the key output for the Qwen-fill subgraph that fixes what the photos couldn't cover.
- status - per-view diagnostic, so you can see which view landed where.
The inputs are mostly slot assignment and geometry. front_index / left_index / right_index / rear_index (all -1 = auto) let you force which photo goes to which slot when MediaPipe's yaw classifier misfires. strip_width / strip_height set the canvas. Rear handling: rear_split_x (where to split the rear photo), rear_extent (fraction of strip per half), rear_confidence, rear_blend_band, rear_flip_lr, rear_seam_width (the inpaint-flagged band on each side of the rear slots - set 0 to disable), and rear_mask (a head silhouette from e.g. BD_SAM3MultiPrompt that gets perspective-warped to fill the slot). bell_sigma controls how wide each view's confidence bell is (0.22 keeps each side dominant in its own slice), and canonical_mode defaults to cylindrical - the atan2(x,z)/latitude projection that makes the strip a real unwrap.
Installing
ComfyUI Manager → search "BrainDead" → install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead
pip install -r requirements.txt
Restart. Needs the mediapipe model bundle (auto-downloaded by BD Face Landmarks) and scipy for the TPS warp.
Where people get burned
The rear seam is where this node lives or dies - if you don't provide a rear_mask, the rear halves get a plain cv2.resize and the seam shows; feed it the head silhouette and the warp fills the slot properly. And don't skip the inpaint_mask: the strip will have low-coverage gaps, and that mask is the whole mechanism for getting Qwen to fix them. Force the slot indices if the classifier misassigns - that's what they're there for.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | Source photo batch — same order/count as the LANDMARKS_BATCH (typically 4 images: front, left, right, rear). | |
| landmarks_batch | BD_LANDMARKS_BATCH | From BD_FaceLandmarks. By default, view_hint per view picks which strip slot each image goes to. Override with the per-slot index inputs below when MediaPipe's yaw classifier misfires. | |
| front_index | INT | -1-1–63 | Image index for the FRONT slot. -1 = auto (use the first view classified as 'front'). Set to e.g. 0 to force image 0 into the front slot even if MediaPipe classified it differently. |
| left_index | INT | -1-1–63 | Image index for the LEFT slot (subject's left side, lands at strip-right). -1 = auto. |
| right_index | INT | -1-1–63 | Image index for the RIGHT slot (subject's right side, lands at strip-left). -1 = auto. |
| rear_index | INT | -1-1–63 | Image index for the REAR slot. -1 = auto (first undetected view, or first view classified as 'rear'). |
| strip_width | INT | 4096512–16384 | Output strip width (longitude direction). |
| strip_height | INT | 1024256–4096 | Output strip height (latitude direction). |
| rear_split_x | FLOAT | 0.500–1 | Column in the rear image where to split (0=left edge, 1=right edge). Right of the split → leftmost strip slot; left of the split → rightmost strip slot. |
| rear_extentopt | FLOAT | 0.180–0.35 | Fraction of strip width occupied by each rear half. 0.18 → each rear half takes ~18% of the strip (combined rear = ~36%, reaching the canonical ear/temple region where face and rear naturally meet anatomically). |
| rear_confidenceopt | FLOAT | 0.500–1 | Fixed confidence value applied to the rear slots. 0.5 default keeps rear visible while letting the side-view blend band still register. 0 → rear is pure fill that Qwen paints over. |
| rear_blend_bandopt | FLOAT | 0.080–0.2 | Width of the smooth blend band at the rear-slot boundary (fraction of strip width). Both the side-view bell and the rear-mask ramp linearly across this band so they cross at 50/50. Wider → longer crossfade region (better when rear/face colors differ a lot, but the underlying mix is still imperfect — that's what Qwen finalize fixes). 0 → hard cutoff. |
| rear_flip_lropt | BOOLEAN | false | Swap which half of the rear image goes to which strip edge. Default assumes a standard rear photo (photographer behind subject, same facing). Toggle if your rear photo is mirrored or shot from the front (e.g. with the subject turned around). |
| rear_maskopt | MASK | Head-silhouette MASK for the rear image — typically from BD_SAM3MultiPrompt('head') or any head/person segmentation. When provided, each rear half gets perspective-warped so its head silhouette fills the strip slot from edge to edge (matches the cylindrical warp geometry of the side views). Without it, the rear is plain cv2.resize-stretched (looks pasted on). | |
| rear_seam_widthopt | FLOAT | 0.040–0.2 | Width of the inpaint-flagged seam band on each side of the rear slots, as a fraction of strip width. 0 disables. |
| bell_sigmaopt | FLOAT | 0.220.05–0.5 | Half-width of the per-view cosine confidence bell (fraction of strip width). 0.22 keeps each side view dominant in its own slice without extrapolating across the centerline; smaller = sharper handoff (also reduces 'ghost face' at the ears, where side-TPS can extrapolate occluded back-of-head landmarks). Larger = wider but more cross-contamination between views. |
| canonical_modeopt | COMBO | cylindrical | How to project the canonical face landmarks into strip space. cylindrical = atan2(x,z) longitude, y latitude. (equirectangular / JSON layout: future.) |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| strip_image | IMAGE | — |
| coverage_mask | MASK | — |
| inpaint_mask | MASK | — |
| status | STRING | — |