Nodes/opencv-comfyui/OpenCV copyTo_0
ComfyUI Node

OpenCV copyTo_0

Mask-aware copying, the compositing glue you're missing

By geroldmeisinger·Created about a year ago·Updated about a year ago· 35
OpenCV copyTo_0
  • src
  • mask
  • dst
  • nparray

copyTo_0 is the mask-aware copy node: it copies pixels from src but only where a mask is nonzero, and leaves everything else alone. In one node it does the two things you end up hand-building otherwise - "keep only this masked region" and "paste these pixels back into a bigger image." It's the compositing glue that belongs in any workflow where a mask meets an image.

The inputs are src (NPARRAY) and mask (NPARRAY); output is a single nparray. Two behaviors, depending on whether you wire the optional dst:

  • No dst (the common case): you get a new array equal to src wherever the mask is nonzero, and zeros (black) everywhere else. That's masking out - extracting the masked region onto a black background.
  • With dst: pixels from src are written into dst wherever the mask is nonzero, and dst stays unchanged everywhere else. That's compositing - pasting a crop back onto a canvas, or restoring original pixels into a region you'd modified.

The optional dst input is one of those OpenCV out-parameters, but here it's actually meaningful: leaving it empty gives you the extract behavior, feeding one gives you the paste behavior. That's the one genuine design fork on this node.

Where it fits in real workflows

This is squarely in the "get a mask, act on it" territory the detection/inpainting docs describe. Classic uses: extracting just the detected face region for a detailer pass, then pasting the refined crop back over the original with dst - or, after an inpainting pass, using a mask to copy the original pixels back into areas you don't want touched. It's the low-level compositor that makes "only this region changed" possible.

One practical note: the mask should be a single-channel uint8 array (0s and 255s) the same size as src. A grayscale mask works as a binary gate here - nonzero is "copy," zero is "skip." If your mask comes out of a ComfyUI masking node, it may arrive as a float tensor, so route it through Image2Nparray (batch 1 only) and check it's actually single-channel before feeding it in.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
pip install opencv-python-contrib

Or ComfyUI Manager → opencv-comfyui → restart. No models.

Troubleshooting

  • Size mismatch between src and mask → assertion error. Same dimensions required.
  • The BGR thing again: this pack works in BGR, so convert colors with cvtColor if you're inspecting results, and remember the Image2Nparray/Nparrays2Image bridge is how IMAGE gets in and out.
  • copyTo_0 and copyTo_1 are the identical overload pair (MatLike vs UMat). Same node, either works.
Categoryimage/OpenCV

Inputs (3)

NameTypeDefaultDescription
srcNPARRAY
maskNPARRAY
dstoptNPARRAY

Outputs (1)

NameTypeDescription
nparrayNPARRAY