Nodes/ComfyUI CV/cv2.convertMaps
ComfyUI Node

cv2.convertMaps

Turn float remap maps into the fast fixed-point pair

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.convertMaps
  • map1
  • map2
  • dstmap1
  • dstmap2
◄dstmap1typeCV_16SC2 (fixed-point, faster remap)►
◄nninterpolationfalse►

Who this is for

cv2.remap takes a map of "for each output pixel, where do I read from?" and does the resampling. That map comes in two flavours: the readable one (two float32 arrays: x and y) and the fast one (a single packed int16 pair plus a uint16 interpolation-coefficient table). cv2.convertMaps converts between them.

So the pitch is: build your warp once in float, convert it to the fixed-point form once, then remap many images with the faster representation. If you're distorting one image, this node is pure overhead - there's nothing to amortise. If you're applying the same lens correction across a video batch, or running the same warp in a loop, it can be worth the extra step. The author's own tooltip puts the gain at roughly 30% faster remap for the fixed-point form.

It's a raw wrapper from ComfyUI CV (bmad4ever/comfyui_cv), category image/CV/low-level/cv2 C. The pack also ships a whole curated remap.py family (identity/lens/cylinder/relative maps) built around exactly this trick, with the design note: "Maps compose in NPARRAY space and collapse into ONE cv2.remap pass." If you're doing warp work, read that module's docs before hand-rolling maps.

How it works

In: map1 and map2. Out: dstmap1 and dstmap2. The conversion is bidirectional.

  • Float → fixed. Give it float32 maps (CV_32FC1 for both) and ask for CV_16SC2: you get a packed int16 x/y map plus a CV_16UC1 coefficient map. Fewer bytes, integer indexing, faster remap.
  • Fixed → float. Give it the packed pair and ask for CV_32FC1: you get the maps back in plain float, which is what you need if you want to inspect or edit them in NPARRAY space.

The subtlety is nninterpolation. The fixed-point pair is only valid for one interpolation mode. If the map will be consumed with INTER_NEAREST, that flag must be set at conversion time - get it wrong and the coefficient table doesn't match how the map is used, which shows up as subtle edge tearing rather than an error.

Fixed-point also quantises. The int16 map resolves to fractions of a pixel, not to floats, so a warp that needs sub-pixel precision beyond that will lose something in the conversion.

Inputs and outputs that matter

  • map1 - required, NPARRAY only. CV_16SC2, CV_32FC1 or CV_32FC2. The author's tooltip is explicit: a data array, not an image.
  • map2 - required, NPARRAY only. CV_16UC1, CV_32FC1, or an empty matrix - that last case matters, because the packed CV_16SC2 form carries x and y in a single map and leaves nothing for map2.
  • dstmap1type - required COMBO, defaulting to CV_16SC2 (fixed-point, faster remap), with CV_32FC1 (float32, standard) as the other option. This is the direction switch.
  • nninterpolation - optional BOOLEAN, default False, an advanced input. Set True when the fixed-point maps will be used with nearest-neighbour.
  • dstmap1, dstmap2 - the converted pair, ready for cv2.remap.

Build the input maps with the pack's remap.py nodes or with cv2.initUndistortRectifyMap; consume the output with cv2.remap.

Installing the pack

Manager → search ComfyUI CV, or:

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

Restart. Requirements: Python ≥ 3.12, a ComfyUI on the V3 node API, and opencv-contrib-python-headless~=5.0.0.93. Behaviour is curated against that pinned OpenCV build specifically.

Where people get burned

  • Converting for a single remap. The conversion cost is real and the saving only exists across repetition. One image → skip it.
  • nninterpolation left False while remapping with INTER_NEAREST. No error, just wrong resampling along sharp edges. Decide the interpolation mode before you convert, not after.
  • Empty map2 surprises. Both sockets are required. The packed form legitimately wants an empty second map, so wire something that can express "empty" - the pack's array nodes - rather than leaving a required socket dangling.
  • Expecting a visible result. Both outputs are NPARRAY data. There is nothing here to preview; the pixels only appear once you remap.
  • Losing precision you actually needed. If your warp is doing sub-pixel work on high-frequency detail - texture, fine text - check the fixed-point version against the float one before committing to it.
  • Pack caveats. LLM-assisted development, acknowledged overfitting risk, no planned updates, "not recommended in production" without independent review - and no community corpus behind the pack at all (a Reddit search comes back empty). That matters more for a node like this than for cv2.circle: an obscure optimisation path is exactly where an untested assumption survives. The pack's own docs are the best reference to read first, because they were written by the same process.
Categoryimage/CV/low-level/cv2 C

Inputs (4)

NameTypeDefaultDescription
map1NPARRAYThe first input map of type CV_16SC2, CV_32FC1, or CV_32FC2 . A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
map2NPARRAYThe second input map of type CV_16UC1, CV_32FC1, or none (empty matrix), respectively. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
dstmap1typeCOMBOCV_16SC2 (fixed-point, faster remap)Type of the first output map that should be CV_16SC2, CV_32FC1, or CV_32FC2 .
nninterpolationoptBOOLEANfalseFlag indicating whether the fixed-point maps are used for the nearest-neighbor or for a more complex interpolation. Preset to the OpenCV default (False).

Outputs (2)

NameTypeDescription
dstmap1NPARRAY—
dstmap2NPARRAY—