Nodes/ComfyUI CV/CV Mosaic (RGB -> Bayer CFA)
ComfyUI Node

CV Mosaic (RGB -> Bayer CFA)

Make your own RAW file, because you can't download one

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
CV Mosaic (RGB -> Bayer CFA)
  • nparray
  • cfa
◄patternRGGB►

Here's a problem with demosaicing research that almost nobody says out loud: to test what a demosaic algorithm does, you need an un-demosaiced image. Real cameras give you a CFA and the camera's own processing. Downloadable ground-truth RGB is everywhere; licence-safe raw Bayer sample data is essentially not. So you synthesize one.

This node takes a 3-channel RGB ndarray, and at each pixel keeps only the single channel a real Bayer sensor would sample there, following a 2×2 pattern. The result is a single-channel colour-filter-array - the inverse of cv2.demosaicing. Then you demosaic it back with whatever algorithm you're curious about and score the reconstruction. It's a test rig, not a production step, and it's a good one.

How it works

The pattern names the layout of the top-left 2×2 block, and it must match the demosaicing code you feed the result into (COLOR_Bayer<pattern>2RGB, optionally with _VNG or _EA):

  • RGGB (default) - R at (0,0), G at (0,1) and (1,0), B at (1,1). The most common sensor layout.
  • GRBG, GBRG, BGGR - the other three, present so you can test all of them.

nparray is an [H,W,3] RGB image with channel 0 = R, so build it with Image -> CV Array in RGB mode. Green is sampled at twice the density of red and blue - that's the point of the pattern, and it's why demosaic algorithms fight so hard over the G plane.

One behaviour worth knowing because it's lenient rather than strict: a single-channel input is treated as already mosaiced and passed through untouched. So you can chain mosaic → transform → mosaic again, or feed the node a CFA from elsewhere, without an error.

What you do with it

Image -> CV Array (RGB)  →  CV Mosaic (RGB -> Bayer CFA)  →  cv2_demosaicing  →  PSNR / cv2_absdiff

Score that round trip and you can see, with your own eyes, exactly what each algorithm costs - the zipper artefacts on edges, moire on fine texture. Different demosaic methods (bilinear, VNG, EA) trade sharpness against colour fringing, and the difference only really lands when you look at your own image rather than a paper's figure.

cv2_demosaicing is one of the pack's auto-generated raw wrappers, and this is exactly the case the author means when they say the ~470 generated cv2.* wrappers are uncurated: you're responsible for the input dtypes and the flag values. That's fine for a test rig. It's less fine if you expected a polished node.

Inputs and outputs

Required: nparray (the RGB image), pattern. Output: cfa - a single-channel [H,W] array, same dtype as the input, one colour sample per pixel. That's all it does.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv

Manager → ComfyUI CV. Restart and reload. Python ≥ 3.12, V3-API ComfyUI, opencv-contrib-python-headless~=5.0.0.93. No models, nothing to download, runs in milliseconds.

Common issues

A demosaiced result that's wildly green or colour-shifted. Pattern mismatch - you mosaiced RGGB and demosaiced with COLOR_BayerBG2RGB. OpenCV's naming convention for these codes refers to the second row of the pattern, which is a reliable source of confusion; the pack's tooltip points you at matching them explicitly, so do that rather than guessing.

A shape error. The input wasn't [H,W,3]. Image -> CV Array defaults to BGR in most pipelines, and this node wants RGB; use the RGB mode. Then demosaic in the matching channel order.

Score comparisons that don't mean much. Demosaic quality is content-dependent - smooth gradients and fine texture fail differently. One image proves nothing. This node's value is making the comparison runnable on your own data, which is more than most people have.

Categoryimage/CV/low-level

Inputs (2)

NameTypeDefaultDescription
nparrayNPARRAYRGB image [H,W,3] (channel 0 = R). Use 'Image -> CV Array' in RGB mode to produce it. A single-channel input is treated as already-mosaiced and passed through unchanged.
patternCOMBORGGBCFA layout of the top-left 2x2 block. RGGB = R at (0,0), G at (0,1) and (1,0), B at (1,1) - the most common sensor. Must match the demosaicing code downstream (COLOR_Bayer<pattern>2RGB...).

Outputs (1)

NameTypeDescription
cfaNPARRAYSingle-channel [H,W] CFA (same dtype as the input) - one colour sample per pixel. Feed it into cv2.demosaicing.