Detect AI-Generated Images in Python
Create Your Own AI-Image Detector in Python
AI can now generate images that look almost real. Faces, landscapes, product photos, even news images can be produced in seconds. As these tools get better, a simple question keeps coming up: how do we tell what’s real and what isn’t?
This article walks through a practical, code-based approach to detecting AI-generated images using classic image analysis and machine learning. No deep learning models. No massive datasets. Just simple features, a Random Forest, and a clear idea of what we’re measuring.
Why AI Images Leave Traces
Even the best AI-generated images tend to share subtle patterns. They may look perfect at a glance, but statistically they behave a little differently than real photos.
Some common differences include:
Unnatural color distributions
Overly smooth or inconsistent noise patterns
Edge structures that don’t match real-world optics
The trick is not to see these differences like a human, but to measure them numerically.
The Core Idea
Instead of training a large neural network, this approach extracts a small set of handcrafted features from each image and feeds them into a Random Forest classifier.
Each image is reduced to a feature vector that describes:
Color behavior
Edge density
Noise consistency
These features are fast to compute and easy to interpret.
Feature Extraction Explained
The heart of the system is the extract_features function. Here’s what it does, step by step.
Color Statistics
mean_color = arr.mean(axis=(0, 1))
std_color = arr.std(axis=(0, 1))This captures the average color and color variation across the image.
AI-generated images often show:
Unusually even color distributions
Lower or oddly shaped variance compared to real photos
These six numbers alone already carry useful information.
Edge Density
edges = img.filter(ImageFilter.FIND_EDGES)
edge_density = edge_arr.mean()Edges represent transitions in texture and structure.
Real photos tend to have:
Natural edge patterns from lenses and sensors
AI images sometimes produce:
Over-sharpened or inconsistent edges
Missing micro-details in textured areas
Measuring average edge intensity helps surface those differences.
Noise Estimation
shifted = np.roll(arr, 1, axis=0)
noise_estimate = np.abs(arr - shifted).mean()This is a simple way to estimate high-frequency noise.
Real cameras introduce sensor noise that’s spatially consistent. AI images often look clean, but the “noise” they produce doesn’t behave like real sensor noise.
This single value often becomes one of the strongest indicators.
Final Feature Vector
All features are combined into one array:
return np.hstack([mean_color, std_color, edge_density, noise_estimate])Each image becomes a compact numeric fingerprint.
Training the Classifier
First, download the AI-generated and real images here.
The training setup is straightforward.
real_images = glob.glob(”.../REAL/*.jpg”)
ai_images = glob.glob(”.../AI/*.jpg”)Real photos are labeled
0AI-generated images are labeled
1
A Random Forest is used because it:
Handles small feature sets well
Captures non-linear relationships
Requires minimal tuning
model = RandomForestClassifier(n_estimators=200)
model.fit(X, y)Once trained, the model learns which feature patterns are more likely to come from AI-generated images.
Making Predictions
Prediction is simple and fast.
def predict(image_path):
features = extract_features(image_path).reshape(1, -1)
label = model.predict(features)[0]
return “AI-Generated” if label == 1 else “Real Photo”This makes the system easy to integrate into:
Moderation pipelines
Image verification tools
Research experiments
Limitations to Keep in Mind
This is not a silver bullet.
Performance depends on the quality and diversity of your dataset
New AI models may reduce detectable artifacts
High-quality post-processed AI images can fool simple detectors
In real-world use, this approach works best as one signal among many, not the only line of defense.
Use the following code to create the experiment.
import numpy as np
from PIL import Image, ImageFilter
from sklearn.ensemble import RandomForestClassifier
import glob
def extract_features(path):
img = Image.open(path).convert(”RGB”)
arr = np.array(img) / 255.0
# Color statistics
mean_color = arr.mean(axis=(0, 1))
std_color = arr.std(axis=(0, 1))
# Edge density
edges = img.filter(ImageFilter.FIND_EDGES)
edge_arr = np.array(edges) / 255.0
edge_density = edge_arr.mean()
# Noise estimate (high-frequency variance)
shifted = np.roll(arr, 1, axis=0)
noise_estimate = np.abs(arr - shifted).mean()
return np.hstack([mean_color, std_color, edge_density, noise_estimate])
# --- TRAINING ---
real_images = glob.glob(”C:/Users/Desktop/REAL/*.jpg”)
ai_images = glob.glob(”C:/Users/Desktop/AI/*.jpg”)
X = []
y = []
for p in real_images:
X.append(extract_features(p))
y.append(0) # real
for p in ai_images:
X.append(extract_features(p))
y.append(1) # AI
X = np.array(X)
y = np.array(y)
model = RandomForestClassifier(n_estimators=200)
model.fit(X, y)
print(”Training complete.”)
# --- PREDICTION TEST ---
def predict(image_path):
features = extract_features(image_path).reshape(1, -1)
label = model.predict(features)[0]
return “AI-Generated” if label == 1 else “Real Photo”
# Example:
print(predict(”C:/Users/Desktop/TEST/Nanobanana_generation.png”))When running the last line of code, and testing the algorithm on a Bloomberg terminal image I generated from Nano Banana Pro, I get the following result:
AI-GeneratedSuccess!
The Signal Beyond 🚀
From classic tools that have stood the test of time to fresh innovations like multi-market RSI heatmaps, COT reports, seasonality, and pairs trading recommendation system, the new report is designed to give you a sharper edge in navigating the markets.
Free trial available.




