Nodes/opencv-comfyui/OpenCV moments_0
ComfyUI Node

OpenCV moments_0

Get the area, centroid, and orientation of any detected shape

By geroldmeisinger·Created about a year ago·Updated about a year ago· 35
OpenCV moments_0
  • array
  • literal
binaryImage

Ever want to know how big a detected object is, where its center of mass is, or which way it's tilted? That's image moments - a compact set of statistics OpenCV computes from a binary shape. moments_0 wraps cv2.moments so you can pull them off a mask inside ComfyUI.

Why you'd reach for it

You've segmented something - SAM, a depth threshold, a color range - and the mask comes out as a blob of white pixels. Moments turn that blob into numbers:

  • m00 is the area (pixel count)
  • m10 / m00, m01 / m00 give the centroid (x, y)
  • mu20, mu02, mu11 describe spread and orientation
  • the normalized (nu) and Hu moments are rotation/scale-invariant signatures - useful for matching shapes against a reference

This is the "measure the thing you detected" step, the same family as contourArea and boundingRect in the pack.

The honest caveat: the output is a string

Here's the rub. cv2.moments returns a Moments object - a class instance, not an image or a tuple of numbers. This pack only emits images, floats, and literal strings, so the whole Moments object gets stringified into a single literal (STRING) output. You get one text blob containing m00=..., mu20=..., etc.

That makes moments_0 a genuinely useful inspection tool - wire in a mask, read off the numbers in the widget, understand your blob - but a poor automation building block. If you need the centroid as floats you can wire into arithmetic, you'll be parsing that string. For serious automated shape-analysis you'd more likely compute moments in a Python snippet outside the graph. Know that going in and it won't bite you.

Inputs

  • array (NPARRAY) - must be single-channel (grayscale or a binary mask). A 3-channel image throws error: (-215:Assertion failed) img.type() == CV_8UC1.
  • binaryImage (BOOLEAN) - when True, every non-zero pixel counts as 1. Leave it True for masks; it makes the moments exact pixel statistics instead of weighting them by intensity.

Installing it

Part of geroldmeisinger/opencv-comfyui, which auto-generates ~635 cv2 wrappers. Install via ComfyUI Manager (search "opencv-comfyui") or:

cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui

then restart. Dependency is opencv-contrib-python, which you likely already have.

The pipeline

IMAGE → Image2Nparray → moments_0. Image2Nparray flips RGB→BGR and only takes batch_size==1. To read a mask, convert it to grayscale (mask channels are already 1-channel, so this works directly). The literal output is a string, not an image - don't feed it to Nparrays2Image.

Troubleshooting

  • CV_8UC1 assertion - feed single-channel input only.
  • Output looks like one long text value - expected, that's the stringified Moments object.
  • Batch error - Image2Nparray handles one image per call; use ImageFromBatch (length=1).
Categoryimage/OpenCV

Inputs (2)

NameTypeDefaultDescription
arrayNPARRAY
binaryImageBOOLEAN

Outputs (1)

NameTypeDescription
literalSTRING