File size: 3,526 Bytes
e0547b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from PIL import Image
import numpy as np
import gradio as gr
import os
import tempfile

def perform_ela_with_red_dots(input_image, quality=90, scale=10, threshold=50):
    """
    Perform Error Level Analysis (ELA) on an image and overlay red dots on tampered areas.
    
    Parameters:
    - input_image: PIL Image object (input image)
    - quality: JPEG quality for recompression (default: 90)
    - scale: Factor to amplify differences for visibility (default: 10)
    - threshold: Threshold for highlighting significant differences (default: 50)
    
    Returns:
    - result_image: PIL Image object with ELA red dots overlaid
    """
    try:
        # Step 1: Convert input image to RGB
        original = input_image.convert('RGB')
        original_array = np.array(original)

        # Step 2: Save the image at a slightly lower quality (recompress)
        with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as temp_file:
            temp_path = temp_file.name
            original.save(temp_path, "JPEG", quality=quality)

        # Step 3: Load the recompressed image
        recompressed = Image.open(temp_path).convert('RGB')
        recompressed_array = np.array(recompressed)

        # Step 4: Compute the absolute difference between original and recompressed
        diff = np.abs(original_array - recompressed_array)

        # Step 5: Amplify the differences for better visibility
        ela = diff * scale
        ela = np.clip(ela, 0, 255).astype(np.uint8)

        # Step 6: Create a red-dot overlay for significant differences
        red_dots = np.zeros_like(original_array)
        mask = ela > threshold  # Highlight areas above the threshold
        red_dots[mask] = [255, 0, 0]  # Red color for significant differences

        # Step 7: Blend the red dots with the original image
        alpha = 0.5  # Transparency for blending
        blended = original_array.copy()
        blended = blended * (1 - alpha) + red_dots * alpha
        blended = blended.astype(np.uint8)

        # Step 8: Convert the result back to a PIL Image
        result_image = Image.fromarray(blended)

        # Step 9: Clean up the temporary file
        if os.path.exists(temp_path):
            os.remove(temp_path)

        return result_image

    except Exception as e:
        raise Exception(f"Error performing ELA: {e}")

# Gradio interface function
def ela_interface(input_image):
    """
    Gradio interface to process an image and return the ELA result.
    
    Parameters:
    - input_image: Input image uploaded via Gradio
    
    Returns:
    - result_image: Processed image with ELA red dots
    """
    if input_image is None:
        raise gr.Error("Please upload an image to process.")
    
    # Perform ELA on the uploaded image
    result_image = perform_ela_with_red_dots(input_image, quality=90, scale=10, threshold=50)
    return result_image

# Define the Gradio interface
interface = gr.Interface(
    fn=ela_interface,  # Function to call
    inputs=gr.Image(type="pil", label="Upload Image (JPEG)"),  # Input: Image upload
    outputs=gr.Image(type="pil", label="ELA Result with Red Dots"),  # Output: Processed image
    title="Error Level Analysis (ELA) for Image Tampering Detection",
    description="Upload a JPEG image to perform Error Level Analysis (ELA). Areas with potential tampering will be highlighted with red dots.",
    allow_flagging="never"
)

# Launch the Gradio app
if __name__ == "__main__":
    interface.launch(server_name="0.0.0.0", server_port=7860)