sainarc commited on
Commit
d00fddd
·
verified ·
1 Parent(s): 67e2168

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +213 -0
app.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from flask import Flask, render_template, request, jsonify
3
+ from werkzeug.utils import secure_filename
4
+ from transformers import pipeline
5
+ from PIL import Image
6
+ import librosa
7
+ import numpy as np
8
+
9
+ app = Flask(__name__)
10
+
11
+ # Configuration
12
+ UPLOAD_FOLDER = 'uploads'
13
+ ALLOWED_IMAGE_EXTENSIONS = {'jpg', 'jpeg', 'png'}
14
+ ALLOWED_AUDIO_EXTENSIONS = {'wav', 'mp3'}
15
+ MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
16
+
17
+ # Create uploads folder if it doesn't exist
18
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
19
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
20
+ app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE
21
+
22
+ # Load models locally
23
+ print("Loading image detection model...")
24
+ try:
25
+ image_classifier = pipeline("image-classification", model="dima806/ai_vs_real_image_detection")
26
+ print("✓ Image model loaded successfully")
27
+ except Exception as e:
28
+ print(f"✗ Error loading image model: {e}")
29
+ image_classifier = None
30
+
31
+ print("Loading audio detection model...")
32
+ try:
33
+ audio_classifier = pipeline("audio-classification", model="Gustking/wav2vec2-large-xlsr-deepfake-audio-classification")
34
+ print("✓ Audio model loaded successfully")
35
+ except Exception as e:
36
+ print(f"✗ Error loading audio model: {e}")
37
+ audio_classifier = None
38
+
39
+
40
+ def allowed_file(filename, file_type):
41
+ """Check if file extension is allowed."""
42
+ if '.' not in filename:
43
+ return False
44
+ ext = filename.rsplit('.', 1)[1].lower()
45
+ if file_type == 'image':
46
+ return ext in ALLOWED_IMAGE_EXTENSIONS
47
+ elif file_type == 'audio':
48
+ return ext in ALLOWED_AUDIO_EXTENSIONS
49
+ return False
50
+
51
+
52
+ def detect_image_deepfake(file_path):
53
+ """Detect deepfake in image using local model."""
54
+ if not image_classifier:
55
+ return {'error': 'Image model not loaded'}
56
+
57
+ try:
58
+ # Load and process image
59
+ image = Image.open(file_path).convert('RGB')
60
+
61
+ # Run inference
62
+ results = image_classifier(image)
63
+
64
+ # Results is a list of dicts with 'label' and 'score'
65
+ if results and len(results) > 0:
66
+ # Find the prediction with highest score
67
+ max_result = max(results, key=lambda x: x.get('score', 0))
68
+
69
+ label = max_result.get('label', 'UNKNOWN')
70
+ confidence = round(max_result.get('score', 0) * 100, 2)
71
+
72
+ # If confidence is less than 70%, return REAL
73
+ if confidence < 90:
74
+ label = 'REAL'
75
+
76
+ return {'label': label, 'confidence': confidence}
77
+
78
+ return {'error': 'No predictions returned'}
79
+
80
+ except Exception as e:
81
+ return {'error': f'Error processing image: {str(e)}'}
82
+
83
+
84
+ def detect_audio_deepfake(file_path):
85
+ """Detect deepfake in audio using local model."""
86
+ if not audio_classifier:
87
+ return {'error': 'Audio model not loaded'}
88
+
89
+ try:
90
+ # Load audio file
91
+ audio_data, sr = librosa.load(file_path, sr=None)
92
+
93
+ # Run inference
94
+ results = audio_classifier(audio_data)
95
+
96
+ # Results is a list of dicts with 'label' and 'score'
97
+ if results and len(results) > 0:
98
+ # Find the prediction with highest score
99
+ max_result = max(results, key=lambda x: x.get('score', 0))
100
+
101
+ label = max_result.get('label', 'UNKNOWN')
102
+ confidence = round(max_result.get('score', 0) * 100, 2)
103
+
104
+ # Treat low-confidence predictions as Fake
105
+ if confidence < 80:
106
+ label = 'Fake'
107
+ return {'label': label, 'confidence': confidence}
108
+
109
+ return {'error': 'No predictions returned'}
110
+
111
+ except Exception as e:
112
+ return {'error': f'Error processing audio: {str(e)}'}
113
+
114
+
115
+ @app.route('/')
116
+ def index():
117
+ """Serve the main HTML page."""
118
+ return render_template('index.html')
119
+
120
+
121
+ @app.route('/detect/image', methods=['POST'])
122
+ def detect_image():
123
+ """Endpoint for image deepfake detection."""
124
+ try:
125
+ # Check if file is present
126
+ if 'file' not in request.files:
127
+ return jsonify({'success': False, 'error': 'No file provided'}), 400
128
+
129
+ file = request.files['file']
130
+
131
+ if file.filename == '':
132
+ return jsonify({'success': False, 'error': 'No file selected'}), 400
133
+
134
+ # Validate file type
135
+ if not allowed_file(file.filename, 'image'):
136
+ return jsonify({'success': False, 'error': 'Invalid file type. Use JPG or PNG.'}), 400
137
+
138
+ # Save file temporarily
139
+ filename = secure_filename(file.filename)
140
+ filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
141
+ file.save(filepath)
142
+
143
+ try:
144
+ # Detect deepfake using local model
145
+ result = detect_image_deepfake(filepath)
146
+
147
+ # Check for errors
148
+ if 'error' in result:
149
+ return jsonify({'success': False, 'error': result['error']}), 500
150
+
151
+ return jsonify({
152
+ 'success': True,
153
+ 'label': result['label'],
154
+ 'confidence': result['confidence']
155
+ }), 200
156
+
157
+ finally:
158
+ # Clean up uploaded file
159
+ if os.path.exists(filepath):
160
+ os.remove(filepath)
161
+
162
+ except Exception as e:
163
+ return jsonify({'success': False, 'error': f'Server error: {str(e)}'}), 500
164
+
165
+
166
+ @app.route('/detect/audio', methods=['POST'])
167
+ def detect_audio():
168
+ """Endpoint for audio deepfake detection."""
169
+ try:
170
+ # Check if file is present
171
+ if 'file' not in request.files:
172
+ return jsonify({'success': False, 'error': 'No file provided'}), 400
173
+
174
+ file = request.files['file']
175
+
176
+ if file.filename == '':
177
+ return jsonify({'success': False, 'error': 'No file selected'}), 400
178
+
179
+ # Validate file type
180
+ if not allowed_file(file.filename, 'audio'):
181
+ return jsonify({'success': False, 'error': 'Invalid file type. Use WAV or MP3.'}), 400
182
+
183
+ # Save file temporarily
184
+ filename = secure_filename(file.filename)
185
+ filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
186
+ file.save(filepath)
187
+
188
+ try:
189
+ # Detect deepfake using local model
190
+ result = detect_audio_deepfake(filepath)
191
+
192
+ # Check for errors
193
+ if 'error' in result:
194
+ return jsonify({'success': False, 'error': result['error']}), 500
195
+
196
+ return jsonify({
197
+ 'success': True,
198
+ 'label': result['label'],
199
+ 'confidence': result['confidence']
200
+ }), 200
201
+
202
+ finally:
203
+ # Clean up uploaded file
204
+ if os.path.exists(filepath):
205
+ os.remove(filepath)
206
+
207
+ except Exception as e:
208
+ return jsonify({'success': False, 'error': f'Server error: {str(e)}'}), 500
209
+
210
+
211
+ if __name__ == "__main__":
212
+ port = int(os.environ.get("PORT", 7860))
213
+ app.run(host="0.0.0.0", port=port)