Products

SIGN UPLOG IN
Nudity Detection

Models / Gore & Disgusting content Detection

Gore & Disgusting content Detection BETA

This page describes version 2.0 of Gore Detection. The previous version is here.

Overview

The Gore & Disgusting model helps you determine if an image or video contains gore, horrific or disgusting imagery such as blood, guts, wounds, corpses, skulls and more.

The output of the model is provided in 10 gore classes to help you determine what kind of depiction is in the image or video, and 3 type classes:

Gore classes Very bloodyvery_bloody
Slightly bloodyslightly_bloody
Body organbody_organ
Serious injuryserious_injury
Superficial injurysuperficial_injury
Corpsecorpse
Skullskull
Unconsciousunconscious
Body wastebody_waste
Otherother
Gore typeAnimated goreanimated
Fake gorefake
Real gorereal

Related models

The following 3 models can provide a useful complement to the gore model:

Gore classes

  • Very bloody: Photos and illustrations with large amounts of blood or bleeding
    gore.classes.very_bloody
    • Open wounds
    • Large amounts of blood or blood splatters
    • Profuse bloody noses or mouths
    • Bleeding from major injuries

    This does not include blood in a medical context, such as blood tests, blood donations, or blood transfusions.

  • Slightly bloody: Photos and illustrations with small amounts of blood or bleeding
    gore.classes.slightly_bloody
    • Slightly bleeding nose
    • Small injuries
    • Small amounts of blood on surfaces

    This does not include blood in a medical context, such as blood tests, blood donations, or blood transfusions.

  • Body organ:
    gore.classes.body_organ
    • Human organs (such as heart, lungs, kidneys, instentine, liver) visible inside the body due to deep cuts or wounds, or during medical surgery
    • Preserved human body organs such as brains or lungs, typically used as artifacts in museums or for educational purposes
  • Serious injury: Major injuries, that typically require urgent care
    gore.classes.serious_injury
    • Gunshot or stab wounds
    • Deep cuts, exposing blood or organs
    • Loss of limbs or fingers with bleeding
    • Animal attacks and bites that have not healed
  • Superficial injury: Minor injuries that typically do not require urgent care
    gore.classes.superficial_injury
    • Small cuts
    • Scratches
    • Small injuries with limited bleeding
  • Corpse: Human corpses
    gore.classes.corpse
    • Human bodies with enough contextual evidence to assume the person is dead

    See the unconscious class for cases where the person is assumed to be alive but unconscious. See the serious_injury class for graphic injuries where the person is visibly alive.

  • Skull: Human skull
    gore.classes.skull
    • Human skull
    • Human skeleton, with a fully or partly visible skull
  • Unconscious: Person who, based on contextual evidence can be assumed to be alive but unconscious
    gore.classes.unconscious
    • Person lying down in a place not typically used for sleeping (i.e. not in a bed, tent or sofa)
    • Person lying down in a position that evokes unconsciousness (i.e. non-natural position)

    This does not include people visibly dead (see corpse class) or having injuries (see serious_injury class).

  • Body waste:
    gore.classes.body_waste
    • Urine: person urinating, with urine being visible
    • Feces: human feces and animal feces when their aspect is similar to human feces
    • Vomit: person vomiting, or in a context that evokes an intention to vomit (such as kneeling over a toilet seat)
  • Other: Other situations
    gore.classes.other
    • Dead or suffering animals (except for insects and small fishes)
    • Close-ups of eyes or mouths
    • Blood displayed in a medical context, such as in a pouch or in a test tube
    • Scars with no visible bleeding (i.e. healed scars)
    • Symbols and locations that typically evoke death: cemeteries, graves
    • Illustrations of horrific or frightening characters, that typically convey evil or danger

    Please reach out if you need to differentiate between different aspects within this other class.

Gore type

The Gore type section can be used to differentiate fake gore content from real gore content and gore content appearing in art or illustrations.

  • Animated gore: Illustrations containing gore depictions
    gore.type.animated
    • Gore appearing in drawings, paintings, illustrations
    • Gore appearing in animations and cartoons
    • Gore appearing in digital art and computer-generated designs
    • Gore appearing in video game graphics
  • Fake gore: Photos with fake gore displays
    gore.type.fake
    • Blood that appears to be fake based on context
    • Costumes and accessories that mimick death or injuries, such as in a Halloween setting
    • Face filters that evoke scars, blood or injuries
  • Real gore: Real photographic gore depictions
    gore.type.real
    • Gore imagery in real photos, where there is no evidence that the gore content is fake

    Realistic movie scenes will be flagged as real gore and not as fake gore.

Use the model (images)

If you haven't already, create an account to get your own API keys.

Detect gore & disgusting content

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.

Option 1: Send image URL

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=gore-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': 'gore-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' => 'gore-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': 'gore-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);
});

See request parameter description

ParameterTypeDescription
mediabinaryimage to analyze
modelsstringcomma-separated list of models to apply
api_userstringyour API user id
api_secretstringyour API secret

Option 2: Send raw image

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=gore-2.0' \
    -F 'api_user={api_user}' \
    -F 'api_secret={api_secret}'


# this example uses requests
import requests
import json

params = {
  'models': 'gore-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' => 'gore-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', 'gore-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);
});

See request parameter description

ParameterTypeDescription
mediabinaryimage to analyze
modelsstringcomma-separated list of models to apply
api_userstringyour API user id
api_secretstringyour API secret

API response

The API will then return a JSON response with the following structure:

                  
                  
{
  "status": "success",
  "request": {
    "id": "req_glra5CGwKiJOgQIKG2xMe",
    "timestamp": 1716968170.907796,
    "operations": 1
  },
  "gore": {
    "prob": 0.01,
    "classes": {
      "very_bloody": 0.01,
      "slightly_bloody": 0.01,
      "body_organ": 0.01,
      "serious_injury": 0.01,
      "superficial_injury": 0.01,
      "corpse": 0.01,
      "skull": 0.01,
      "unconscious": 0.01,
      "body_waste": 0.01,
      "other": 0.01
    },
    "type": {
      "animated": 0.01,
      "fake": 0.01,
      "real": 0.01
    }
  },
  "media": {
    "id": "med_glra5aI8HdK23yzRwsWjs",
    "uri": "https://sightengine.com/assets/img/examples/example-fac-1000.jpg"
  }
}


              

Use model (Videos)

Detecting Gore & Disgusting content in videos

Option 1: Short video

Here's how to proceed to analyze a short video (less than 1 minute):


curl -X POST 'https://api.sightengine.com/1.0/video/check-sync.json' \
  -F 'media=@/path/to/video.mp4' \
  -F 'models=gore-2.0' \
  -F 'api_user={api_user}' \
  -F 'api_secret={api_secret}'


# this example uses requests
import requests
import json

params = {
  # specify the models you want to apply
  'models': 'gore-2.0',
  'api_user': '{api_user}',
  'api_secret': '{api_secret}'
}
files = {'media': open('/path/to/video.mp4', 'rb')}
r = requests.post('https://api.sightengine.com/1.0/video/check-sync.json', files=files, data=params)

output = json.loads(r.text)


$params = array(
  'media' => new CurlFile('/path/to/video.mp4'),
  // specify the models you want to apply
  'models' => 'gore-2.0',
  'api_user' => '{api_user}',
  'api_secret' => '{api_secret}',
);

// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/video/check-sync.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/video.mp4'));
// specify the models you want to apply
data.append('models', 'gore-2.0');
data.append('api_user', '{api_user}');
data.append('api_secret', '{api_secret}');

axios({
  method: 'post',
  url:'https://api.sightengine.com/1.0/video/check-sync.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);
});

See request parameter description

ParameterTypeDescription
mediabinaryimage to analyze
modelsstringcomma-separated list of models to apply
intervalfloatframe interval in seconds, out of 0.5, 1, 2, 3, 4, 5 (optional)
api_userstringyour API user id
api_secretstringyour API secret

Option 2: Long video

Here's how to proceed to analyze a long video. Note that if the video file is very large, you might first need to upload it through the Upload API.


curl -X POST 'https://api.sightengine.com/1.0/video/check.json' \
  -F 'media=@/path/to/video.mp4' \
  -F 'models=gore-2.0' \
  -F 'callback_url=https://yourcallback/path' \
  -F 'api_user={api_user}' \
  -F 'api_secret={api_secret}'


# this example uses requests
import requests
import json

params = {
  # specify the models you want to apply
  'models': 'gore-2.0',
  # specify where you want to receive result callbacks
  'callback_url': 'https://yourcallback/path',
  'api_user': '{api_user}',
  'api_secret': '{api_secret}'
}
files = {'media': open('/path/to/video.mp4', 'rb')}
r = requests.post('https://api.sightengine.com/1.0/video/check.json', files=files, data=params)

output = json.loads(r.text)


$params = array(
  'media' => new CurlFile('/path/to/video.mp4'),
  // specify the models you want to apply
  'models' => 'gore-2.0',
  // specify where you want to receive result callbacks
  'callback_url' => 'https://yourcallback/path',
  'api_user' => '{api_user}',
  'api_secret' => '{api_secret}',
);

// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/video/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/video.mp4'));
// specify the models you want to apply
data.append('models', 'gore-2.0');
// specify where you want to receive result callbacks
data.append('callback_url', 'https://yourcallback/path');
data.append('api_user', '{api_user}');
data.append('api_secret', '{api_secret}');

axios({
  method: 'post',
  url:'https://api.sightengine.com/1.0/video/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);
});

See request parameter description

ParameterTypeDescription
mediabinaryimage to analyze
callback_urlstringcallback URL to receive moderation updates (optional)
modelsstringcomma-separated list of models to apply
intervalfloatframe interval in seconds, out of 0.5, 1, 2, 3, 4, 5 (optional)
api_userstringyour API user id
api_secretstringyour API secret

Option 3: Live-stream

Here's how to proceed to analyze a live-stream:


curl -X GET -G 'https://api.sightengine.com/1.0/video/check.json' \
    --data-urlencode 'stream_url=https://domain.tld/path/video.m3u8' \
    -d 'models=gore-2.0' \
    -d 'callback_url=https://your.callback.url/path' \
    -d 'api_user={api_user}' \
    -d 'api_secret={api_secret}'


# if you haven't already, install the SDK with 'pip install sightengine'
from sightengine.client import SightengineClient
client = SightengineClient('{api_user}','{api_secret}')
output = client.check('gore-2.0').video('https://domain.tld/path/video.m3u8', 'https://your.callback.url/path')


// if you haven't already, install the SDK with 'composer require sightengine/client-php'
use \Sightengine\SightengineClient;
$client = new SightengineClient('{api_user}','{api_secret}');
$output = $client->check(['gore-2.0'])->video('https://domain.tld/path/video.m3u8', 'https://your.callback.url/path');


// if you haven't already, install the SDK with 'npm install sightengine --save'
var sightengine = require('sightengine')('{api_user}', '{api_secret}');
sightengine.check(['gore-2.0']).video('https://domain.tld/path/video.m3u8', 'https://your.callback.url/path').then(function(result) {
    // The API response (result)
}).catch(function(err) {
    // Handle error
});

See request parameter description

ParameterTypeDescription
stream_urlstringURL of the video stream
callback_urlstringcallback URL to receive moderation updates (optional)
modelsstringcomma-separated list of models to apply
intervalfloatframe interval in seconds, out of 0.5, 1, 2, 3, 4, 5 (optional)
api_userstringyour API user id
api_secretstringyour API secret

Moderation result

The Moderation result will be provided either directly in the request response (for sync calls, see below) or through the callback URL your provided (for async calls).

Here is the structure of the JSON response with moderation results for each analyzed frame under the data.frames array:

            
                  
{
  "status": "success",
    "request": {
    "id": "req_gmgHNy8oP6nvXYaJVLq9n",
    "timestamp": 1717159864.348989,
    "operations": 21
  },
  "data": {
  "frames": [
    {
      "info": {
        "id": "med_gmgHcUOwe41rWmqwPhVNU_1",
        "position": 0
      },
      "gore": {
        "prob": 0.01,
        "classes": {
          "very_bloody": 0.01,
          "slightly_bloody": 0.01,
          "body_organ": 0.01,
          "serious_injury": 0.01,
          "superficial_injury": 0.01,
          "corpse": 0.01,
          "skull": 0.01,
          "unconscious": 0.01,
          "body_waste": 0.01,
          "other": 0.01
        },
        "type": {
          "animated": 0.01,
          "fake": 0.01,
          "real": 0.01
        }
       },
      },
      ...
    ]
  },
  "media": {
    "id": "med_gmgHcUOwe41rWmqwPhVNU",
    "uri": "yourfile.mp4"
  },
}


            

You can use the classes under the gore object to determine the gore level of the video.

Any other needs?

See our full list of Image/Video models for details on other filters and checks you can run on your images and videos. You might also want to check our Text models to moderate text-based content: messages, reviews, comments, usernames...

Was this page helpful?