This is a Stable Diffusion web UI extension that uses NudeNet to detect NSFW regions in an image, allowing for partial censoring of the image, useful when sharing images NSFW images on social media.
Image generation
andLive preview
- Auto and manual censor
Extras tab
tab - Post-processing via
Extras tab
- Partial censoring of the image
- Customizable censoring categories
- Multiple censoring methods
- API
Gaussian Blur
: Blur the image control withBlur strength
Variable blur
: Applies varying strength blur strength based of the grayscale value of the mask, making the censor border less eye jarring. Warning CPU intensive.Pixelate
: Pixelated Mosaic effect.Fill color
: Fill a specified colorNo censor
: No filter is applied, but the NudeNet detection mask is still generated, use when you only want the mask but don’t want to censor the image.Disable
: Disable this extension for this workflow
Settings can be found under Settings
> NudeNet NSFW Censor
Enable Region censor for image generation
: enables/disables NudeNet censor for image generationSave a copy of the image before applying censor
: Save a copy of the image before applying censorSave censor mask
: Save the mask generated by NudeNetGeneration censor filter
: censor filter used for the final generated imageLive preview censor filter
: censor filter used duringLive preview
Extras censor filter
: the default censor filter used forExtras tab
Mask shape
: the mask shape applied on the detected regionsRectangle round radius
: controls the corner rounding radius whenMask shape
isRounded rectangle
-
- different ranges of value have different meaning
-
- [0, 1]: round ratio, 0.5 will round 50%, round radius will scale with the mask size
-
- (0, inf): round unit, round radius will scale with the image size
-
- (-inf, 0): absolute pixel, round radius will absolute value in pixels
-
- note: due to a bug with Pillow 9.5.0
Rounded rectangle
can fail to draw the mask
- note: due to a bug with Pillow 9.5.0
-
Blur strength
: Controls the blur strength forGaussian Blur
andVariable blur
. -
Mask blend strength
: applies toGaussian Blur
,Pixelate
,Fill color
apply blur to the detected mask, softening the censor border, if the value is too high the censor area might be transparent. -
Mask blend strength - Variable blur
: controls the size of the censor transition border Apply blur to the detected mask, grayscale value is used to control the strength blur. -
Blur strength curve - Variable blur
: Controls the blur strength gradient. -
- Value range [0, 6]
-
- 0: No blur
-
- 3: linear strength
-
- 4: linear with mask grayscale value
-
- 6: Entire image Max blur
-
Pixelation factor
: Controls pixelation strength -
Fill color
: Fill the detected region with this color
-
Categories to be censored
: NudeNet has 18 categories of body parts
Select which you wish to censor, each type has three values that you can adjustthreshold
horizontal multiplier
andvertical multiplier
-
threshold
: confidence threshold of when the detected region is used
typically a threshold of 0.25~0.5 should be a good range to reliably detect a category,
setting this to a high value means that it will only trigger censoring when it's more confident, setting it to1
is the same as disabling a category, on the other hand setting a low value would make censoring easier to trigger but also more chance of erroneously detecting regions -
horizontal multiplier
andvertical multiplier
: to compensate NudeNet's detection often is off-centered or does not cover the entire body part, the origin NudeNet detected region can be enlarged byhorizontal multiplier
andvertical multiplier
expanding the masked area covering a larger region.
List of NudeNet categories
Anus covered
Anus exposed
Armpits covered
Armpits exposed
Belly covered
Belly exposed
Buttocks covered
Buttocks exposed
Face female
Face male
Feet covered
Feet exposed
Female breast covered
Female breast exposed
Female genitalia covered
Female genitalia exposed
Male breast exposed
Male genitalia exposed
-
Non-Maximum Suppression threshold
: Discard overlapping detected regions, -
- set to 1 disables NMS note that NMS is performed prior to the adjustment of the detected regions
-
Print detection info in terminal
: Print info about detected mask regions, used for tweaking values, does not work when mask shape is set toEntire image
/nudenet/censor
- all parameters are optional, if not specified it will use the parameter configured in the settings, if they configuration already configured in the settings then the payload can be just the
input_image
alone enable_nudenet
is enabled by default- if no censoring is apply to the image then image will return
None
from PIL import Image
import requests
import base64
import io
image_path = r"input_image.png"
with open(image_path, 'rb') as image_file:
base64_image = base64.b64encode(image_file.read()).decode('utf-8')
image_path_mask = r"input_custom_mask.png"
with open(image_path_mask, 'rb') as image_file:
base64_image_mask = base64.b64encode(image_file.read()).decode('utf-8')
payload = {
"input_image": base64_image, # the image you wish to censor
"input_mask": base64_image_mask, # optional, if used will be combined with the NudeNet mask
"enable_nudenet": True, # enable NudeNet detect and generate the censor mask
"output_mask": True, # return the generated mask
"filter_type": "Variable blur", # the type of filter that will be used for censoring the image
"blur_radius": 10, # control the strength of gaussian blur when using "Variable blur" or "Gaussian blur"
"blur_strength_curve": 3, # control the blur strength gradient for "Variable blur"
"pixelation_factor": 5, # the pixelation factor when using "Pixelate"
"fill_color": "#000000", # the fill color when using "Fill color"
"mask_shape": "Ellipse", # the shape of the masked NudeNet regions
"mask_blend_radius": 10, # the blurring of the combined NudeNet and input_mask before censoring is applied to the input_image
"rectangle_round_radius": 0, # controls corner the rounding radius when mask_shape is "Rounded rectangle"
"nms_threshold": 0.5, # Non-Maximum Suppression threshold of the NudeNet detected regions
# the following three list of 18 float configures which category is censored
# the confidence threshold of each category for it to be censored
# and the amount that each detected regions will be expanded in horizontal and vertical direction
# each element in the list correspond to one NudeNet label, the order can be found below in Default category configuration or on webui's api "/docs" page
# confidence thresholds float [0, 1] when set to 1 disables this category
# this example below censors [Female_breast_exposed, Female_genitalia_exposed, Anus_exposed, Male_genitalia_exposed]
"thresholds": [1, 1, 1, 0.25, 0.25, 1, 0.25, 1, 1, 1, 1, 1, 1, 1, 0.25, 1, 1, 1],
# expand horizontal / vertical, float [0, inf]
"expand_horizontal": [1, 1, 1, 2.50, 2.50, 1, 2.50, 1, 1, 1, 1, 1, 1, 1, 2.00, 1, 1, 1],
"expand_vertical": [1, 1, 1, 1.00, 1.50, 1, 1.75, 1, 1, 1, 1, 1, 1, 1, 1.00, 1, 1, 1],
}
response = requests.post(url=f'http://localhost:7860/nudenet/censor', json=payload)
if response.status_code == 200:
response = response.json()
if response['image']:
Image.open(io.BytesIO(base64.b64decode(response['image']))).show()
if response['mask']:
Image.open(io.BytesIO(base64.b64decode(response['mask']))).show()
nudenet_labels_dict = {
# Category_name: [threshold, horizontal_multiplier, vertical_multiplier ]
'Female_genitalia_covered': [0.25, 2, 1],
'Face_female': [0.25, 1.5, 1.5],
'Buttocks_exposed': [0.25, 1, 1.25],
'Female_breast_exposed': [0.25, 2.5, 1],
'Female_genitalia_exposed': [0.25, 2.5, 1.5],
'Male_breast_exposed': [0.25, 1.5, 1.5],
'Anus_exposed': [0.25, 2.5, 1.75],
'Feet_exposed': [0.25, 1, 1],
'Belly_covered': [0.25, 1, 1],
'Feet_covered': [0.25, 1, 1],
'Armpits_covered': [0.25, 1, 1],
'Armpits_exposed': [0.25, 1, 1],
'Face_male': [0.25, 1.5, 1.5],
'Belly_exposed': [0.25, 2, 1.5],
'Male_genitalia_exposed': [0.25, 2, 1],
'Anus_covered': [0.25, 1, 1],
'Female_breast_covered': [0.25, 2.5, 1.5],
'Buttocks_covered': [0.25, 1, 1],
}