CMK Detailer Finalize -Pipe-
One paste at the end, not five pastes in the middle
- detailer_pipe
- segs
- segs_2
- segs_3
- segs_4
- segs_5
- segs_6
- segs_7
- segs_8
- segs_9
- segs_10
- segs_11
- segs_12
- segs_13
- segs_14
- segs_15
- segs_16
- segs_17
- segs_18
- segs_19
- segs_20
- segs_21
- segs_22
- segs_23
- segs_24
- segs_25
- segs_26
- segs_27
- segs_28
- segs_29
- segs_30
- segs_31
- segs_32
- pipe
- image
- image_proceed
- diagnostic
- log_pipe
CMK Flow lets you run several detailer branches in parallel - different regions, different settings - and then composites all of them in exactly one place. CMK Detailer Finalize -Pipe- is that place. If you've ever stacked two detailers into a single chain and ended up with a face that looks laminated, this is the alternative.
What it does
Takes the DETAILER pipe from the prepare node and one or more sets of SEGS, does the final paste of every refined crop back onto the source image, and commits the result to a fresh CMK_PIPE. The incoming source pipe is never mutated in place, which is the kind of statement that sounds fussy until you've debugged a pipeline where two branches both quietly edited the same context.
Inputs: detailer_pipe, segs, feather (default 5, 0–100) and alpha (default 255, 0–255), both marked advanced. Then up to 32 more segs_N inputs and 32 optional log_pipe_N string inputs, which is how the parallel branches come in. Outputs: pipe, image, image_proceed, diagnostic, and a concatenated log_pipe string.
The mechanism
Each detected region arrives holding its own cropped, re-sampled image and its crop region. The paste walks every segment, clamps the crop rectangle to the image bounds, resizes the refined crop to the region if needed, and blends it in with:
out = original * (1 - mask) + refined * mask
where the mask is the segment's mask softened by a box filter of feather pixels, scaled by alpha / 255. So feather is your seam control - 5 is a tight blend, 40 onwards and you're fading detail out at the region edges - and alpha is a straight opacity cap on the whole paste, useful for a half-strength pass. All branches merge through this one path, including branches resolved from a cache hit, so a cached and a freshly executed branch composite identically. That sounds obvious and it isn't: it's the kind of detail that otherwise shows up as "the second run of the same workflow looks different."
One behavior the pack documentation is proud of: the SEGS merge only touches pixels inside the spatial support of the segments actually assigned to a branch, and it does not use a pixel-difference mask. That's deliberate - a difference mask lets the source and result images interleave into a salt-and-pepper mess when two branches disagree.
Failures you'll actually see
It raises with a specific message if the context is incomplete: "detailer_image is missing in detailer_pipe" or "source_pipe is missing" - both telling you to rebuild the context with CMK Detailer Prepare -Pipe-. In practice that means you wired a stale pipe from a different run, or you removed the prepare node and left the finalize in place. It won't guess.
Feeding it an empty SEGS collection is fine - it counts what it has, uses what's valid, and reports the totals. Garbage that isn't a well-formed SEGS tuple gets skipped rather than crashing the run, which is the right call in a node whose entire job is merging 32 optional inputs.
Install
Comes with the pack. Manager: search CMK Flow, install the CMKFlow entry, restart. Manually, from the directory containing main.py:
git clone https://github.com/CMKFlow/cmk_nodes.git custom_nodes/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py
Wait for CMK dependency check: OK - a manual clone doesn't run pip by itself, and that helper is the difference between a working pack and a wall of import errors. CMK Flow is a single-author GPL-3.0 project (Carsten Kirschner) open-sourced in July 2026; it's a self-contained implementation rather than a wrapper, so no Impact Pack needed for the SEGS machinery, but the shared environment does get ultralytics, onnxruntime, insightface, segment-anything and opencv-python installed into it.
Detector weights live under models/ultralytics/bbox (or segm), SAM under models/sams. The resource checker will audit the exact filenames the bundled workflows want and offer to fetch the missing ones:
python3 custom_nodes/cmk_nodes/scripts/check_cmk_resources.py --models-root "/path/to/shared/models"
Issues worth knowing
If you're seeing a visible seam, feather is the dial, but check the mask shape first - a bounding-box detector produces rectangular regions and rectangular seams, and softening the paste only hides that so far. A segmentation detector gives a polygon and the problem mostly disappears, which is the oldest known trade in this corner of ComfyUI.
Don't wire image from the finalize node back into the same detailer branch; that's a loop. The whole design assumes branches read the original and the finalize commits once.
And if a parallel branch's results vanish after you tweak one branch, that's the boundary cache doing its job with a stale dependency manifest. A restart clears it. Caches are temp-only by design, and the pack is explicit that they aren't a project format.
Inputs (67)
| Name | Type | Default | Description |
|---|---|---|---|
| detailer_pipe | CMK_DETAILER_PIPE | — | |
| segs | SEGS | — | |
| feather | INT | 50–100 | — |
| alpha | INT | 2550–255 | — |
| log_pipeopt | STRING | — | |
| segs_2opt | SEGS | — | |
| segs_3opt | SEGS | — | |
| segs_4opt | SEGS | — | |
| segs_5opt | SEGS | — | |
| segs_6opt | SEGS | — | |
| segs_7opt | SEGS | — | |
| segs_8opt | SEGS | — | |
| segs_9opt | SEGS | — | |
| segs_10opt | SEGS | — | |
| segs_11opt | SEGS | — | |
| segs_12opt | SEGS | — | |
| segs_13opt | SEGS | — | |
| segs_14opt | SEGS | — | |
| segs_15opt | SEGS | — | |
| segs_16opt | SEGS | — | |
| segs_17opt | SEGS | — | |
| segs_18opt | SEGS | — | |
| segs_19opt | SEGS | — | |
| segs_20opt | SEGS | — | |
| segs_21opt | SEGS | — | |
| segs_22opt | SEGS | — | |
| segs_23opt | SEGS | — | |
| segs_24opt | SEGS | — | |
| segs_25opt | SEGS | — | |
| segs_26opt | SEGS | — | |
| segs_27opt | SEGS | — | |
| segs_28opt | SEGS | — | |
| segs_29opt | SEGS | — | |
| segs_30opt | SEGS | — | |
| segs_31opt | SEGS | — | |
| segs_32opt | SEGS | — | |
| log_pipe_2opt | STRING | — | |
| log_pipe_3opt | STRING | — | |
| log_pipe_4opt | STRING | — | |
| log_pipe_5opt | STRING | — | |
| log_pipe_6opt | STRING | — | |
| log_pipe_7opt | STRING | — | |
| log_pipe_8opt | STRING | — | |
| log_pipe_9opt | STRING | — | |
| log_pipe_10opt | STRING | — | |
| log_pipe_11opt | STRING | — | |
| log_pipe_12opt | STRING | — | |
| log_pipe_13opt | STRING | — | |
| log_pipe_14opt | STRING | — | |
| log_pipe_15opt | STRING | — | |
| log_pipe_16opt | STRING | — | |
| log_pipe_17opt | STRING | — | |
| log_pipe_18opt | STRING | — | |
| log_pipe_19opt | STRING | — | |
| log_pipe_20opt | STRING | — | |
| log_pipe_21opt | STRING | — | |
| log_pipe_22opt | STRING | — | |
| log_pipe_23opt | STRING | — | |
| log_pipe_24opt | STRING | — | |
| log_pipe_25opt | STRING | — | |
| log_pipe_26opt | STRING | — | |
| log_pipe_27opt | STRING | — | |
| log_pipe_28opt | STRING | — | |
| log_pipe_29opt | STRING | — | |
| log_pipe_30opt | STRING | — | |
| log_pipe_31opt | STRING | — | |
| log_pipe_32opt | STRING | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| pipe | CMK_PIPE | — |
| image | IMAGE | — |
| image_proceed | IMAGE | — |
| diagnostic | CMK_DIAGNOSTIC | — |
| log_pipe | STRING | — |