Detecting AI-Generated Images Using Entropy Analysis
Professional researchers (and myself) have been exploring ways to distinguish AI-generated images from real ones every since they took over certain social media. In this blog post I present a way to detect AI-generated pixel images, by analyzing the randomness of each RGB channel using local entropy calculations.
The Process
- Reading the Image: The image is loaded, and its RGB channels are accessed individually.
- Calculating Local Entropy: For each channel (Red, Green, Blue), the local entropy is computed. In detail: We create a circular mask of a specified radius, then calculate Shannon entropy for each pixel in the area. This measures the randomness or unpredictability of pixel values in a neighborhood.
- Comparing Entropy Across Channels: At every pixel, the entropy values of the three channels are compared. If the entropy is the same across all channels within a specified tolerance, that pixel is marked.
- Highlighting Matching Pixels: These pixels are highlighted in red on the image. This visual representation helps in identifying patterns.
Code Example
Below is a Python code example using Matplotlib and scikit-image to perform the above process:
import numpy as np
import matplotlib.pyplot as plt
from skimage import io, filters, img_as_ubyte
from skimage.morphology import disk
# Step 1: Reading the Image
image = io.imread('image.jpg')
# Ensure the image is in RGB format
if image.shape[2] == 4:
image = image[:, :, :3]
# Split the image into RGB channels
red_channel = image[:, :, 0]
green_channel = image[:, :, 1]
blue_channel = image[:, :, 2]
# Convert channels to uint8 if necessary
red_channel = img_as_ubyte(red_channel)
green_channel = img_as_ubyte(green_channel)
blue_channel = img_as_ubyte(blue_channel)
# Step 2: Calculating Local Entropy
radius = 5 # Neighborhood radius
selem = disk(radius)
entropy_red = filters.rank.entropy(red_channel, selem)
entropy_green = filters.rank.entropy(green_channel, selem)
entropy_blue = filters.rank.entropy(blue_channel, selem)
# Step 3: Comparing Entropy Across Channels
tolerance = 0.1
entropy_diff_rg = np.abs(entropy_red - entropy_green)
entropy_diff_rb = np.abs(entropy_red - entropy_blue)
entropy_diff_gb = np.abs(entropy_green - entropy_blue)
# Create a mask where entropy differences are within the tolerance
mask = (entropy_diff_rg < tolerance) & (entropy_diff_rb < tolerance) & (entropy_diff_gb < tolerance)
# Step 4: Highlighting Matching Pixels
highlighted_image = image.copy()
highlighted_image[mask] = [255, 0, 0] # Mark matching pixels in red
# Display the original and highlighted images
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(image)
ax[0].set_title('Original Image')
ax[0].axis('off')
ax[1].imshow(highlighted_image)
ax[1].set_title('Highlighted Image')
ax[1].axis('off')
plt.tight_layout()
plt.show()
AI/Diffusion Generated Image Example (generated with Stable Diffusion)
Note the strange block patterns in the sky and the shadows.
Real Image Example (my own image)
Interpreting the Results
- Real Images: In natural images, especially in uniform areas like skies or walls, the entropy across RGB channels tends to be similar. This results in large groups of matching pixels, which appear as cohesive red regions.
- AI-Generated Images: Diffusion models introduce more randomness, even in areas that should be uniform. This leads to many small, scattered red areas. The lack of large groups indicates the image may be AI-generated.
Why It Works
Diffusion models create images by adding and removing noise in a way that can leave subtle inconsistencies across color channels. By focusing on the entropy of each channel, these inconsistencies can be detected.
Easier Detection in Uniform Areas
This method is particularly effective for images with backgrounds or areas of the same color:
- Uniform Backgrounds: In real images, areas like clear skies, walls, or any uniformly colored surfaces have consistent texture and color, leading to similar entropy values across all RGB channels.
- Same Color Areas: Objects with solid colors exhibit minimal variations in pixel values. The local entropy in these areas is low and consistent across channels.
In AI-generated images, these uniform areas often contain slight variations and noise due to the generation process, causing discrepancies in entropy values between channels. This makes it easier to detect inconsistencies when analyzing images with large areas of uniform color.
Caveats
The effectiveness of this method heavily depends on the quality of the AI-generated images, compression algorithm and the complexity of the scenes. Heavy image compression, such as with jpg images, can hide AI generated images. In turn compression artefacts can also make the image seem AI generated when it is not.