ayush-kale-96 commited on
Commit
12324e4
Β·
verified Β·
1 Parent(s): 1157352

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +288 -240
app.py CHANGED
@@ -1,240 +1,288 @@
1
- """
2
- Deepfake Detection System - Main Streamlit Application
3
- """
4
- import streamlit as st
5
- import os
6
- from pathlib import Path
7
- from utils.detect import DeepfakeDetector
8
- from utils.media_io import MediaHandler
9
- import tempfile
10
-
11
- # Page configuration
12
- st.set_page_config(
13
- page_title="Deepfake Detection System",
14
- page_icon="πŸ”",
15
- layout="wide"
16
- )
17
-
18
- # Initialize session state
19
- if 'analysis_complete' not in st.session_state:
20
- st.session_state.analysis_complete = False
21
- if 'results' not in st.session_state:
22
- st.session_state.results = None
23
-
24
- def main():
25
- # Header
26
- st.title("πŸ” Deepfake Detection System")
27
- st.markdown("### Analyze images and videos for AI-generated or manipulated content")
28
-
29
- # Sidebar for API key
30
- with st.sidebar:
31
- st.header("βš™οΈ Configuration")
32
- api_key = st.text_input(
33
- "Gemini API Key",
34
- type="password",
35
- help="Enter your Google Gemini API key"
36
- )
37
-
38
- st.markdown("---")
39
- st.markdown("### πŸ“– About")
40
- st.info(
41
- "This system uses Google's Gemini AI to analyze media files "
42
- "for signs of deepfake manipulation or AI generation."
43
- )
44
-
45
- st.markdown("### 🎯 Features")
46
- st.markdown("""
47
- - Image analysis
48
- - Video analysis
49
- - Frame-by-frame detection
50
- - Confidence scoring
51
- - Detailed reports
52
- """)
53
-
54
- # Main content
55
- if not api_key:
56
- st.warning("⚠️ Please enter your Gemini API key in the sidebar to continue.")
57
- st.markdown("""
58
- ### How to get your API key:
59
- 1. Visit [Google AI Studio](https://makersuite.google.com/app/apikey)
60
- 2. Create or select a project
61
- 3. Generate an API key
62
- 4. Paste it in the sidebar
63
- """)
64
- return
65
-
66
- # Media type selection
67
- st.markdown("---")
68
- col1, col2 = st.columns([1, 2])
69
-
70
- with col1:
71
- media_type = st.radio(
72
- "πŸ“ Select Media Type",
73
- ["Image", "Video"],
74
- help="Choose the type of media you want to analyze"
75
- )
76
-
77
- with col2:
78
- st.markdown(f"### Upload {media_type}")
79
-
80
- if media_type == "Image":
81
- uploaded_file = st.file_uploader(
82
- "Choose an image file",
83
- type=["jpg", "jpeg", "png", "webp"],
84
- help="Supported formats: JPG, PNG, WEBP"
85
- )
86
- else:
87
- uploaded_file = st.file_uploader(
88
- "Choose a video file",
89
- type=["mp4", "avi", "mov", "mkv"],
90
- help="Supported formats: MP4, AVI, MOV, MKV"
91
- )
92
-
93
- # Analysis section
94
- if uploaded_file is not None:
95
- st.markdown("---")
96
-
97
- # Display uploaded media
98
- col1, col2 = st.columns([1, 1])
99
-
100
- with col1:
101
- st.markdown("### πŸ“Ž Uploaded Media")
102
- if media_type == "Image":
103
- st.image(uploaded_file, use_container_width=True)
104
- else:
105
- st.video(uploaded_file)
106
-
107
- with col2:
108
- st.markdown("### πŸ”¬ Analysis")
109
-
110
- # Analyze button
111
- if st.button("πŸš€ Analyze Media", type="primary", use_container_width=True):
112
- with st.spinner("πŸ” Analyzing media... This may take a moment."):
113
- try:
114
- # Save uploaded file temporarily
115
- with tempfile.NamedTemporaryFile(delete=False, suffix=Path(uploaded_file.name).suffix) as tmp_file:
116
- tmp_file.write(uploaded_file.getvalue())
117
- tmp_path = tmp_file.name
118
-
119
- # Initialize detector
120
- detector = DeepfakeDetector(api_key)
121
-
122
- # Perform analysis
123
- if media_type == "Image":
124
- results = detector.analyze_image(tmp_path)
125
- else:
126
- results = detector.analyze_video(tmp_path)
127
-
128
- # Store results
129
- st.session_state.results = results
130
- st.session_state.analysis_complete = True
131
-
132
- # Clean up temp file
133
- os.unlink(tmp_path)
134
-
135
- st.success("βœ… Analysis complete!")
136
- st.rerun()
137
-
138
- except Exception as e:
139
- st.error(f"❌ Error during analysis: {str(e)}")
140
- if os.path.exists(tmp_path):
141
- os.unlink(tmp_path)
142
-
143
- # Display results
144
- if st.session_state.analysis_complete and st.session_state.results:
145
- st.markdown("---")
146
- display_results(st.session_state.results, media_type)
147
-
148
- def display_results(results, media_type):
149
- """Display analysis results in a formatted manner"""
150
- st.markdown("## πŸ“Š Analysis Results")
151
-
152
- # Overall verdict
153
- is_fake = results.get('is_deepfake', False)
154
- confidence = results.get('confidence_score', 0)
155
-
156
- # Color-coded verdict
157
- if is_fake:
158
- verdict_color = "πŸ”΄"
159
- verdict_text = "LIKELY DEEPFAKE/AI-GENERATED"
160
- alert_type = "error"
161
- else:
162
- verdict_color = "🟒"
163
- verdict_text = "LIKELY AUTHENTIC"
164
- alert_type = "success"
165
-
166
- # Display verdict
167
- col1, col2, col3 = st.columns([1, 2, 1])
168
-
169
- with col2:
170
- if alert_type == "error":
171
- st.error(f"{verdict_color} **{verdict_text}**")
172
- else:
173
- st.success(f"{verdict_color} **{verdict_text}**")
174
-
175
- # Metrics
176
- st.markdown("### πŸ“ˆ Detection Metrics")
177
- col1, col2, col3 = st.columns(3)
178
-
179
- with col1:
180
- st.metric("Confidence Score", f"{confidence:.1f}%")
181
-
182
- with col2:
183
- st.metric("Authenticity", f"{100 - confidence:.1f}%")
184
-
185
- with col3:
186
- risk_level = "High" if confidence > 70 else "Medium" if confidence > 40 else "Low"
187
- st.metric("Risk Level", risk_level)
188
-
189
- # Detailed analysis
190
- st.markdown("### πŸ” Detailed Analysis")
191
-
192
- with st.expander("πŸ“ Full Analysis Report", expanded=True):
193
- st.markdown(results.get('analysis', 'No detailed analysis available.'))
194
-
195
- # Indicators found
196
- if 'indicators' in results and results['indicators']:
197
- with st.expander("⚠️ Deepfake Indicators Detected"):
198
- for idx, indicator in enumerate(results['indicators'], 1):
199
- st.markdown(f"**{idx}.** {indicator}")
200
-
201
- # Video-specific results
202
- if media_type == "Video" and 'frame_analysis' in results:
203
- with st.expander("🎬 Frame-by-Frame Analysis"):
204
- frame_data = results['frame_analysis']
205
- st.markdown(f"**Total Frames Analyzed:** {frame_data.get('total_frames', 0)}")
206
- st.markdown(f"**Suspicious Frames:** {frame_data.get('suspicious_frames', 0)}")
207
-
208
- if frame_data.get('frame_details'):
209
- st.markdown("#### Sample Frames:")
210
- for frame_info in frame_data['frame_details'][:5]:
211
- st.markdown(f"- Frame {frame_info.get('frame_number', 'N/A')}: {frame_info.get('note', 'N/A')}")
212
-
213
- # Recommendations
214
- st.markdown("### πŸ’‘ Recommendations")
215
-
216
- if is_fake:
217
- st.warning("""
218
- **This media shows signs of manipulation or AI generation. Consider:**
219
- - Verifying the source
220
- - Looking for corroborating evidence
221
- - Checking metadata
222
- - Consulting additional verification tools
223
- - Being cautious about sharing
224
- """)
225
- else:
226
- st.info("""
227
- **This media appears authentic, but:**
228
- - No detection system is 100% accurate
229
- - Always verify important content through multiple sources
230
- - Check the original source when possible
231
- """)
232
-
233
- # Reset button
234
- if st.button("πŸ”„ Analyze Another File", use_container_width=True):
235
- st.session_state.analysis_complete = False
236
- st.session_state.results = None
237
- st.rerun()
238
-
239
- if __name__ == "__main__":
240
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Deepfake Detection System - Gradio Application
3
+ """
4
+ import gradio as gr
5
+ import os
6
+ from pathlib import Path
7
+ from utils.detect import DeepfakeDetector
8
+ import tempfile
9
+
10
+ def analyze_media(api_key, media_file, media_type):
11
+ """
12
+ Analyze media file for deepfake content
13
+
14
+ Args:
15
+ api_key: Gemini API key
16
+ media_file: Uploaded file
17
+ media_type: "Image" or "Video"
18
+
19
+ Returns:
20
+ tuple: (result_html, confidence_score, verdict)
21
+ """
22
+ # Validate API key
23
+ if not api_key or api_key.strip() == "":
24
+ return (
25
+ "⚠️ **Error**: Please enter your Gemini API key first.",
26
+ None,
27
+ None
28
+ )
29
+
30
+ # Validate file upload
31
+ if media_file is None:
32
+ return (
33
+ "⚠️ **Error**: Please upload a file to analyze.",
34
+ None,
35
+ None
36
+ )
37
+
38
+ try:
39
+ # Get file path
40
+ file_path = media_file.name if hasattr(media_file, 'name') else media_file
41
+
42
+ # Initialize detector
43
+ detector = DeepfakeDetector(api_key.strip())
44
+
45
+ # Perform analysis based on media type
46
+ if media_type == "Image":
47
+ results = detector.analyze_image(file_path)
48
+ else: # Video
49
+ results = detector.analyze_video(file_path, max_frames=10)
50
+
51
+ # Check for errors
52
+ if 'error' in results:
53
+ return (
54
+ f"❌ **Error during analysis**: {results['error']}\n\nPlease check your API key and try again.",
55
+ None,
56
+ None
57
+ )
58
+
59
+ # Format results
60
+ result_html = format_results(results, media_type)
61
+ confidence = results.get('confidence_score', 0)
62
+ verdict = "πŸ”΄ LIKELY DEEPFAKE" if results.get('is_deepfake', False) else "🟒 LIKELY AUTHENTIC"
63
+
64
+ return result_html, confidence, verdict
65
+
66
+ except Exception as e:
67
+ return (
68
+ f"❌ **Error**: {str(e)}\n\nPlease check your file and API key, then try again.",
69
+ None,
70
+ None
71
+ )
72
+
73
+ def format_results(results, media_type):
74
+ """Format analysis results as HTML"""
75
+ is_fake = results.get('is_deepfake', False)
76
+ confidence = results.get('confidence_score', 0)
77
+ analysis = results.get('analysis', 'No analysis available.')
78
+ indicators = results.get('indicators', [])
79
+
80
+ # Build HTML output
81
+ html = f"""
82
+ <div style="font-family: Arial, sans-serif;">
83
+ <h2>πŸ“Š Analysis Results</h2>
84
+
85
+ <div style="background: {'#fee'; border-left: 4px solid #f00;' if is_fake else '#efe; border-left: 4px solid #0f0;'} padding: 15px; margin: 10px 0;">
86
+ <h3>{'πŸ”΄ LIKELY DEEPFAKE/AI-GENERATED' if is_fake else '🟒 LIKELY AUTHENTIC'}</h3>
87
+ </div>
88
+
89
+ <div style="background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px;">
90
+ <h3>πŸ“ˆ Detection Metrics</h3>
91
+ <p><strong>Confidence Score:</strong> {confidence:.1f}%</p>
92
+ <p><strong>Authenticity:</strong> {100 - confidence:.1f}%</p>
93
+ <p><strong>Risk Level:</strong> {'High' if confidence > 70 else 'Medium' if confidence > 40 else 'Low'}</p>
94
+ </div>
95
+
96
+ <div style="background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px;">
97
+ <h3>πŸ” Detailed Analysis</h3>
98
+ <p style="white-space: pre-wrap;">{analysis}</p>
99
+ </div>
100
+ """
101
+
102
+ # Add indicators if found
103
+ if indicators:
104
+ html += """
105
+ <div style="background: #fff3cd; padding: 15px; margin: 10px 0; border-radius: 5px; border-left: 4px solid #ffc107;">
106
+ <h3>⚠️ Deepfake Indicators Detected</h3>
107
+ <ul>
108
+ """
109
+ for indicator in indicators[:5]:
110
+ html += f"<li>{indicator}</li>"
111
+ html += """
112
+ </ul>
113
+ </div>
114
+ """
115
+
116
+ # Add video-specific results
117
+ if media_type == "Video" and 'frame_analysis' in results:
118
+ frame_data = results['frame_analysis']
119
+ html += f"""
120
+ <div style="background: #e7f3ff; padding: 15px; margin: 10px 0; border-radius: 5px; border-left: 4px solid #2196F3;">
121
+ <h3>🎬 Frame-by-Frame Analysis</h3>
122
+ <p><strong>Total Frames Analyzed:</strong> {frame_data.get('total_frames', 0)}</p>
123
+ <p><strong>Suspicious Frames:</strong> {frame_data.get('suspicious_frames', 0)}</p>
124
+ </div>
125
+ """
126
+
127
+ # Add recommendations
128
+ html += """
129
+ <div style="background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px;">
130
+ <h3>πŸ’‘ Recommendations</h3>
131
+ """
132
+
133
+ if is_fake:
134
+ html += """
135
+ <p><strong>This media shows signs of manipulation or AI generation. Consider:</strong></p>
136
+ <ul>
137
+ <li>Verifying the source</li>
138
+ <li>Looking for corroborating evidence</li>
139
+ <li>Checking metadata</li>
140
+ <li>Consulting additional verification tools</li>
141
+ <li>Being cautious about sharing</li>
142
+ </ul>
143
+ """
144
+ else:
145
+ html += """
146
+ <p><strong>This media appears authentic, but remember:</strong></p>
147
+ <ul>
148
+ <li>No detection system is 100% accurate</li>
149
+ <li>Always verify important content through multiple sources</li>
150
+ <li>Check the original source when possible</li>
151
+ </ul>
152
+ """
153
+
154
+ html += """
155
+ </div>
156
+ </div>
157
+ """
158
+
159
+ return html
160
+
161
+ # Create Gradio interface
162
+ def create_interface():
163
+ """Create and configure Gradio interface"""
164
+
165
+ with gr.Blocks(title="Deepfake Detection System", theme=gr.themes.Soft()) as demo:
166
+
167
+ # Header
168
+ gr.Markdown("""
169
+ # πŸ” Deepfake Detection System
170
+ ### Analyze images and videos for AI-generated or manipulated content
171
+
172
+ This system uses Google's Gemini AI to detect deepfakes and AI-generated content in media files.
173
+ """)
174
+
175
+ # API Key Section
176
+ with gr.Row():
177
+ with gr.Column(scale=3):
178
+ api_key_input = gr.Textbox(
179
+ label="πŸ”‘ Gemini API Key",
180
+ type="password",
181
+ placeholder="Enter your Google Gemini API key here...",
182
+ info="Get your free API key from https://makersuite.google.com/app/apikey"
183
+ )
184
+ with gr.Column(scale=1):
185
+ gr.Markdown("""
186
+ ### πŸ“– How to get API Key:
187
+ 1. Visit [Google AI Studio](https://makersuite.google.com/app/apikey)
188
+ 2. Sign in with Google
189
+ 3. Create API key
190
+ 4. Paste it here
191
+ """)
192
+
193
+ gr.Markdown("---")
194
+
195
+ # Main Interface
196
+ with gr.Row():
197
+ with gr.Column(scale=1):
198
+ # Media Type Selection
199
+ media_type = gr.Radio(
200
+ choices=["Image", "Video"],
201
+ value="Image",
202
+ label="πŸ“ Select Media Type",
203
+ info="Choose the type of media you want to analyze"
204
+ )
205
+
206
+ # File Upload
207
+ media_file = gr.File(
208
+ label="πŸ“€ Upload Media File",
209
+ file_types=["image", "video"],
210
+ type="filepath"
211
+ )
212
+
213
+ # Analyze Button
214
+ analyze_btn = gr.Button(
215
+ "πŸš€ Analyze Media",
216
+ variant="primary",
217
+ size="lg"
218
+ )
219
+
220
+ # Quick Stats
221
+ gr.Markdown("""
222
+ ### πŸ“Š Supported Formats
223
+ **Images:** JPG, PNG, WEBP
224
+ **Videos:** MP4, AVI, MOV, MKV
225
+
226
+ ### ⏱️ Processing Time
227
+ **Images:** 5-15 seconds
228
+ **Videos:** 30-60 seconds
229
+ """)
230
+
231
+ with gr.Column(scale=2):
232
+ # Results Display
233
+ gr.Markdown("### πŸ“Š Analysis Results")
234
+
235
+ with gr.Row():
236
+ verdict_output = gr.Textbox(
237
+ label="Verdict",
238
+ interactive=False,
239
+ scale=2
240
+ )
241
+ confidence_output = gr.Number(
242
+ label="Confidence Score (%)",
243
+ interactive=False,
244
+ scale=1
245
+ )
246
+
247
+ result_output = gr.HTML(
248
+ label="Detailed Analysis"
249
+ )
250
+
251
+ # Footer
252
+ gr.Markdown("""
253
+ ---
254
+ ### ⚠️ Important Notes
255
+ - **Not 100% Accurate**: No detection system is perfect. Always verify through multiple sources.
256
+ - **Privacy**: Your API key and files are not stored. They're only used for analysis.
257
+ - **For Educational Use**: This tool is for educational and research purposes.
258
+
259
+ ### πŸ› οΈ Technology Stack
260
+ Built with: Google Gemini AI β€’ Gradio β€’ OpenCV β€’ Python
261
+ """)
262
+
263
+ # Connect the analyze button
264
+ analyze_btn.click(
265
+ fn=analyze_media,
266
+ inputs=[api_key_input, media_file, media_type],
267
+ outputs=[result_output, confidence_output, verdict_output]
268
+ )
269
+
270
+ # Examples section
271
+ gr.Markdown("""
272
+ ### πŸ’‘ Tips for Best Results
273
+ - Use high-quality images and videos
274
+ - Ensure good lighting in the media
275
+ - Videos should be at least 5 seconds long
276
+ - Check multiple suspicious areas if available
277
+ """)
278
+
279
+ return demo
280
+
281
+ # Launch the application
282
+ if __name__ == "__main__":
283
+ demo = create_interface()
284
+ demo.launch(
285
+ server_name="0.0.0.0",
286
+ server_port=7860,
287
+ share=False
288
+ )