Nudity Detection
Deprecated nudity-2.0Detect explicit, suggestive, and NSFW content in images and videos with 15 nudity classes.
Overview
The Advanced Nudity Detection API is an A.I.-based service to determine the nudity content of images and videos. There are 15 nudity classes and 3 context classes that you can use to automatically understand the content of your images/videos, and set the appropriate rules.
Here are the 15 nudity classes starting with the most explicit ones:
| Explicit classes | Sexual Activity | sexual_activity |
| Sexual Display | sexual_display | |
| Sextoy | sextoy | |
| Erotica | erotica | |
| Suggestive classes | Female underwear | lingerie |
| Male underwear | male_underwear | |
| Very revealing cleavage | cleavage_categories.very_revealing | |
| Revealing cleavage | cleavage_categories.revealing | |
| Very revealing male chest | male_chest_categories.very_revealing | |
| Revealing male chest | male_chest_categories.revealing | |
| Slightly revealing male chest | male_chest_categories.slightly_revealing | |
| Bikini | bikini | |
| Miniskirt | miniskirt | |
| Other suggestive scene or pose | other | |
| Safe | None | none |
Here are the 3 context classes that can be used to further refine your filtering:
| Context classes | Sea, lake, pool | sea_lake_pool |
| Other outdoor | outdoor_other | |
| Other indoor | indoor_other |
Explicit classes
- Sexual activity: Actual or simulated sexual activity with exposed nudity
nudity.sexual_activity- Sexual intercourse with clear nudity, including genital-genital and oral-genital activity
- Clear masturbation
- Direct touching of genitals
- Sex toys involved in sexual activity: penetrating mouth, anus or genitals. Includes dildos, sex dolls, fleshlights, plugs
- Semen or vaginal fluids on faces, on body parts, on sextoys or in condoms
- Sexual display: Explicit exposure of genitals/sexual organs
nudity.sexual_display- Female genitals: exposed genitalia, vulva or anus, either directly visible or through transparent, see-through or sheer clothing
- Male genitals, male penises, both erect and non-erect, testicles, either directly visible or through transparent, see-through or sheer clothing
- The above applies to transgender individuals
- Sextoy: Sex toys not in use
nudity.sextoy- Dildos, plugs and beads
- Sex dolls, fleshlights
- This class is for displays of sextoys that are not in use, such as when shown in product listings. Scenes with sex toys that are being used as part of sexual activities will be flagged under the sexual_activity class
- Erotica: Exposure of breasts, nude buttocks or the pubic region
nudity.erotica- Nude female breasts, female breasts with visible nipples or areola
- Nude buttocks, both male and female, in a non-sexual setting
- Pubic region, pubic hair, female crotch region or area around genitals with no genitals visible
- Genitals clearly visible through opaque clothes or underwear
- Women or men in underwear with a sexual pose that emphasizes their genital area, without the genitals being visible
Suggestive classes
- Female underwear and lingerie
nudity.suggestive_classes.lingerie- Women wearing visible underwear bottoms: panties, thongs, etc, with or without lace, including women wearing male underwear
- Women wearing visible underwear tops: bras, corsets transparent around the belly, with or without lace (sports bras are excluded)
- Women wearing suggestive nightdresses or bodysuits
- Male underwear
nudity.suggestive_classes.male_underwear- Men wearing boxers, briefs, jockstraps, thongs
- Bare male chest
nudity.suggestive_classes.male_chest- Shirtless men, men where some or most of the area between the waist and shoulders is visible (bare chest, topless, nude torso, etc.) or where the back is visible
- Men lifting the shirt to show the belly or chest area
- Men wearing see-through, sheer, or mesh clothing with torso visible
- Men wearing clothes exposing a large part of the nipple or belly area, such as crop-tops or very deep tank-tops
- You can filter shirtless men based on context, for instance to allow bare chests at beaches or pools, but not in other places
- Note that men wearing regular tank-tops or stringers are considered safe and are not flagged in this category
- Further subclasses are available to determine how much of the torso or back is visible:
- Very revealing nudity.suggestive_classes.male_chest_categories.very_revealing
- Revealing nudity.suggestive_classes.male_chest_categories.revealing
- Slightly revealing nudity.suggestive_classes.male_chest_categories.slightly_revealing
very_revealing revealing slightly_revealing safeThe rating depends on which parts of the torso or back are visible, as shown on this model. - Suggestive cleavage / neckline
nudity.suggestive_classes.cleavage- Women wearing a top with a suggestive cleavage / neckline, but where the areola and nipples are not visible
- Further subclasses are available to determine how much of the cleavage is visible:
- Very revealing nudity.suggestive_classes.cleavage_categories.very_revealing
- Revealing nudity.suggestive_classes.cleavage_categories.revealing
erotica very_revealing revealing safeThe rating depends on which parts cleavage are visible, as shown on this model. If the nipple (in bright orange) were visible then the rating would be erotica - Bikini
nudity.suggestive_classes.bikini- Women wearing bikinis, microbikinis or two-piece swimsuits
- You can filter bikinis based on context, for instance to allow bikinis at beaches or pools, but not indoors
- Miniskirt
nudity.suggestive_classes.miniskirt- Women wearing short or very short skirts, that end above the middle of the thigh
- Other Suggestive poses or scenes
nudity.suggestive_classes.other- Suggestive poses
- Suggestive zooms
- Schematic representations of sexual positions. Detailed depictions would fall under the sexual_activity category
- None:
This class includes all cases where none of the above suggestive or explicit situations occur. As an example, this would include situations such as:
nudity.none- Exposed arms, legs in a non-sexual setting
- People hugging or making non-sexual contact
- People kissing (mouth-mouth)
- People wearing tank tops or stringers without nipples visible
- Panties, thongs, bras, swimwear shown but not worn by a person (such as on the floor)
- Women in one-piece swimsuits
- Underwear worn such that only the waistband is visible
- Unclothed dolls with no sexual organs, such as Barbie dolls
Context
Some moderation decisions need to be based on context. As an example, shirtless men or women in bikinis might be moderated differently if they are at the beach or in their bathroom.
To help you perform such fine-grained decisions, additional context information is available with the following classes:
- Beach, sea, lake, swimming pool
nudity.context.sea_lake_pool- Scenes at the beach, near or on the sea, near or on lakes
- Scenes near or in swimming pools whether outdoor or indoor
- Other outdoor locations
nudity.context.outdoor_other- Other outdoor locations such as in parks, gardens, cities, nature
- Other indoor locations
nudity.context.indoor_other- Other indoor locations such as private homes and public buildings
Understanding the scoring
The scores are returned in a way that puts the emphasis on the most explicit class corresponding to the image/video. As an example, the class sexual_display shouldn't be understood as "is there sexual display in the image?" but rather "is there sexual display AND no sexual activity in the image?".
As an illustration, an image of a woman in lingerie will score highly on the suggestive class. But if that woman is engaged in a sexual act, the API will focus on the most explicit class (sexual_activity) and return a very low score for the less explicit one (suggestive and suggestive.lingerie), because the image as a whole is explicit and should not be labelled as simply "suggestive" or "lingerie".
Code Examples
The Nudity Detection model works with Images, GIFs and Videos. Most types and formats of images or videos are supported.
Getting started
If you haven't already, create an account to get your own API keys.
Detecting nudity
Let's say you want to moderate the following image:
You can either share a URL to the image, or upload the raw binary image.
URL-based
Here's how to proceed if you choose to share the image URL:
curl -X GET -G 'https://api.sightengine.com/1.0/check.json' \
-d 'models=nudity-2.0' \
-d 'api_user={api_user}&api_secret={api_secret}' \
--data-urlencode 'url=https://sightengine.com/assets/img/examples/example-fac-1000.jpg'
# this example uses requests
import requests
import json
params = {
'url': 'https://sightengine.com/assets/img/examples/example-fac-1000.jpg',
'models': 'nudity-2.0',
'api_user': '{api_user}',
'api_secret': '{api_secret}'
}
r = requests.get('https://api.sightengine.com/1.0/check.json', params=params)
output = json.loads(r.text)
$params = array(
'url' => 'https://sightengine.com/assets/img/examples/example-fac-1000.jpg',
'models' => 'nudity-2.0',
'api_user' => '{api_user}',
'api_secret' => '{api_secret}',
);
// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/check.json?'.http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$output = json_decode($response, true);
// this example uses axios
const axios = require('axios');
axios.get('https://api.sightengine.com/1.0/check.json', {
params: {
'url': 'https://sightengine.com/assets/img/examples/example-fac-1000.jpg',
'models': 'nudity-2.0',
'api_user': '{api_user}',
'api_secret': '{api_secret}',
}
})
.then(function (response) {
// on success: handle response
console.log(response.data);
})
.catch(function (error) {
// handle error
if (error.response) console.log(error.response.data);
else console.log(error.message);
});
Raw image-based
Here's how to proceed if you choose to upload the raw image:
curl -X POST 'https://api.sightengine.com/1.0/check.json' \
-F 'media=@/path/to/image.jpg' \
-F 'models=nudity-2.0' \
-F 'api_user={api_user}' \
-F 'api_secret={api_secret}'
# this example uses requests
import requests
import json
params = {
'models': 'nudity-2.0',
'api_user': '{api_user}',
'api_secret': '{api_secret}'
}
files = {'media': open('/path/to/image.jpg', 'rb')}
r = requests.post('https://api.sightengine.com/1.0/check.json', files=files, data=params)
output = json.loads(r.text)
$params = array(
'media' => new CurlFile('/path/to/image.jpg'),
'models' => 'nudity-2.0',
'api_user' => '{api_user}',
'api_secret' => '{api_secret}',
);
// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/check.json');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($ch);
curl_close($ch);
$output = json_decode($response, true);
// this example uses axios and form-data
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
data = new FormData();
data.append('media', fs.createReadStream('/path/to/image.jpg'));
data.append('models', 'nudity-2.0');
data.append('api_user', '{api_user}');
data.append('api_secret', '{api_secret}');
axios({
method: 'post',
url:'https://api.sightengine.com/1.0/check.json',
data: data,
headers: data.getHeaders()
})
.then(function (response) {
// on success: handle response
console.log(response.data);
})
.catch(function (error) {
// handle error
if (error.response) console.log(error.response.data);
else console.log(error.message);
});
API response
The API will then return a JSON response with the following structure:
{
"status": "success",
"request": {
"id": "req_1SJJxJjUHnSVWreApx9fF",
"timestamp": 1693574119.571633,
"operations": 1
},
"nudity": {
"sexual_activity": 0.01,
"sexual_display": 0.01,
"erotica": 0.01,
"sextoy": 0.01,
"suggestive": 0.01,
"suggestive_classes": {
"bikini": 0.01,
"cleavage": 0.01,
"cleavage_categories": {
"very_revealing": 0.01,
"revealing": 0.01,
"none": 0.99
},
"lingerie": 0.01,
"male_chest": 0.01,
"male_chest_categories": {
"very_revealing": 0.01,
"revealing": 0.01,
"slightly_revealing": 0.01,
"none": 0.99
},
"male_underwear": 0.01,
"miniskirt": 0.01,
"other": 0.01
},
"none": 0.99,
"context": {
"sea_lake_pool": 0.01,
"outdoor_other": 0.99,
"indoor_other": 0.01
}
},
"media": {
"id": "med_1SJJEFuLqeSedThQjhNoS",
"uri": "https://sightengine.com/assets/img/examples/example-fac-1000.jpg"
}
}
You can use the classes under the nudity object to determine the nudity level of the image. In the above example the winning class is nudity.none with a confidence of 0.99, meaning that the API is very confident in its classification.