CivArchive
    PortraitDatasetTools - v1.0
    NSFW
    Preview 143883513

    This workflow is specifically designed to assist with preparing portrait datasets for stylistic Lora training. Prepare an image dataset in one or more directories and then point this workflow at them. It will automatically upscale, colorise, restore etc. the images and extract a normally rotated square 1024x1024 face image from each source image into an output directory you specify. The workflow utilises some ComfyUI custom nodes available on my github page, or published through ComfyUI. Additional details...

    # Portrait Dataset Gate — self-driving LoRA dataset prep

    Point it at a folder of source photos. For each image it decides what that

    image actually needs, does only that, and names the output so you can see what

    happened. Built for face-centric LoRA training sets.

    **Workflow:** PORTRAIT_DATASET_GATE_v1.json

    ---

    ## What it does, per image

    ```

    source ─▶ score ──reject (too small, or not a photograph) ──▶ gate_rejected/

    │

    ├─▶ too soft/small? ──▶ SeedVR2 super-res ──▶ rescore (up to 2 passes)

    │

    ▼ accepted

    head crop (derotated to eye level, square, +15% padding)

    │

    ├─▶ black & white or sepia? ──▶ DDColor colourise → tag _col

    ├─▶ single-hue colour cast? ──▶ skin-anchored correction

    ├─▶ skin texture below 1.0? ──▶ SUPIR restoration → tag _sup

    ├─▶ face drifted? ──▶ revert to the crop → tag _noid

    └─▶ still marginal? → tag _rev

    ▼

    train/<original stem>[_col][_sup][_noid][_rev].png

    ```

    **The filename is the report.** No tag means it was clean out of the box.

    _col means every colour is invented — check those, especially hair.

    _sup means restoration ran. _sup_rev means it ran and the result is still

    marginal, so look at it. You only eyeball what the workflow couldn't settle.

    Every scoring also appends a row to quality_gate.csv with the metrics and the

    reason, so you can tune thresholds against what you actually see.

    ---

    ## Setup

    ### Required custom nodes

    - **[ComfyUI-PortraitDatasetTools](https://github.com/BillyBGit/ComfyUI-PortraitDatasetTools)** — the measurement and routing nodes

    - [ComfyUI-SeedVR2_VideoUpscaler](https://github.com/numz/ComfyUI-SeedVR2_VideoUpscaler) — super-resolution

    - [ComfyUI-DDColor](https://github.com/kijai/ComfyUI-DDColor) — B&W colourisation

    - [ComfyUI-KJNodes](https://github.com/kijai/ComfyUI-KJNodes) — ImageResizeKJv2

    - [ComfyUI-Custom-Scripts](https://github.com/pythongosssss/ComfyUI-Custom-Scripts) — ShowText

    SUPIR is **built into ComfyUI core** SUPIRApply + ModelPatchLoader) — no

    wrapper needed.

    ### Models

    | put in | file |

    |---|---|

    | models/model_patches/ | SUPIR-v0Q_fp16.safetensors — [Kijai/SUPIR_pruned](https://huggingface.co/Kijai/SUPIR_pruned) (2.7 GB) |

    | models/checkpoints/ | any photographic SDXL checkpoint (SUPIR is an SDXL pipeline) |

    | SeedVR2's folder | seedvr2_ema_7b_sharp_fp16 + ema_vae_fp16 |

    | models/upscale_models/ | a face upscaler such as 4xFaceUpSharpDAT |

    | DDColor's checkpoints/ | ddcolor_modelscope.pth |

    ### Running

    1. Set node *[2]** to your source folder — **one directory per line**. Every

    output path is relative to it, so you can paste in fifty model folders and

    each one's outputs land in its own place.

    2. Queue **once per image** using the **batch-count** field.

    3. Start ComfyUI **without --cache-none** — it breaks the lazy branches.

    That's the only path you need to set.

    ---

    ## Tuning

    Defaults came from surveying a ~400-image scraped dataset. Survey your own set

    before trusting them; a corpus of studio portraits sits very differently from

    scraped material.

    | widget | default | meaning |

    |---|---|---|

    | min_face_px | 500 | face bbox short edge, **native** pixels |

    | hard_floor_face_px | 200 | below this, reject without attempting super-res |

    | min_clarity | 60 | ~20 soft, ~60 acceptable, 150+ crisp |

    | min_source_grain | 0.15 | below = no sensor noise at all: illustration, airbrushed, or AI |

    | texture gate | 1.0 | below this, run restoration |

    | target_b (skin tone) | 14 | **dataset-specific.** ~14 warm-toned, ~9 East Asian |

    **Forcing individual images through:** the FORCE primitive accept /

    refine_1x / refine_2x) ignores every threshold. Put the stragglers in their

    own folder, point [2] at it, set it, queue, then set it back to off.

    ---

    ## Findings worth knowing

    **Restoration is capped by the VAE, not the model.** A pure VAE encode→decode

    with no sampling at all loses as much skin texture as any img2img pass at

    1024. Chroma, Flux.1, Flux.2, SRPO and Qwen-Image-Edit were all tested; all

    returned the input or worse. **SUPIR is the exception** — it carries a

    purpose-trained denoise encoder that replaces the VAE encoder for its hint

    latent, so its conditioning skips that low-pass. Measured 0.63 → 0.87 texture

    at ~20 s/image with identity preserved at 0.94.

    **SUPIR's denoise is a peak, not a slider.** 0.65 is best; 0.75 collapses back

    below the input. Raising it does not give you more.

    **SUPIR converges rather than simply improving.** It lifts low texture and

    pulls down high texture, so running it on everything would damage your best

    images. Hence the 1.0 gate.

    **A second restoration pass makes things worse** (0.45 → 0.36), and retrying at

    a different denoise doesn't rescue a failure — the peak doesn't move per image.

    There is deliberately no loopback.

    **Over-processed output usually means the source had no real texture.** Already

    airbrushed exports, illustrations and heavily compressed scans have nothing for

    super-res to recover, so it synthesises wax. That's what min_source_grain

    catches before any GPU time is spent.

    **For anything the pipeline can't lift: do nothing.** A soft but genuine

    photograph is better training data than invented texture — and the _rev tag

    already tells you which ones to look at.

    ---

    ## Licence

    Workflow: MIT. The models it loads carry their own licences.

    Description

    While this workflow uses SDXL for processing (used in conjunction with SUPIR), it is intended to prepare image datasets for lora training - which could be used to train any model.

    Workflows
    SDXL 1.0

    Details

    Downloads
    11
    Platform
    CivitAI
    Platform Status
    Available
    Created
    9/26/2026
    Updated
    9/26/2026
    Deleted
    -

    Files

    portraitdatasettools_v10.json

    Mirrors