CoolFace
Apppublic

frozencherry/Forgery-Localization-App

sourceHugging Faceupdated 1y agoView on Hugging Face
1likes
app.py117 linesDownload Raw Back to root
1import numpy as np2from PIL import Image, ImageChops, ImageEnhance, UnidentifiedImageError3import tensorflow as tf4import gradio as gr5import os6import traceback7import io8import cv2 # Added missing import for cv29 10# Enable XLA and set libdevice path programmatically11tf.config.optimizer.set_jit(True)12tf.config.optimizer.set_experimental_options({13    'xla_auto_jit': True,14    'xla_gpu_cuda_data_dir': '/home/ubuntu/miniconda3/pkgs/cuda-nvvm-tools-12.5.40-h59595ed_0/nvvm/libdevice'15})16 17# ==== CUSTOM OBJECTS ====18from custom_layer import CBAM  # Your custom attention module19from metrics import *  # Your loss/metric functions20 21# ==== LOAD MODEL ====22custom_objects = {23    'CBAM': CBAM,24    'dice_coef_loss': dice_coef_loss,25    'dice_coefficient': dice_coefficient,26    'iou': iou,27    'accuracy': accuracy,28    'weighted_dice_bce_loss': weighted_dice_bce_loss29}30 31model = tf.keras.models.load_model("final_finetune.keras", custom_objects=custom_objects)32input_height, input_width = 256, 25633print(model.input_shape)34print(model.output_shape)35 36ELA_QUALITY = 95 # Define ELA_QUALITY as it was missing37 38# ==== ELA CALCULATION ====39def calculate_ela(original_image, quality=ELA_QUALITY):40    with io.BytesIO() as output:41        original_image.save(output, format='JPEG', quality=quality)42        jpeg_data = output.getvalue()43    resaved_image = Image.open(io.BytesIO(jpeg_data))44    ela_image = ImageChops.difference(original_image, resaved_image)45    ela_image = ImageEnhance.Brightness(ela_image).enhance(6.0) # Changed to 6.046    return np.array(ela_image) # Return as NumPy array47 48# ==== PREPROCESS FUNCTION ====49def preprocess(image):50    try:51        if image is None:52            raise ValueError("No image provided.")53        54        if isinstance(image, tuple):55            image = image[0]  # Gradio might send (PIL.Image, dict) tuple56 57        if not isinstance(image, Image.Image):58            image = Image.open(image)59        60        # Convert image to RGB and then to JPEG in memory for consistent processing61        if image.mode != 'RGB':62            image = image.convert('RGB')63        with io.BytesIO() as output_jpeg:64            image.save(output_jpeg, format='JPEG')65            jpeg_data = output_jpeg.getvalue()66        image = Image.open(io.BytesIO(jpeg_data)) # Re-open as JPEG for consistent handling67 68        original_image = image.resize((input_width, input_height))69        ela_array = calculate_ela(original_image) # ela_array is now a NumPy array directly70 71        # Ensure original_image is also a numpy array for consistent handling72        original_array = np.array(original_image).astype(np.float32) / 255.073        ela_array = cv2.resize(ela_array, (input_width, input_height))74        ela_array = ela_array.astype(np.float32) / 255.075 76        # Ensure ela_array has 3 channels if it's grayscale (as per model.input_shape)77        if ela_array.ndim == 2:78            ela_array = np.stack([ela_array, ela_array, ela_array], axis=-1)79        elif ela_array.shape[-1] == 1:80            ela_array = np.concatenate([ela_array, ela_array, ela_array], axis=-1)81        82        return np.expand_dims(original_array, axis=0), np.expand_dims(ela_array, axis=0)83    84    except (UnidentifiedImageError, ValueError, TypeError, AttributeError) as e:85        print(f"Preprocessing error: {str(e)}")86        return None, None # Changed to return None, None for prediction to handle87 88# ==== PREDICT FUNCTION ====89def predict(image):90    original_preprocessed, ela_preprocessed = preprocess(image)91    if original_preprocessed is None or ela_preprocessed is None:92        return "Preprocessing failed", None93    try:94        prediction = model.predict([original_preprocessed, ela_preprocessed])[0]95        prediction_mask = (prediction > 0.5).astype(np.uint8) * 25596        prediction_image = Image.fromarray(prediction_mask.squeeze()).convert("L")97        return "Prediction successful", prediction_image98    except Exception as e:99        print(f"Prediction error: {str(e)}")100        return f"Error during prediction: {str(e)}", None101 102# ==== GRADIO APP ====103# Get sample image paths104sample_image_paths = [["samples/IMG_0002364.jpg"]]105 106demo = gr.Interface(107    fn=predict,108    inputs=gr.Image(type="pil", label="Upload Image"),109    outputs=[gr.Text(label="Status"), gr.Image(label="Forgery Mask")],110    title="Forgery Localization",111    description="Upload any image format (e.g., JPG, PNG, TIF) to detect forged regions using ELA + CNN.",112    examples=sample_image_paths # Add sample images here113)114 115if __name__ == "__main__":116    demo.launch()117