abhisheksan commited on
Commit
15fccb8
·
1 Parent(s): fa55b66

Refactor forgery detection process and improve result aggregation in forgery_routes.py

Browse files
app/api/forgery_routes.py CHANGED
@@ -6,8 +6,9 @@ from app.services.gan_detection_service import GANDetectionService
6
  from app.utils.file_utils import download_file, remove_temp_file, get_file_content
7
  from app.utils.forgery_image_utils import detect_face
8
  from app.utils.forgery_video_utils import extract_audio, extract_frames, compress_and_process_video, detect_speech # Adjust the import path if necessary
9
-
10
  import os
 
11
  import logging
12
  import traceback
13
  from pydantic import BaseModel
@@ -22,6 +23,8 @@ image_manipulation_service = ImageManipulationService()
22
  face_manipulation_service = FaceManipulationService()
23
  audio_deepfake_service = AudioDeepfakeService()
24
  gan_detection_service = GANDetectionService()
 
 
25
 
26
  def parse_confidence(value):
27
  if isinstance(value, str):
@@ -86,6 +89,17 @@ async def process_image(firebase_filename: str):
86
  logging.info(f"Image processing completed for: {firebase_filename}")
87
  return results
88
 
 
 
 
 
 
 
 
 
 
 
 
89
  async def process_video(firebase_filename: str):
90
  logging.info(f"Starting video processing for: {firebase_filename}")
91
  try:
@@ -100,14 +114,13 @@ async def process_video(firebase_filename: str):
100
  audio_content = get_file_content(audio_filename)
101
  if detect_speech(audio_content):
102
  logging.info("Speech detected in the audio")
103
- audio_deepfake_result = audio_deepfake_service.detect_deepfake(audio_filename)
104
- is_audio_deepfake = audio_deepfake_result["prediction"] == "Fake"
105
  else:
106
  logging.info("No speech detected in the audio")
107
  await remove_temp_file(audio_filename)
108
  logging.info(f"Temporary audio file removed: {audio_filename}")
109
  else:
110
- logging.warning("No audio detected or extracted from the video")
111
 
112
  results = {"is_audio_deepfake": is_audio_deepfake}
113
 
@@ -115,45 +128,61 @@ async def process_video(firebase_filename: str):
115
  logging.info(f"Frames extracted: {len(frames)} frames")
116
 
117
  results.update({
118
- "image_manipulation": [],
119
- "face_manipulation": [],
120
- "gan_detection": []
 
 
 
 
 
 
121
  })
122
 
123
  face_frames = []
124
- for i, frame in enumerate(frames):
125
- frame_filename = frame # Assuming extract_frames now returns a list of filenames
126
- logging.info(f"Processing frame: {frame_filename}")
127
- frame_content = get_file_content(frame_filename)
128
- has_face = detect_face(frame_content)
129
- logging.info(f"Face detection result for {frame_filename}: {'Face detected' if has_face else 'No face detected'}")
130
-
131
- results["image_manipulation"].append(image_manipulation_service.detect_manipulation(frame_filename))
132
- results["gan_detection"].append(gan_detection_service.detect_gan(frame_filename))
133
 
 
 
 
134
  if has_face:
135
- face_frames.append(frame_filename)
136
- results["face_manipulation"].append(face_manipulation_service.detect_manipulation(frame_filename))
137
- else:
138
- results["face_manipulation"].append(None)
139
- logging.info(f"Face manipulation detection skipped for {frame_filename} (no face detected)")
140
-
141
- await remove_temp_file(frame_filename)
142
- logging.info(f"Temporary frame file removed: {frame_filename}")
143
-
144
- # Aggregate results
145
- for key in results:
146
- if key != "is_audio_deepfake" and results[key]:
147
- valid_results = [r for r in results[key] if r is not None]
148
- results[key] = {
149
- "collective_detection": any(r.get("is_manipulated", False) if isinstance(r, dict) else r for r in valid_results),
150
- "collective_confidence": sum(parse_confidence(r.get("confidence", 0)) if isinstance(r, dict) else 0 for r in valid_results) / len(valid_results) if valid_results else 0
151
- }
 
 
 
 
 
 
 
 
 
152
  logging.info(f"Aggregated results: {results}")
153
 
154
  await remove_temp_file(compressed_video_filename)
155
- logging.info(f"Temporary compressed video file removed: {compressed_video_filename}")
 
 
156
  logging.info(f"Video processing completed for: {firebase_filename}")
 
157
  return results
158
  except Exception as e:
159
  logging.error(f"Error processing video: {e}")
 
6
  from app.utils.file_utils import download_file, remove_temp_file, get_file_content
7
  from app.utils.forgery_image_utils import detect_face
8
  from app.utils.forgery_video_utils import extract_audio, extract_frames, compress_and_process_video, detect_speech # Adjust the import path if necessary
9
+ from app.services.deepfake_video_detection import DeepfakeVideoDetectionService
10
  import os
11
+ import numpy as np
12
  import logging
13
  import traceback
14
  from pydantic import BaseModel
 
23
  face_manipulation_service = FaceManipulationService()
24
  audio_deepfake_service = AudioDeepfakeService()
25
  gan_detection_service = GANDetectionService()
26
+ deepfake_video_detection_service = DeepfakeVideoDetectionService()
27
+
28
 
29
  def parse_confidence(value):
30
  if isinstance(value, str):
 
89
  logging.info(f"Image processing completed for: {firebase_filename}")
90
  return results
91
 
92
+ def convert_to_python_types(obj):
93
+ if isinstance(obj, np.generic):
94
+ return obj.item()
95
+ elif isinstance(obj, (list, tuple)):
96
+ return [convert_to_python_types(item) for item in obj]
97
+ elif isinstance(obj, dict):
98
+ return {key: convert_to_python_types(value) for key, value in obj.items()}
99
+ elif isinstance(obj, np.ndarray):
100
+ return obj.tolist()
101
+ return obj
102
+
103
  async def process_video(firebase_filename: str):
104
  logging.info(f"Starting video processing for: {firebase_filename}")
105
  try:
 
114
  audio_content = get_file_content(audio_filename)
115
  if detect_speech(audio_content):
116
  logging.info("Speech detected in the audio")
117
+ # Audio deepfake detection logic here if needed
 
118
  else:
119
  logging.info("No speech detected in the audio")
120
  await remove_temp_file(audio_filename)
121
  logging.info(f"Temporary audio file removed: {audio_filename}")
122
  else:
123
+ logging.info("No audio detected or extracted from the video")
124
 
125
  results = {"is_audio_deepfake": is_audio_deepfake}
126
 
 
128
  logging.info(f"Frames extracted: {len(frames)} frames")
129
 
130
  results.update({
131
+ "image_manipulation": {
132
+ "collective_detection": False,
133
+ "collective_confidence": 0.0
134
+ },
135
+ "face_manipulation": None,
136
+ "gan_detection": {
137
+ "collective_detection": False,
138
+ "collective_confidence": 0.0
139
+ }
140
  })
141
 
142
  face_frames = []
143
+ img_manip_detections = []
144
+ img_manip_confidences = []
145
+ gan_detections = []
146
+ gan_confidences = []
 
 
 
 
 
147
 
148
+ for frame in frames:
149
+ frame_content = get_file_content(frame)
150
+ has_face = detect_face(frame_content)
151
  if has_face:
152
+ face_frames.append(frame)
153
+
154
+ img_manip_result = image_manipulation_service.detect_manipulation(frame)
155
+ gan_result = gan_detection_service.detect_gan(frame)
156
+
157
+ img_manip_detections.append(img_manip_result.get("is_manipulated", False))
158
+ img_manip_confidences.append(parse_confidence(img_manip_result.get("confidence", "0%")))
159
+ gan_detections.append(gan_result.get("is_gan", False))
160
+ gan_confidences.append(parse_confidence(gan_result.get("confidence", "0%")))
161
+
162
+ # Aggregate results for image manipulation and GAN detection
163
+ results["image_manipulation"]["collective_detection"] = any(img_manip_detections)
164
+ results["image_manipulation"]["collective_confidence"] = sum(img_manip_confidences) / len(img_manip_confidences) if img_manip_confidences else 0.0
165
+
166
+ results["gan_detection"]["collective_detection"] = any(gan_detections)
167
+ results["gan_detection"]["collective_confidence"] = sum(gan_confidences) / len(gan_confidences) if gan_confidences else 0.0
168
+
169
+ # Perform deepfake detection if faces were detected
170
+ if face_frames:
171
+ deepfake_result = deepfake_video_detection_service.detect_deepfake(face_frames)
172
+ deepfake_result = convert_to_python_types(deepfake_result)
173
+ results["face_manipulation"] = {
174
+ "collective_detection": bool(deepfake_result["is_deepfake"]),
175
+ "collective_confidence": deepfake_result['confidence']
176
+ }
177
+
178
  logging.info(f"Aggregated results: {results}")
179
 
180
  await remove_temp_file(compressed_video_filename)
181
+ for frame in frames:
182
+ await remove_temp_file(frame)
183
+ logging.info(f"Temporary files removed")
184
  logging.info(f"Video processing completed for: {firebase_filename}")
185
+
186
  return results
187
  except Exception as e:
188
  logging.error(f"Error processing video: {e}")
app/services/deepfake_video_detection.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tensorflow as tf
2
+ import numpy as np
3
+ import cv2
4
+ from app.utils.file_utils import get_file_content
5
+ import io
6
+
7
+ class DeepfakeVideoDetectionService:
8
+ def __init__(self):
9
+ self.model = tf.keras.models.load_model("models\deepfake_videos.h5")
10
+
11
+ def process_frame(self, frame):
12
+ frame = cv2.resize(frame, (224, 224))
13
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
14
+ frame = tf.keras.applications.xception.preprocess_input(tf.convert_to_tensor(frame, dtype=tf.float32))
15
+ return np.expand_dims(frame, axis=0)
16
+
17
+ def calculate_weighted_average(self, predictions, threshold=0.5):
18
+ weights = np.maximum(predictions - threshold, 0)
19
+ if np.sum(weights) == 0:
20
+ return np.mean(predictions)
21
+ else:
22
+ return np.average(predictions, weights=weights)
23
+
24
+ def detect_deepfake(self, frame_filenames):
25
+ predictions = []
26
+ for filename in frame_filenames:
27
+ frame_content = get_file_content(filename)
28
+ frame = cv2.imdecode(np.frombuffer(frame_content, np.uint8), cv2.IMREAD_COLOR)
29
+ processed_frame = self.process_frame(frame)
30
+ prediction = float(self.model.predict(processed_frame, verbose=0)[0][0])
31
+ predictions.append(prediction)
32
+
33
+ predictions = np.array(predictions)
34
+ weighted_avg_confidence = self.calculate_weighted_average(predictions)
35
+ is_fake = weighted_avg_confidence > 0.5
36
+
37
+ return {
38
+ "is_deepfake": is_fake,
39
+ "confidence": float(weighted_avg_confidence),
40
+ "max_confidence": float(np.max(predictions)),
41
+ "min_confidence": float(np.min(predictions)),
42
+ "frames_analyzed": len(predictions)
43
+ }
models/deepfake_videos.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ab66e33cd80e38b3642994c16a271af3b2519ae1e189a792014e6607cb57beed
3
+ size 149835704