cv2.ximgproc.computeMSE
Two disparity maps, one number
- GT
- src
- float
Mean squared error between two disparity maps. That's the whole node: GT and src, an ROI, and one float out. It's the plainest quality metric in the pack, and it's the one you want when you need a single monotonically-sensible number to sort candidates by.
It also has a specific weakness that its sibling in the same module exists to fix: squaring the error means outliers dominate. One bad region - a mislabelled patch, an invalid band, a depth estimator's edge-case failure - can move the mean more than a broadly mediocre map improves it. So when you're comparing, run both this and computeBadPixelPercent (which counts pixels over a tolerance instead of squaring them) and watch whether they agree. When MSE says one thing and bad-pixel-percent says another, you know you're looking at outliers rather than improvement.
Inputs
GT- ground-truth disparity.NPARRAY,IMAGEorMASK; frame 0 of a batch.src- the map being evaluated, same accepted types.ROI_x,ROI_y,ROI_w,ROI_h- the region to score, as four ints. There is no sensible default here and OpenCV's is all zeros, i.e. an empty rectangle. Set them. The reason ROI is exposed at all in these nodes is that a stereo map has an invalid band along one edge, and averaging that nonsense into your score measures the matcher's geometry rather than its quality. This pack's curatedCV Disparity Filter (WLS)has anauto (skip the invalid left band)mode that picks the ROI for you.
Output: one FLOAT - there's no image preview, so wire it into Inspect CV Data to read the value.
When it's the right metric
Disparity maps and depth maps with real units, compared against something you trust. Use it to answer "did the refinement step make this better or worse", "is WLS or the interpolator better on this frame", "which of these two stereo settings should I ship". It's arithmetic, it's deterministic, and it doesn't have opinions - unlike your eyes, which will prefer the smoother map every time even when the smoother map is less accurate.
When it isn't
If you're comparing two images - a before/after of a denoiser, an upscaler, a filter - MSE is a poor proxy for what you perceive, and on 8-bit data it's dominated by tiny differences in flat regions. Use the pack's CV Quality Compare instead: it scores SSIM and hands back a per-pixel quality map so you can see where the two images disagree. Same idea, perceptual metric, and it takes images (colour included) rather than disparity maps.
And be careful with normalisation. MSE between a 0–1 float map and a 0–255 uint8 map will be enormous for reasons that have nothing to do with the algorithm. Cast to a common dtype (CV Cast Array) and make sure both are the same scale before you believe a comparison.
A practical loop
Load GT ─┐
├→ computeMSE → Inspect CV Data
Load A ──┘
Load B ──┘ → computeMSE → Inspect CV Data
Same ROI every run, one variable changed at a time, and write the numbers down. This is the least glamorous habit in computer vision and it's the one that separates people who tune filters from people who shuffle them.
Installing it
Part of ComfyUI CV, contrib module. Manager → search ComfyUI CV, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
# restart ComfyUI
Python ≥3.12 and a recent V3-API ComfyUI.
What goes wrong
- ROI left at zero - an empty rectangle is the default, not a no-op.
- A wild number. Units or dtype mismatch between the two maps, or an uninitialised region of the estimate (disparity maps are full of holes and sentinel values; filter them before scoring, with something like
cv2_filterSpecklesor a validity mask). - Missing node.
ximgprocis contrib-only. All fouropencv-python*distributions share onesite-packages/cv2, so a non-contrib install silently turns the submodule into an empty stub.tools/repair_opencv_contrib.py --checkin the pack repo reports it. - Expecting a preview. The output is a float, not an image.
Inspect CV Datais how you see it.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| GT | NPARRAY,IMAGE,MASK | ground truth disparity map Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| src | NPARRAY,IMAGE,MASK | disparity map to evaluate Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| ROI_x | INT | 0-2147483648–2147483647 | Rectangle top-left corner X in pixels. |
| ROI_y | INT | 0-2147483648–2147483647 | Rectangle top-left corner Y in pixels. |
| ROI_w | INT | 00–2147483647 | Rectangle width in pixels (>= 0). |
| ROI_h | INT | 00–2147483647 | Rectangle height in pixels (>= 0). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| float | FLOAT | — |