Spaces:
No application file
No application file
| 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) |