Calculator
The Calculator that only knows one trick (mean spectra) — and that's fine
- image
- masks
- results
Here's a genuinely useful move with hyperspectral data: pick a region of your image, and ask what the average spectrum of that region looks like. That single question powers a huge amount of remote-sensing analysis - "what does the typical vegetation pixel reflect?", "how does this mineral class's spectrum differ from that one?" The Calculator node is that question, packaged for a ComfyUI graph.
Don't let the generic name fool you. Right now it does exactly one thing, and it does it cleanly.
How it works
You feed it a spectral image (the pack's SPE type, from either loader) plus one or more masks, and it computes, for each mask, the mean of every pixel where the mask is nonzero - averaged across all pixels but not across bands. So each mask becomes one row in the output, and the row has one value per band: that's the region's mean spectrum.
Mechanically it's about as simple as it gets. For every mask in the batch:
raw[mask != 0].mean(0)
The output lands as a 2D NDARRAY with shape (number_of_masks, number_of_bands). Nothing fancy, no learning, just honest statistics.
The inputs that matter
image(SPE) - the hyperspectral object, straight fromSpectral LoaderorENVI Loader.masks(MASK) - any ComfyUI mask works, but the intended pairing is obvious from the pack's example workflow: theKMeansnode's classes mask output. Run KMeans over your cube to segment pixels into classes, feed a few of those class masks in, and you get the mean spectrum per class - which is the standard unsupervised way to start understanding what's in a scene.method- an enum dropdown, and here's the honest part: it only containsmean, and that's its default. The dropdown is future-proofing, a placeholder for methods that don't exist yet. If you somehow picked something else, the code would raiseNotImplementedErroranyway. So ignore it; it's a promise, not a feature.
Output
results (NDARRAY) - the stack of mean spectra. Its natural destination is the pack's Plot node, whose series input expects exactly this shape: one spectrum per row, plotted against band number. That's precisely what the repo's example workflow does - KMeans segments, Calculator averages, Plot draws.
Installing it
ComfyUI Manager: search ComfyUI_Spectral, install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/chenlongming/ComfyUI_Spectral
cd ComfyUI_Spectral
pip install -r requirements.txt
then restart. (The README's reqirements.txt is a typo - the real file is requirements.txt.) The only dependency you probably don't already have is spectral; there are no model files to fetch.
Where people get tripped up
Two things. First, the MASK input isn't a single mask the way you might reflexively expect - it's a batch, and each mask in the batch becomes its own output row. That's a feature: it's how you compute a whole set of class spectra in one pass. Second, keep your expectations calibrated on the method dropdown - this is an early-stage pack (the README says so plainly), so "Calculator" is a name with ambitions, not a spec sheet. One mean-spectrum trick today, more later, maybe.
The real trap isn't the node, it's the data: raw[mask != 0].mean(0) averages everything the mask selects, so a sloppy mask (feathers, partial pixels, mixed classes) gives you a mushy spectrum that's a blend of whatever it overlaps. If your mask straddles two materials, the "mean spectrum" is neither. Clean masks in, clean spectra out.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | SPE | — | |
| method | COMBO | mean | 1 options: mean |
| masks | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| results | NDARRAY | — |