In a world where synthetic media can be faked in seconds, TruthLens provides deterministic, physical, and statistical media forensics to fight back.
TruthLens is a full-stack digital media forensics platform that analyzes images and videos for synthetic AI generation or localized manipulation. Rather than relying on generic black-box classifiers, TruthLens evaluates physical sensor artifacts, statistical compression anomalies, 2D spectral frequency distributions, demosaicing patterns, and facial geometry β synthesized by an AI reasoning agent (llama-3.3-70b) into a transparent, evidence-backed verdict.
- π¬ Error Level Analysis (ELA) β Re-saves media at 90% and 95% JPEG quality to measure localized compression error variances and output JET heatmap overlays.
- π‘ Noise Residual & PRNU Analysis β Laplacian high-pass noise extraction detecting unnaturally smooth synthetic noise residuals vs physical sensor photon shot noise.
- β‘ 2D FFT & DCT Spectrum Analysis β Computes Discrete Cosine Transform radial energy drop-off and 2D FFT magnitude log-spectra to spot periodic generator grid artifacts.
- π§© CFA Bayer Demosaicing Analysis β Evaluates green-channel Bayer directional gradient correlations to distinguish physical camera sensor demosaicing from direct pixel synthesis.
- π€ InsightFace Facial Alignment β Detects, crops, and measures facial landmark ratios, symmetry, and eye alignment via InsightFace
buffalo_l. - π Perceptual Hashing & EXIF Forensics β Calculates 64-bit pHash signatures, checks camera EXIF metadata, IPTC/ICC headers, and flags suspicious stripping signals.
- π€ Groq LLM Reasoning Agent β Synthesizes quantitative metrics from all forensic signals via LangChain + Groq (
llama-3.3-70b-versatile) into an explainable verdict. - β‘ Real-time Streaming β WebSocket-powered live progress updates as each forensic engine finishes.
graph TD
subgraph Client["Next.js Frontend Client"]
UI["Upload Zone & Results Dashboard"]
WS_Client["WebSocket Telemetry Client"]
end
subgraph Backend["FastAPI Backend (uv Python Runtime)"]
API["POST /analyze Endpoint"]
WS_Server["WebSocket Manager (/ws/job_id)"]
Orchestrator["Async Pipeline Orchestrator"]
end
subgraph Engine["Physical & Statistical Forensics Suite"]
ELA["ELA Analyzer\n(JPEG Error Variance)"]
Noise["Noise Residual\n(PRNU Sensor Pattern)"]
Freq["Frequency Spectrum\n(2D FFT & DCT Energy)"]
CFA["CFA Demosaicing\n(Bayer Grid Variance)"]
Faces["InsightFace Geometry\n(Landmarks & Crop)"]
Hash["Perceptual Hashing\n(64-bit pHash)"]
Meta["Metadata Inspector\n(EXIF & Headers)"]
end
subgraph Intelligence["AI Reasoning & Synthesis Layer"]
Groq["Groq LLM Reasoning Agent\n(llama-3.3-70b-versatile)"]
end
UI -->|"1. Upload File"| API
API -->|"2. Job UUID"| UI
UI -->|"3. Connect WS"| WS_Client
WS_Client <-->|"Live Updates"| WS_Server
API -->|"4. Dispatch Task"| Orchestrator
Orchestrator --> ELA
Orchestrator --> Noise
Orchestrator --> Freq
Orchestrator --> CFA
Orchestrator --> Faces
Orchestrator --> Hash
Orchestrator --> Meta
ELA & Noise & Freq & CFA & Faces & Hash & Meta -->|"Structured Metrics"| Groq
Groq -->|"Confidence Verdict & Breakdown"| Orchestrator
Orchestrator -->|"Final Results Payload"| WS_Server
sequenceDiagram
autonumber
actor User as User / Client
participant Frontend as Next.js UI
participant Backend as FastAPI Server
participant Pipeline as Async Orchestrator
participant Analyzers as Forensic Modules (ELA/Noise/FFT/CFA/Faces)
participant Groq as Groq LLM Agent
User->>Frontend: Upload Media File
Frontend->>Backend: POST /analyze (multipart file)
Backend-->>Frontend: Return {"job_id": "<uuid>"}
Frontend->>Backend: Open WebSocket /ws/<job_id>
Backend-->>Frontend: Connection Established
Backend->>Pipeline: Dispatch run_pipeline(job_id, bytes)
par Concurrent Forensic Execution
Pipeline->>Analyzers: ELA Re-compression Variance
Pipeline->>Analyzers: Noise Residual & PRNU Analysis
Pipeline->>Analyzers: 2D FFT & DCT Radial Spectrum
Pipeline->>Analyzers: CFA Bayer Demosaicing Evaluation
Pipeline->>Analyzers: InsightFace Bounding Box & Alignment
Pipeline->>Analyzers: pHash & EXIF Metadata Extraction
end
Analyzers-->>Pipeline: Return ForensicSignalResults + Heatmap b64 maps
Pipeline-->>Frontend: Stream WebSocket step updates (done)
Pipeline->>Groq: Send Forensic Signals JSON Payload
Groq-->>Pipeline: Return Verdict, Confidence Score & Point-by-Point Rationale
Pipeline-->>Frontend: Stream Final "result" WebSocket Message
Frontend-->>User: Render Interactive Forensic Telemetry Dashboard
| Layer | Technology |
|---|---|
| Frontend | Next.js 14, TypeScript, TailwindCSS |
| Backend Runtime | FastAPI, Python 3.10+, uv package manager |
| Forensic Signals | OpenCV, NumPy, SciPy, Pillow, PyWavelets |
| Face Extraction | InsightFace buffalo_l |
| Reasoning Agent | LangChain + Groq (llama-3.3-70b-versatile) |
| Provenance & Hashing | Perceptual DCT pHash + DuckDuckGo Web Provenance |
| Testing | Pytest (uv run pytest) |
- Node.js 18+
- Python 3.10+
uv(Fast Python package manager):pip install uvorcurl -LsSf https://astral.sh/uv/install.sh | sh
cd backend
# Sync environment dependencies with uv
uv sync
# Run backend development server
uv run uvicorn main:app --reload --port 8000cd frontend
npm install
npm run devCreate .env.local in /frontend:
NEXT_PUBLIC_API_URL=http://localhost:8000Create .env in /backend:
GROQ_API_KEY=your_groq_api_key_hereFor a detailed explanation of what every component does and how each physical/statistical forensic module works in simple English, check out the Forensics & Components Guide.
TruthLens/
βββ frontend/
β βββ src/
β βββ app/
β β βββ page.tsx # Upload & hero page
β β βββ results/[id]/
β β βββ page.tsx # Telemetry & forensic dashboard
β βββ components/
β
βββ backend/
βββ pyproject.toml # uv project configuration
βββ uv.lock # uv locked dependencies
βββ main.py # FastAPI routes & WebSocket manager
βββ pipeline.py # Async forensic task orchestrator
βββ forensic/ # Physical & statistical analyzers
β βββ base.py # BaseForensicAnalyzer contract & models
β βββ ela.py # Error Level Analysis
β βββ noise.py # Noise residual & PRNU analyzer
β βββ frequency.py # 2D FFT & DCT radial spectrum
β βββ cfa.py # Bayer demosaicing analyzer
β βββ faces.py # InsightFace alignment & crop
β βββ hashing.py # Perceptual pHash generator
β βββ metadata.py # EXIF & header inspector
βββ agent/
β βββ agent.py # Groq LLM reasoning verdict agent
βββ tools/
βββ reverse_search.py # Web provenance cross-referencing
Run all unit and integration tests using uv:
PYTHONPATH=. uv run --project backend pytest test/ -v- Digital media forensics provides probabilistic evidence to inform human analysis, not infallible binary judgments.
- Re-compression or aggressive web scaling (e.g. messaging apps) can alter EXIF tags and high-frequency noise residuals.
MIT Β© 2026 Aromal Biju