CV Save Classifier
Train once, predict forever, no Python node needed
- filename
- saved
This is the node that turns the ML corner of ComfyUI CV from a demo into a usable tool. CV Train Classifier fits a cv2.ml model - kNN, SVM, and friends - and hands you YAML text. This writes that text to disk, so a later workflow can load it from a dropdown instead of retraining, and so the graph that uses the model can be simple.
Where the file goes
model_yaml is the model text from CV Train Classifier. filename defaults to classifier, and .yml.gz is appended if it's missing - path components are stripped, so it always lands inside ComfyUI/models/cvml (a folder the pack registers with ComfyUI's folder system on import, the same way model loaders register their own).
The content is the standard OpenCV StatModel YAML, gzipped. Two consequences worth knowing:
- OpenCV's kNN and SVM models embed their training data, so the files can be chunky - gzip typically shrinks them by about 10×, which is why the pack compresses rather than writing plain YAML.
- To use the model outside ComfyUI, gunzip it and feed it to
cv2.ml.SVM_loador the matching loader. It's a real OpenCV model file, not a pack-specific format.
Re-saving the same filename overwrites, deliberately, so re-running a training graph is idempotent. And the gzip header's mtime is pinned to zero, which means identical models produce byte-identical files - a small detail that makes "did the model change?" answerable with a diff.
Outputs
filename is the name written inside models/cvml, and it's the same string that CV Predict Classifier's model dropdown lists after a page reload. Note the phrasing: after a page reload. Node input combos are populated when the definitions are fetched, so a file saved during a session doesn't appear in the dropdown until you refresh - the same gotcha the pack documents for loading example inputs. If your freshly saved model seems missing, refresh before you start debugging.
saved is a BOOLEAN and it's the honest one: an empty model_yaml - the signature of a trainer that reported success=false - writes nothing and returns saved=false rather than raising. Your graph keeps running and the flag tells you nothing was produced. This is an output node with no downstream requirement, so it runs even with nothing wired to it.
There's a deliberate omission worth appreciating: the returned filename is the bare name, not a path. The tooltip explains why - an absolute path leaving the node would end up embedded in shared workflow JSON and pasted previews, carrying your drive layout, install location and username with it. Nice bit of paranoia in a pack that's otherwise happy to throw arrays around.
The workflow this enables
workflows/exercise_shape_classifier_hog.json trains a HOG+SVM shape classifier on data synthesised inside ComfyUI - three shapes drawn with raw cv2 primitives, then augmented with rotations, noise and brightness shifts - and saves it here. workflows/exercise_classifier_reuse.json then contains no trainer at all: CV Predict Classifier picks the saved file and classifies a fresh query set with rotations and brightness the training run never saw. Train once, predict forever, and the inference graph is three nodes long.
That pair is a genuinely good demonstration of the idea, and worth running through once even if you never touch cv2.ml again - it's the cleanest illustration in the pack of why saving a model is worth a node.
Install
Part of ComfyUI CV (bmad4ever/comfyui_cv), GPL-3.0 fork of opencv-comfyui:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
# restart ComfyUI
Manager users: search the pack title. Python ≥ 3.12 and a V3-node-API ComfyUI build. models/cvml is created/registered on import, so you don't need to make the folder by hand.
Straight talk about the corner it lives in
This is classic computer vision, not deep learning. A saved SVM with HOG features will classify your three shapes and your region properties and your superpixel statistics perfectly well; it will not recognise a cat. Read the pack's own ML nodes as "teach a graph a threshold automatically" rather than as a lightweight replacement for a trained network, and you'll get real value out of it - the honest use is turning hand-tuned heuristics into something fitted from examples you generated yourself.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| model_yaml | STRING | The model_yaml output of 'CV Train Classifier' (loadable OpenCV YAML text). | |
| filename | STRING | classifier | File name inside models/cvml; '.yml.gz' is appended if missing, path components are stripped. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| filename | STRING | Name of the file written inside models/cvml - the same string the 'model' combo of 'CV Predict Classifier' lists after a page reload ('' when nothing was saved). The folder it lives in is deliberately NOT part of it: an absolute path leaving the node would end up in shared workflow JSON and pasted previews, carrying the drive layout, install location and user name with it. |
| saved | BOOLEAN | False when model_yaml was empty (the trainer failed upstream) - nothing was written. |