HunzalaRasheed1 commited on
Commit
cbab20b
·
verified ·
1 Parent(s): 0ebcbdf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +141 -125
app.py CHANGED
@@ -1,144 +1,160 @@
1
- import streamlit as st
 
 
2
  import io
3
  import base64
4
  from PIL import Image
5
- import tempfile
6
- import os
7
- import json
8
-
9
- # Import functions from your backend file
10
- from backend import (
11
- detect_clones,
12
- error_level_analysis,
13
- extract_exif_metadata,
14
- noise_analysis,
15
- manipulation_likelihood,
16
- get_clone_explanation,
17
- pil_to_base64
18
- )
19
 
20
- # Create temp directory
21
- TEMP_DIR = tempfile.mkdtemp()
22
 
23
- # Helper functions
24
- def save_uploaded_image(uploaded_file):
25
- """Save a Streamlit uploaded file and return the path"""
26
- temp_path = os.path.join(TEMP_DIR, "temp_analyze.jpg")
27
- with open(temp_path, "wb") as f:
28
- f.write(uploaded_file.getbuffer())
29
- return temp_path
30
 
31
- # Streamlit UI
32
- st.set_page_config(page_title="Image Forensic & Fraud Detection Tool", layout="wide")
 
 
33
 
34
- st.title("Image Forensic & Fraud Detection Tool")
35
- st.write("Upload an image to analyze it for potential manipulation using various forensic techniques.")
36
-
37
- # Sidebar for uploading and basic controls
38
- with st.sidebar:
39
- uploaded_file = st.file_uploader("Upload Image", type=["jpg", "jpeg", "png"])
40
 
41
- if uploaded_file is not None:
42
- analyze_button = st.button("Analyze Image", type="primary")
 
43
 
44
- # Display probability meter if analysis has been done
45
- if "probability" in st.session_state:
46
- st.markdown("### Manipulation Probability")
47
- st.progress(st.session_state.probability)
48
- st.write(f"{st.session_state.probability*100:.1f}%")
49
 
50
- # Main content area with tabs
51
- if uploaded_file is not None:
52
- # Display the original image
53
- image = Image.open(uploaded_file)
54
-
55
- # Create tabs for different analyses
56
- tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs([
57
- "Analysis Results",
58
- "Original Image",
59
- "Error Level Analysis",
60
- "Noise Analysis",
61
- "Clone Detection",
62
- "AI Detection Heatmap"
63
- ])
64
-
65
- with tab2:
66
- st.image(image, caption="Original Image")
67
-
68
- # Run analysis when button is clicked
69
- if analyze_button:
70
- # Save the image
71
- temp_path = save_uploaded_image(uploaded_file)
72
-
73
- with st.spinner("Analyzing image..."):
74
- try:
75
- # Run all analyses
76
- exif_result = extract_exif_metadata(temp_path)
77
- manipulation_result = manipulation_likelihood(temp_path)
78
- clone_result, clone_count = detect_clones(temp_path)
79
- ela_image = error_level_analysis(temp_path)
80
- noise_image = noise_analysis(temp_path)
81
-
82
- # Store probability in session state
83
- st.session_state.probability = manipulation_result["probability"]
84
-
85
- # Display results in each tab
86
- with tab1:
87
- st.markdown(f"""
88
- ## Manipulation Analysis Results
89
 
90
- **Overall Assessment: {manipulation_result['probability']*100:.1f}% likelihood of manipulation**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
- {manipulation_result['explanation']}
93
 
94
- ### Clone Detection Analysis:
95
- Found {clone_count} potential cloned regions in the image.
96
- {get_clone_explanation(clone_count)}
97
 
98
- ### EXIF Metadata Analysis:
99
- {exif_result['summary']}
 
100
 
101
- Indicators found: {len(exif_result['indicators'])}
102
- """)
103
-
104
- if exif_result['indicators']:
105
- st.markdown("### Detailed indicators:")
106
- for indicator in exif_result['indicators']:
107
- st.markdown(f"- {indicator}")
108
-
109
- # Display EXIF data as expandable JSON
110
- with st.expander("View EXIF Metadata"):
111
- st.json(exif_result["metadata"])
 
 
 
 
 
 
 
 
 
 
 
112
 
113
- with tab3:
114
- st.markdown("""
115
- Error Level Analysis reveals differences in compression levels. Areas with different compression levels
116
- often indicate modifications. Brighter regions in the visualization suggest potential manipulations.
117
- """)
118
- st.image(ela_image, caption="Error Level Analysis Result")
119
 
120
- with tab4:
121
- st.markdown("""
122
- Noise Analysis examines the noise patterns in the image. Inconsistent noise patterns often indicate
123
- areas that have been manipulated or added from different sources.
124
- """)
125
- st.image(noise_image, caption="Noise Pattern Analysis")
126
 
127
- with tab5:
128
- st.markdown("""
129
- Clone Detection identifies duplicated areas within the image. Red and blue rectangles highlight
130
- matching regions that may indicate copy-paste manipulation.
131
- """)
132
- st.image(clone_result, caption="Clone Detection Result")
133
 
134
- with tab6:
135
- st.markdown("""
136
- This heatmap highlights regions identified by our AI model as potentially manipulated.
137
- Red areas indicate suspicious regions with a higher likelihood of manipulation.
138
- """)
139
- st.image(manipulation_result["heatmap_image"], caption="AI-Detected Suspicious Regions")
140
-
141
- except Exception as e:
142
- st.error(f"Error during analysis: {str(e)}")
143
- else:
144
- st.info("Please upload an image to begin analysis.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import json
4
  import io
5
  import base64
6
  from PIL import Image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
+ # FastAPI backend URL
9
+ API_URL = "http://localhost:8000"
10
 
11
+ #############################
12
+ # HELPER FUNCTIONS
13
+ #############################
 
 
 
 
14
 
15
+ def base64_to_pil(base64_str):
16
+ """Convert base64 string to PIL image"""
17
+ img_data = base64.b64decode(base64_str)
18
+ return Image.open(io.BytesIO(img_data))
19
 
20
+ def upload_image(image, endpoint):
21
+ """Upload an image to the specified API endpoint"""
22
+ # Save image to bytes
23
+ img_byte_arr = io.BytesIO()
24
+ image.save(img_byte_arr, format='JPEG')
25
+ img_byte_arr = img_byte_arr.getvalue()
26
 
27
+ # Send to API
28
+ files = {'file': ('image.jpg', img_byte_arr, 'image/jpeg')}
29
+ response = requests.post(f"{API_URL}{endpoint}", files=files)
30
 
31
+ # Return the JSON response
32
+ return response.json()
 
 
 
33
 
34
+ #############################
35
+ # API INTERFACE FUNCTIONS
36
+ #############################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ def analyze_image(image):
39
+ """Main function that sends the image to the API for analysis"""
40
+ if image is None:
41
+ return {
42
+ original_image: None,
43
+ ela_image: None,
44
+ noise_image: None,
45
+ heatmap_image: None,
46
+ clone_image: None,
47
+ exif_data: "{}",
48
+ analysis_results: "Please upload an image first.",
49
+ probability_slider: 0
50
+ }
51
+
52
+ # Send to API for full analysis
53
+ try:
54
+ response = upload_image(image, "/api/analyze_image")
55
+
56
+ # Process results
57
+ return {
58
+ original_image: image,
59
+ ela_image: base64_to_pil(response["ela_image"]),
60
+ noise_image: base64_to_pil(response["noise_image"]),
61
+ heatmap_image: base64_to_pil(response["heatmap_image"]),
62
+ clone_image: base64_to_pil(response["clone_image"]),
63
+ exif_data: json.dumps(response["exif_data"], indent=2),
64
+ analysis_results: response["analysis_text"],
65
+ probability_slider: response["manipulation_probability"]
66
+ }
67
+ except Exception as e:
68
+ return {
69
+ original_image: image,
70
+ ela_image: None,
71
+ noise_image: None,
72
+ heatmap_image: None,
73
+ clone_image: None,
74
+ exif_data: f"Error: {str(e)}",
75
+ analysis_results: f"Error occurred during analysis: {str(e)}",
76
+ probability_slider: 0
77
+ }
78
 
 
79
 
80
+ #############################
81
+ # GRADIO INTERFACE
82
+ #############################
83
 
84
+ with gr.Blocks(title="Image Forensic & Fraud Detection Tool - MVP Demo") as demo:
85
+ gr.Markdown("""
86
+ # Image Forensic & Fraud Detection Tool
87
 
88
+
89
+ Upload an image to analyze it for potential manipulation using various forensic techniques.
90
+ """)
91
+
92
+ with gr.Row():
93
+ with gr.Column(scale=1):
94
+ input_image = gr.Image(type="pil", label="Upload Image for Analysis")
95
+ analyze_button = gr.Button("Analyze Image", variant="primary")
96
+
97
+ gr.Markdown("### Manipulation Probability")
98
+ probability_slider = gr.Slider(
99
+ minimum=0, maximum=1, value=0,
100
+ label="Manipulation Probability",
101
+ interactive=False
102
+ )
103
+
104
+ gr.Markdown("### EXIF Metadata")
105
+ exif_data = gr.Code(language="json", label="EXIF Data", lines=10)
106
+
107
+ with gr.Column(scale=2):
108
+ with gr.Tab("Analysis Results"):
109
+ analysis_results = gr.Markdown()
110
 
111
+ with gr.Tab("Original Image"):
112
+ original_image = gr.Image(type="pil", label="Original Image")
 
 
 
 
113
 
114
+ with gr.Tab("Error Level Analysis (ELA)"):
115
+ gr.Markdown("""
116
+ Error Level Analysis reveals differences in compression levels. Areas with different compression levels
117
+ often indicate modifications. Brighter regions in the visualization suggest potential manipulations.
118
+ """)
119
+ ela_image = gr.Image(type="pil", label="ELA Result")
120
 
121
+ with gr.Tab("Noise Analysis"):
122
+ gr.Markdown("""
123
+ Noise Analysis examines the noise patterns in the image. Inconsistent noise patterns often indicate
124
+ areas that have been manipulated or added from different sources.
125
+ """)
126
+ noise_image = gr.Image(type="pil", label="Noise Pattern Analysis")
127
 
128
+ with gr.Tab("Clone Detection"):
129
+ gr.Markdown("""
130
+ Clone Detection identifies duplicated areas within the image. Red and blue rectangles highlight
131
+ matching regions that may indicate copy-paste manipulation.
132
+ """)
133
+ clone_image = gr.Image(type="pil", label="Clone Detection Result")
134
+
135
+ with gr.Tab("AI Detection Heatmap"):
136
+ gr.Markdown("""
137
+ This heatmap highlights regions identified by our AI model as potentially manipulated.
138
+ Red areas indicate suspicious regions with a higher likelihood of manipulation.
139
+ """)
140
+ heatmap_image = gr.Image(type="pil", label="AI-Detected Suspicious Regions")
141
+
142
+ # Set up event handlers
143
+ analyze_button.click(
144
+ fn=analyze_image,
145
+ inputs=[input_image],
146
+ outputs=[
147
+ original_image,
148
+ ela_image,
149
+ noise_image,
150
+ heatmap_image,
151
+ clone_image,
152
+ exif_data,
153
+ analysis_results,
154
+ probability_slider
155
+ ]
156
+ )
157
+
158
+ # Launch the app
159
+ if __name__ == "__main__":
160
+ demo.launch()