OCS ApplyFilterImage
Test OCS filters on a plain image before you trust them in a sampler
- image
- IMAGE
OCS's whole claim to fame is that you can filter almost anything mid-sampling - the model input, the denoised output, the noise - using a YAML filter language built on expressions and blends. But those filters run inside a sampling loop, where debugging is miserable: you can't see the intermediate tensor, and a bad filter fails somewhere in the middle of step 14. OCS ApplyFilterImage lets you run the exact same filter machinery on a plain, visible image, so you can see what a filter actually does before you deploy it into a workflow.
What it is
A standalone filter application node. It takes an IMAGE, a seed, and a yaml_config containing a filter definition, applies the OCS filter, and outputs the filtered IMAGE. Under the hood it's nearly identical to the latent version - the source literally subclasses ApplyFilterLatent and just converts the image to the latent-style channel layout and back. The filter language, blending modes, and expression functions are the same ones used in the sampler's noise.filter and model.filter blocks.
The inputs that matter
image(required) - any image tensor. Batches are fine; a single image gets treated as a batch of one.seed(required, default 0) - seeds any noise the filter generates. Useful if a filter uses noise and you want reproducible output.yaml_config(required) - the filter definition. The tooltip's warning is blunt: "there is essentially no error handling." The structure is:
filter:
filter_type: simple
input: default
output: default
strength: 1.0
filter_type selects the behavior (simple, blend, list, and the rest documented in docs/filter.md), and input/output hold expressions using the OCS expression language. If the config isn't an object with a filter key, you get a ValueError - it's the only guardrail, and it's not a friendly one.
The single IMAGE output is the filtered result, ready for a preview node so you can actually look at it.
How to actually use it
Load an image, drop this node after it, and iterate on the yaml_config until the output looks like what you intend - then copy that filter block into the sampler, group, or substeps node where it'll run live. That round-trip is the entire point of the node's existence. It's also handy for offline image work: an OCS filter is just a tensor transform, and this node lets you apply it outside sampling entirely.
Installing and gotchas
Comes with the pack - ComfyUI Manager search "Overly Complicated Sampling", or git clone https://github.com/blepping/comfyui_overly_complicated_sampling into ComfyUI/custom_nodes, then restart. No models, no mandatory dependencies.
The gotchas are the same ones that plague the whole filter system: no error handling (a typo is a raw traceback), and the expression language is OCS's own - //, **, :> keyword args, backtick operators - not Python. Read docs/filter.md and docs/expression.md in the repo before writing anything clever. One thing the image node does not share with the latent version is the mask caveat - ApplyFilterLatent ignores masks; for images there are no masks to ignore.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Image input. | |
| seed | INT | 00–18446744073709550000 | Seed to use for generated noise. |
| yaml_config | STRING | Enter your filter definition here. There is essentially no error handling. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |