Nodes/ComfyUI Assistant Node/PVL Image Translation Offset Detector
ComfyUI Node

PVL Image Translation Offset Detector

Measure how far a frame drifted, down to sub-pixels

By pvlprk·Created about a year ago·Updated 8 months ago· 1
PVL Image Translation Offset Detector
  • original_image
  • shifted_image
  • mask
  • x_offsets_str
  • y_offsets_str
upsample_factor100
overlap_ratio0.30
delimiter[++]

Every so often you're handed two images that are almost the same frame - a video that jittered between takes, two passes of a workflow where the crop position shifted, an animation sequence with a camera nudge - and you need to know, in pixels, how much the second one moved. PVL Image Translation Offset Detector is the node for that. It compares a "shifted" image against an "original" and reports the x and y offsets, with sub-pixel precision if you want it.

It's not a daily driver. It's the tool you dig out when you're doing image registration or frame alignment and you'd otherwise be eyeballing it. Given how niche that is, it's a genuinely useful thing for a pack like pvlprk/comfyui-pvl-api-nodes ("ComfyUI Assistant Node") to include.

How it works

Under the hood it's phase_cross_correlation from scikit-image - a well-trodden, library-grade registration algorithm. Here's the part that makes it practical: the mask input. You use it to tell the node which regions changed (a moving object, a person, an edit) so they get ignored when computing the shift. Pixels where the mask is above 0.5 are excluded from the correlation; everything else counts as stationary reference. Feed a white mask over the thing that moved, black everywhere else, and the node measures the background shift instead of chasing your subject.

It converts images to grayscale, sizes the mask to match, computes the shift per image pair, and returns the offsets as strings, joined by a delimiter ([++] by default). Two outputs: x_offsets_str and y_offsets_str. The sign convention is baked in (offset * -1), so a positive x offset means the shifted image moved right relative to the original, roughly - test once against a known example before trusting it blindly.

Inputs that matter

  • original_image / shifted_image - the two IMAGE inputs, in that order.
  • mask - a MASK; white = ignore that region. The one input that makes or breaks the result.
  • upsample_factor - default 100. This is your sub-pixel precision dial; higher = finer shift estimates at some cost in time. Drop it to 1 if you only need whole-pixel answers.
  • overlap_ratio - default 0.3. Minimum overlap required between images for the correlation to be trusted.

Installing

cd ComfyUI/custom_nodes
git clone https://github.com/pvlprk/comfyui-pvl-api-nodes

restart, or install via ComfyUI Manager (search "ComfyUI Assistant Node"). This node does have a real extra dependency: scikit-image, which is in the pack's requirements.txt but isn't something vanilla ComfyUI ships. If Manager didn't auto-install requirements, you'll need:

pip install scikit-image

No models to download.

Where people get tripped up

The outputs are strings, not numbers. If you want to feed the offset into a math node or an image transform, run it through PVL String To Number (same pack) first - that's clearly how the author expects you to use it, given the delimiter convention matches the pack's string utilities. And remember the batch behavior: if you feed N pairs, you get N offsets joined together, one per frame. For a single pair you get a single value per output.

Categoryimage/alignment

Inputs (6)

NameTypeDefaultDescription
original_imageIMAGE
shifted_imageIMAGE
maskMASK
upsample_factorINT1001–200
overlap_ratioFLOAT0.300.1–0.9
delimiterSTRING[++]

Outputs (2)

NameTypeDescription
x_offsets_strSTRING
y_offsets_strSTRING