OpenCV compare_0
Turn 'where do these images differ' into an actual mask (OpenCV compare_0)
- src1
- src2
- dst
- nparray
Every now and then you don't want an image, you want a question answered per pixel: is this frame different from the reference? Is this region brighter than it was? OpenCV's compare answers those, and compare_0 is it, wrapped for ComfyUI. Feed it two nparrays, tell it how to compare them, and you get back a single-channel mask of 255s and 0s - no model, no API key, no downloads. Just math.
What it actually is
compare_0 is one of the ~635 auto-generated nodes in the opencv-comfyui pack, which turns every standalone function in OpenCV's cv2 into a ComfyUI node. Under the hood it does exactly one thing:
cv2.compare(src1, src2, cmpop, dst)
That's the whole node. The author generated it from OpenCV's type stubs and then let you drive cmpop directly. It's faithful, it's fast, and it's about as raw as OpenCV gets.
How it works
For every pixel position, compare applies the operator in cmpop between the pixel in src1 and the pixel in src2, then writes 255 where the comparison is true and 0 where it's false. The cmpop int is one of the classic OpenCV constants:
0- equal (CMP_EQ)1- greater than2- greater or equal3- less than4- less or equal5- not equal
The two arrays must be the same shape, or OpenCV throws its signature assertion error. It's element-wise, so feed it single-channel grayscale for a clean mask; feed it BGR and you get per-channel comparisons, which is usually not what you meant.
The inputs and outputs that matter
- src1 / src2 (NPARRAY) - the two arrays you're comparing. Same size, same depth, or expect an assertion.
- cmpop (INT) - the operator, from the list above.
0(equal) is the one you'll actually reach for: "make me a mask of every pixel that changed." - dst (NPARRAY, optional) - an out-parameter. The README says it outright: avoid the optional out-parameters (usually called
dst). Leave it unconnected.
Output: one nparray - the 8-bit single-channel mask. Wire it into Nparrays2Image to eyeball it, or feed it straight into anything downstream that takes a mask.
Where it fits in a workflow
This is a crude-but-free change/motion detector. Take a frame, hold it as the reference, run the next frame through compare_0 with cmpop=0, and the white pixels are exactly where they differ - handy for inpainting loops that should only touch what moved. It's also the classic "make a mask from a threshold" trick. The broader point from the masking world applies here too: "you can get that mask in SO many ways" - this is one of the cheapest ones, and it costs you nothing to run.
Installing it
Install the whole pack once and you get every OpenCV node, this one included:
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
or search opencv-comfyui in ComfyUI Manager. The pack needs opencv-python-contrib (opencv-contrib-python in requirements.txt); you almost certainly already have OpenCV in your env from another pack, and if you don't, pip install opencv-python-contrib fixes it.
Common issues
- Size mismatch →
cv2.error: (-209:Sizes of input arguments do not match). Resizesrc2tosrc1first. - "Only images with batch_size==1 are supported" from
Image2Nparray→ you fed a batch. Split withImageFromBatch(length=1) before converting. - Wrong
cmpop→ you won't get an error, you'll get a mask that's backwards or empty.5(not equal) is the natural instinct for "changed pixels" but0with inverted input works too - check the output visually.
Expect dragons, as the author warns - but for this one node, the dragon is mostly just "remember it's per-pixel and both inputs must match."
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| src1 | NPARRAY | — | |
| src2 | NPARRAY | — | |
| cmpop | INT | — | |
| dstopt | NPARRAY | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |