Nodes/ComfyUI CV/CV Quality BRISQUE Features
ComfyUI Node

CV Quality BRISQUE Features

The 36 numbers behind the score

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
CV Quality BRISQUE Features
  • images
  • features
  • count

The descriptor half of BRISQUE, without the SVM. Where CV Quality BRISQUE (no-reference) gives you one opinionated number, this gives you the 36 features that number is computed from.

What's in the vector

Natural-scene statistics: the mean, variance and shape of locally normalised luminance at two scales, then pairwise products of neighbouring coefficients in four directions. The idea is that a natural photograph has a characteristic distribution of these statistics, and degradations - blur, noise, compression - push it away from that distribution. The features describe how natural an image's statistics are.

That makes it a general-purpose image descriptor, not just a quality metric, which is the interesting part. It needs no model file, no reference image, and no training data - just the image. Thirty-six numbers per frame, deterministic, fast.

What you'd actually do with it

Feed it into this pack's classic ML corner. CV Train Classifier trains a cv2.ml model; CV Stack Feature Classes builds a labelled training matrix; CV Save Classifier and CV Predict Classifier handle the round trip. So the workflow is: collect a few hundred images of "good" and "bad" for your specific problem, build the matrix, train, save, and now you have a quality or defect classifier that reflects your judgement rather than the LIVE database's.

That's more useful than it sounds. The shipped BRISQUE SVM was trained on a generic image-quality database; it doesn't know that your pipeline's characteristic failure is a slightly plastic skin texture, or that a particular denoiser leaves faint banding in flat skies. Thirty-six naturalness features plus your own labels do. It's also the cheapest sensible answer to "I want to auto-cull outputs and I can't define what bad looks like in words" - label a hundred, train for a second, and let the classifier find the boundary.

The other honest use is diagnostics: run the features over a batch of your own failures and successes and look at which columns separate them. That tells you what is wrong with the failing images, which is often the actual thing you needed to know.

Inputs and outputs

One input, images - an NPARRAY, IMAGE or MASK, and every frame of a batch gets its own row. One row per frame, so the output is exactly the sample matrix a classifier wants.

features is an (N, 36) float32 array - N being the number of frames. count is how many rows came out, which is your check that the batch size is what you thought before you feed it to a trainer.

One practical note: your training images and your inference images should come from the same kind of source. Features extracted from full-resolution photos and features extracted from half-scale previews are different distributions even for identical content, and a classifier trained on one will perform oddly on the other.

Installing

ComfyUI Manager → search "ComfyUI CV", or:

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

Python ≥ 3.12, a recent ComfyUI on the V3 node API, opencv-contrib-python-headless~=5.0.0.93, numpy, torch. Unlike its sibling, this node needs no data files at all - computeFeatures is pure computation, so there's nothing to download and nothing to point at. The feature-range normalisation that the scoring node needs is only applied when you actually run the SVM.

Gotchas

The features are unnormalised. The scaling to a known range happens in the scoring path, using brisque_range_live.yml. If you train your own classifier on raw features that's fine - it just has to be consistently raw, and you must not mix normalised features into the same training set.

Values are not interpretable individually. Column 17 of the vector has no name you can act on. Treat the 36 as a signature to be compared and clustered, not as measurable properties.

It's a feature extractor, not a verdict. Nothing here tells you whether an image is good. That's either the SVM behind the scoring node or your own labels.

Categoryimage/CV/quality

Inputs (1)

NameTypeDefaultDescription
imagesNPARRAY,IMAGE,MASKImage(s) to describe. One feature row per frame. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.

Outputs (2)

NameTypeDescription
featuresNPARRAYfloat32 array of shape (N, 36) - one row per frame, ready as a sample matrix for 'CV Train Classifier' / 'CV Stack Feature Classes'.
countINTNumber of feature rows (= batch size).