Jatin-tec
Add application file
65d7391
raw
history blame
4.7 kB
import gradio as gr
import torch
from PIL import Image
from typing import Dict, Optional, Tuple
from transformers import AutoImageProcessor, SiglipForImageClassification
from trufor_runner import TruForEngine, TruForResult, TruForUnavailableError
MODEL_ID = "Ateeqq/ai-vs-human-image-detector"
# Use GPU when available so large batches stay responsive.
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
try:
processor = AutoImageProcessor.from_pretrained(MODEL_ID)
model = SiglipForImageClassification.from_pretrained(MODEL_ID)
model.to(device)
model.eval()
except Exception as exc: # pragma: no cover - surface loading issues early.
raise RuntimeError(f"Failed to load model from {MODEL_ID}") from exc
try:
TRUFOR_ENGINE: Optional[TruForEngine] = TruForEngine(device="cpu")
TRUFOR_STATUS = TRUFOR_ENGINE.status_message
except TruForUnavailableError as exc:
TRUFOR_ENGINE = None
TRUFOR_STATUS = str(exc)
def analyze_ai_vs_human(image: Image.Image) -> Tuple[Dict[str, float], str]:
"""Run the Hugging Face detector and return confidences with a readable summary."""
if image is None:
empty_scores = {label: 0.0 for label in model.config.id2label.values()}
return empty_scores, "No image provided."
image = image.convert("RGB")
inputs = processor(images=image, return_tensors="pt").to(device)
with torch.no_grad():
logits = model(**inputs).logits
probabilities = torch.softmax(logits, dim=-1)[0]
scores = {
model.config.id2label[idx]: float(probabilities[idx])
for idx in range(probabilities.size(0))
}
top_idx = int(probabilities.argmax().item())
top_label = model.config.id2label[top_idx]
top_score = scores[top_label]
summary = f"**Predicted Label:** {top_label} \
**Confidence:** {top_score:.4f}"
return scores, summary
def analyze_trufor(image: Image.Image) -> Tuple[str, Optional[Image.Image], Optional[Image.Image]]:
"""Run TruFor inference when available, otherwise return diagnostics."""
if TRUFOR_ENGINE is None:
return TRUFOR_STATUS, None, None
if image is None:
return "Upload an image to run TruFor.", None, None
try:
result: TruForResult = TRUFOR_ENGINE.infer(image)
except TruForUnavailableError as exc:
return str(exc), None, None
summary_lines = []
if result.score is not None:
summary_lines.append(f"**Tamper Score:** {result.score:.4f}")
extras_dict = result.raw_scores.copy()
if result.score is not None:
extras_dict.pop("tamper_score", None)
if extras_dict:
extras = " ".join(f"{key}: {value:.4f}" for key, value in extras_dict.items())
summary_lines.append(f"`{extras}`")
if not summary_lines:
summary_lines.append("TruFor returned no scores for this image.")
return "\n".join(summary_lines), result.map_overlay, result.confidence_overlay
def analyze_image(image: Image.Image) -> Tuple[Dict[str, float], str, str, Optional[Image.Image], Optional[Image.Image]]:
ai_scores, ai_summary = analyze_ai_vs_human(image)
trufor_summary, tamper_overlay, conf_overlay = analyze_trufor(image)
return ai_scores, ai_summary, trufor_summary, tamper_overlay, conf_overlay
with gr.Blocks() as demo:
gr.Markdown(
"""# Image Authenticity Workbench\nUpload an image to compare the AI-vs-human classifier with the TruFor forgery detector."""
)
status_box = gr.Markdown(f"`{TRUFOR_STATUS}`")
image_input = gr.Image(label="Input Image", type="pil")
analyze_button = gr.Button("Analyze", variant="primary", size="sm")
with gr.Tabs():
with gr.TabItem("AI vs Human"):
ai_label_output = gr.Label(label="Prediction", num_top_classes=2)
ai_summary_output = gr.Markdown("Upload an image to view the prediction.")
with gr.TabItem("TruFor Forgery Detection"):
trufor_summary_output = gr.Markdown("Configure TruFor assets to enable tamper analysis.")
tamper_overlay_output = gr.Image(label="Tamper Heatmap", type="pil", interactive=False)
conf_overlay_output = gr.Image(label="Confidence Heatmap", type="pil", interactive=False)
output_components = [
ai_label_output,
ai_summary_output,
trufor_summary_output,
tamper_overlay_output,
conf_overlay_output,
]
analyze_button.click(
fn=analyze_image,
inputs=image_input,
outputs=output_components,
)
image_input.change(
fn=analyze_image,
inputs=image_input,
outputs=output_components,
)
if __name__ == "__main__":
demo.launch()