Shima NSFW Checker
Local content rating with actual censorship, not just a warning
- image
- UNGRADED_IMAGE
- CENSORED_IMAGE
- NO_BUG_IMAGE
- CENSOR_MASK
- NSFW_SCORE
- RATING_INFO
- IS_BLOCKED
Shima NSFW Checker is a content filter that actually does something. Most "NSFW detectors" in ComfyUI just give you a score and a warning. This one rates your image on a G-to-X scale, applies real censorship (mosaic, blur, or black bars over the offending regions), stamps a rating badge on the image, and can block the output entirely with a black image if you want a hard gate. It's a safety hub more than a detector.
Where it shines is production or shared-workflow contexts: you're running a pipeline that other people will run, or you're generating a lot of images and need a policy enforced without a human watching every batch. The workflow-compatible pattern is to keep the "safe" output as the main line and use the IS_BLOCKED boolean or the blocked UNGRADED_IMAGE to gate anything downstream. It's the kind of node you wire up once and then forget, which is exactly what a content filter should be.
One honest caveat: this is the pack's most dependency-hungry node. It uses a ViT-based classifier for a global NSFW score plus NudeNet for body-part segmentation, and it will try to pip install both on first use. If they're missing or the download fails, the node doesn't crash - it returns a black image, an empty mask, score 1.0, and "MISSING DEPS" as the rating info. That's a graceful failure, but it's also a silent one if you weren't watching: your "safe" output can go black because the model couldn't load, not because the content was unsafe.
How it works
For each image in the batch: it computes a global NSFW score via the ViT classifier, and if the score passes a low bar, it runs NudeNet to find exposed body parts (configurable to breasts, genitals, buttocks, or all). It then derives a rating - exposed genitals push it to X, exposed breasts to R, and the global score fills in PG/PG13/G - and compares against your rating_threshold. Unsafe images get censored per preview_mode (mosaic with adjustable block size, blur with adjustable radius, or black bars with adjustable thickness) at the detected regions, and a rating_bug badge (G/PG/PG13/R/X) gets drawn in a corner at the chosen size and position. block_nsfw switches the main image output to black when the content trips the threshold. custom_threshold lets you bypass the rating ladder and set a raw score cutoff instead.
The inputs that matter
image- the images to check.rating_threshold- G / PG / PG13 / R / X, the strictness gate (PG13 is default).preview_mode-none,blur,black_bar, ormosaic- how to censor.rating_bug- stamp the rating badge on the censored output.block_nsfw- force the image output black when unsafe.custom_threshold(optional) - raw score cutoff, overrides the rating ladder.detection_confidence,body_parts,mosaic_block_size,blur_radius,bar_thickness,rating_bug_position,rating_bug_size(optional) - the fine controls.
Outputs
UNGRADED_IMAGE, CENSORED_IMAGE, NO_BUG_IMAGE (the three variants: untouched, censored-with-badge, censored-without-badge), CENSOR_MASK (where it censored), NSFW_SCORE (FLOAT), RATING_INFO (STRING), and IS_BLOCKED (BOOLEAN). For a hard gate, wire IS_BLOCKED into a switch or use block_nsfw so nothing unsafe ever reaches the save node.
How to install it
Part of the Shima pack - ComfyUI Manager, search "Shima", or:
cd ComfyUI/custom_nodes
git clone https://github.com/KDB-USJP/shima_wf.git Shima
restart. On first run it installs nudenet and transformers into your Python env - expect that, and make sure the environment is writable (not a read-only venv).
Common issues & troubleshooting
Everything comes back black with "MISSING DEPS." The classifier or NudeNet failed to load - check the console for the pip install attempt and error. pip install transformers nudenet manually into ComfyUI's Python and restart.
Safe images get censored. Drop the threshold ladder: a lower rating (e.g. R instead of PG13) blocks less. Or set a custom_threshold - if the ViT score alone is what's tripping it, a raw threshold of 0.6+ behaves like the permissive end.
Score reads 1.0 on everything. Same missing-deps fallback as above - that's the "blocked" sentinel score, not a real measurement.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| rating_threshold | COMBO | PG13 | 5 options: G, PG, PG13, R, X |
| preview_mode | COMBO | mosaic | 4 options: none, blur, black_bar, mosaic |
| rating_bug | BOOLEAN | true | — |
| block_nsfw | BOOLEAN | false | If True, outputs a black image on 'IMAGE' output when unsafe content is detected. |
| custom_thresholdopt | FLOAT | 0.000–1 | — |
| body_partsopt | COMBO | all | 4 options: breasts, genitals, buttocks, all |
| mosaic_block_sizeopt | INT | 164–64 | — |
| blur_radiusopt | INT | 215–51 | — |
| bar_thicknessopt | INT | 6020–200 | — |
| detection_confidenceopt | FLOAT | 0.500.1–1 | — |
| rating_bug_positionopt | COMBO | bottom_right | 4 options: top_left, top_right, bottom_left, bottom_right |
| rating_bug_sizeopt | INT | 16040–400 | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| UNGRADED_IMAGE | IMAGE | Production Output: Returns original image if safe, black image if unsafe+blocked. |
| CENSORED_IMAGE | IMAGE | Preview Output: Always returns the image with censorship applied (for previewing what was detected). |
| NO_BUG_IMAGE | IMAGE | Censored image without the rating bug overlay. |
| CENSOR_MASK | MASK | Mask showing the censored regions. |
| NSFW_SCORE | FLOAT | Detected NSFW score (0.0 - 1.0). |
| RATING_INFO | STRING | Text summary of rating and detections. |
| IS_BLOCKED | BOOLEAN | True if the image was blocked due to safety settings. |