Nodes/ComfyUI CV/CV Apply Chromatic Aberration
ComfyUI Node

CV Apply Chromatic Aberration

Add the lens defect that makes a render look photographed

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
CV Apply Chromatic Aberration
  • image
  • IMAGE
◄calibration_file▾►
◄strength1.00►

Cheap lenses bend different wavelengths by different amounts, so the red and blue channels land slightly scaled compared to green - visible as colour fringing that grows toward the corners. Expensive glass reduces it; every real photograph has some. Generated images have exactly none, which is part of why they read as generated. This node adds it, from a calibration file, so the amount is a number you control instead of a vibe.

Why you'd reach for it

It's one component of the anti-AI realism stack, and the community keeps itemising that stack: grain, motion blur, a little vignette, and "red channel aberration" is the phrasing you'll see listed alongside them. Grain you can get from half a dozen packs. Lateral chromatic aberration, applied as a lens model rather than as a channel blur, is rarer - and this pack implements it properly: the displacement comes from a polynomial per-channel model, applied through a remap, with green held fixed as the reference channel.

Two honest uses:

  1. De-AI a still or a clip. A subtle pass at low strength makes edges in the corners fringe the way a real lens fringes. It is deterministic, so you can bake the exact same defect across a whole sequence.
  2. Build a round trip. This is the node the pack pairs with CV Chromatic Aberration Correction: apply a known CA, correct it, and check the correction actually recovers the image. If you're evaluating whether you need the correction node on your footage, that test is the answer.

How it works

The calibration file holds polynomial displacement coefficients plus the size the calibration was made at. The node builds separate map_x/map_y displacement maps for the red and blue channels from those coefficients, scaled by strength, and remaps each channel with linear interpolation (BORDER_REFLECT_101, so the frame edge wraps rather than going black). Green is untouched. Because it's a warp of the R and B planes, the amount of fringing grows with distance from the optical centre without any per-pixel masking - that's what makes it look like glass rather than a filter.

You don't have to own the calibration. Create CA Calibration in the same pack synthesises a target you can shoot or simulate, and CV Chromatic Aberration Correction is the consumer of the same file.

The inputs that matter

  • image - the input. A batch is processed frame by frame, so one node covers a whole clip.
  • calibration_file - a dropdown of .yaml/.xml files from input/calib/. Run Create CA Calibration first, then pick the same filename here. An empty dropdown is an error, not a fallback: pick a file or the node raises.
  • strength - a multiplier on all the polynomial coefficients, default 1.0. 1.0 is the exact calibrated displacement; 0.0 is a no-op; 2.0 doubles it. For the de-AI use you want well under 1 - the point is subtle fringing, and the tooltip's range goes to 100 mostly because somebody will try it.

Output: IMAGE. Same size as the input (see below), batch preserved.

Install

ComfyUI Manager → ComfyUI CV, or:

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

Restart ComfyUI. The pack needs opencv-contrib-python-headless~=5.0.0.93 - behaviour is curated against that pinned build - plus Python 3.12+ and a ComfyUI on the V3 node API. No model downloads: this one is pure arithmetic on your pixels.

Traps and gotchas

  • The calibration file lives in input/calib/. If the dropdown is empty, that folder is empty. Anything you generate with Create CA Calibration lands there.
  • Size mismatch resizes your image. If the frame doesn't match the calibration's recorded size, the node scales the image to the calibration size, applies the displacement, and scales back - and logs a warning. The displacement maps are defined in calibration pixels, so this keeps the fringe magnitude honest, but it's a resample you didn't ask for. Generate a calibration at your working resolution and this never happens.
  • Too much strength looks like a broken render, not a lens. Real lateral CA is a pixel or two at the frame edge. If your corners look like a 3D-red-cyan anaglyph, you're an order of magnitude over.
  • It's a lens defect, not a bloom or a glow. No halo, no blur - only per-channel geometric displacement. Bloom is a different pass; faking it here just gives you soft edges.
  • Fringes are content-dependent. High-contrast detail near the corners shows them, flat sky doesn't. A full-frame JPEG preview will look like nothing happened; check a crop.
Categoryimage/CV

Inputs (3)

NameTypeDefaultDescription
imageIMAGEInput image. A batch is processed frame by frame.
calibration_fileCOMBOCalibration file from input/calib/ (.yaml/.xml) that defines the polynomial displacement. Run 'Create CA Calibration' first, then pick the same filename here.
strengthFLOAT1.000–100Multiplier for all polynomial coefficients. 1.0 = exact displacement from the calibration; 0.0 = identity (no CA); 2.0 = double strength.

Outputs (1)

NameTypeDescription
IMAGEIMAGE—