import os import sys import json import torch import numpy as np import cv2 from PIL import Image from torchvision import transforms from safetensors.torch import load_model from huggingface_hub import hf_hub_download import gradio as gr # Add src to path sys.path.append(os.path.join(os.path.dirname(__file__), 'src')) from model import SEMViTAutoencoder # --- Hub Configuration --- REPO_ID = "morinousagi/sem-vit-anomaly" def load_resources(): device = torch.device("cpu") # 1. Download files from the Model Repo print("Downloading model weights and config from Hub...") model_path = hf_hub_download(repo_id=REPO_ID, filename="model.safetensors") config_path = hf_hub_download(repo_id=REPO_ID, filename="config.json") # 2. Initialize Model model = SEMViTAutoencoder() load_model(model, model_path, strict=False) model.to(device) model.eval() # 3. Load Threshold with open(config_path, "r") as f: config = json.load(f) threshold = config.get("threshold", 1.0) # changed to 1.0 return model, threshold, device # Global initialization MODEL, THRESHOLD, DEVICE = load_resources() def predict(img): if img is None: return None, None # 1. Preprocess (matching dataset.py) transform = transforms.Compose([ transforms.Resize((512, 512)), transforms.Grayscale(num_output_channels=3), transforms.ToTensor() ]) pil_img = Image.fromarray(img.astype('uint8')) input_tensor = transform(pil_img).unsqueeze(0).to(DEVICE) # 2. Inference with torch.no_grad(): output_tensor = MODEL(input_tensor) # 3. Calculate Anomaly Map (matching Peak Score Logic) # Move to CPU and numpy orig = input_tensor.squeeze().cpu().numpy() # [3, 512, 512] recon = output_tensor.squeeze().cpu().numpy() # [3, 512, 512] # Pixel-wise MSE across channels diff = np.mean(np.square(orig - recon), axis=0) # [512, 512] # 4. Scoring Logic (matching train_eval.py) # Apply Gaussian Blur to aggregate the defect signal (mimics avg_pool2d) smoothed_diff = cv2.GaussianBlur(diff, (15, 15), 0) # Peak Score (Max value in the smoothed map) score = np.max(smoothed_diff) is_defective = score > THRESHOLD status = "DEFECTIVE" if is_defective else "NORMAL" bg_color = "#fee2e2" if is_defective else "#dcfce7" text_color = "#b91c1c" if is_defective else "#15803d" html_result = f"""
Peak Score: {score:.5f} | Threshold: {THRESHOLD:.5f}