Devanshu2025 commited on
Commit
a97adf2
·
1 Parent(s): 057379b

Replace dlib with OpenCV face detection, add HuggingFace model downloads

Browse files
Files changed (3) hide show
  1. Dockerfile +12 -5
  2. preprocessing.py +65 -10
  3. requirements.txt +0 -1
Dockerfile CHANGED
@@ -7,17 +7,15 @@ WORKDIR /app
7
  # Prevent Python from buffering stdout/stderr
8
  ENV PYTHONUNBUFFERED=1
9
 
10
- # Install system dependencies required for OpenCV, face-recognition (dlib), and general build
11
  RUN apt-get update && apt-get install -y --no-install-recommends \
12
- build-essential \
13
- cmake \
14
  libgl1 \
15
  libglx-mesa0 \
16
  libglib2.0-0 \
17
  libsm6 \
18
  libxext6 \
19
- libxrender-dev \
20
- libboost-all-dev \
21
  && rm -rf /var/lib/apt/lists/*
22
 
23
  # Copy requirements first to leverage Docker cache
@@ -32,6 +30,15 @@ RUN pip install --no-cache-dir -r requirements.txt
32
  # Copy application code
33
  COPY . .
34
 
 
 
 
 
 
 
 
 
 
35
  # Expose the port Render will use
36
  EXPOSE 8000
37
 
 
7
  # Prevent Python from buffering stdout/stderr
8
  ENV PYTHONUNBUFFERED=1
9
 
10
+ # Install system dependencies required for OpenCV and wget for downloads
11
  RUN apt-get update && apt-get install -y --no-install-recommends \
 
 
12
  libgl1 \
13
  libglx-mesa0 \
14
  libglib2.0-0 \
15
  libsm6 \
16
  libxext6 \
17
+ libxrender1 \
18
+ wget \
19
  && rm -rf /var/lib/apt/lists/*
20
 
21
  # Copy requirements first to leverage Docker cache
 
30
  # Copy application code
31
  COPY . .
32
 
33
+ # Create models directory and download ML models from HuggingFace
34
+ RUN mkdir -p models && \
35
+ wget -q --show-progress -O models/model_84_acc_10_frames_final_data.pt "https://huggingface.co/Devanshu2025/Deepfake-video-detection/resolve/main/model_84_acc_10_frames_final_data.pt" && \
36
+ wget -q --show-progress -O models/model_90_acc_20_frames_FF_data.pt "https://huggingface.co/Devanshu2025/Deepfake-video-detection/resolve/main/model_90_acc_20_frames_FF_data.pt" && \
37
+ wget -q --show-progress -O models/model_95_acc_40_frames_FF_data.pt "https://huggingface.co/Devanshu2025/Deepfake-video-detection/resolve/main/model_95_acc_40_frames_FF_data.pt" && \
38
+ wget -q --show-progress -O models/model_97_acc_60_frames_FF_data.pt "https://huggingface.co/Devanshu2025/Deepfake-video-detection/resolve/main/model_97_acc_60_frames_FF_data.pt" && \
39
+ wget -q --show-progress -O models/model_97_acc_80_frames_FF_data.pt "https://huggingface.co/Devanshu2025/Deepfake-video-detection/resolve/main/model_97_acc_80_frames_FF_data.pt" && \
40
+ wget -q --show-progress -O models/model_97_acc_100_frames_FF_data.pt "https://huggingface.co/Devanshu2025/Deepfake-video-detection/resolve/main/model_97_acc_100_frames_FF_data.pt"
41
+
42
  # Expose the port Render will use
43
  EXPOSE 8000
44
 
preprocessing.py CHANGED
@@ -3,7 +3,6 @@ from torch.utils.data import Dataset
3
  from torchvision import transforms
4
  import cv2
5
  import numpy as np
6
- import face_recognition
7
  from typing import List, Generator, Tuple
8
  import os
9
  import base64
@@ -22,6 +21,59 @@ train_transforms = transforms.Compose([
22
  transforms.Normalize(MEAN, STD)
23
  ])
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  class ValidationDataset(Dataset):
27
  """
@@ -42,14 +94,17 @@ class ValidationDataset(Dataset):
42
 
43
  # Extract frames from video
44
  for i, frame in enumerate(self.frame_extract(self.video_path)):
45
- # Detect face in frame
46
- faces = face_recognition.face_locations(frame)
 
 
 
47
  try:
48
  top, right, bottom, left = faces[0]
49
- frame = frame[top:bottom, left:right, :]
50
  except (IndexError, ValueError):
51
  # No face detected, use full frame
52
- pass
53
 
54
  frames.append(self.transform(frame))
55
 
@@ -93,7 +148,7 @@ def preprocess_video(
93
  output_dir: Directory to save preprocessed images
94
 
95
  Returns:
96
- Tuple of (preprocessed_tensor, preprocessed_images_list, face_cropped_images_list)
97
  """
98
  preprocessed_images = []
99
  face_cropped_images = []
@@ -132,13 +187,13 @@ def preprocess_video(
132
  cv2.imwrite(preprocessed_path, cv2.cvtColor(rgb_frame, cv2.COLOR_RGB2BGR))
133
  preprocessed_images.append(preprocessed_path)
134
 
135
- # Face detection optimization: detect on downscaled frame, crop from original
136
- # Using 0.25 scale factor (4x smaller) for ~4-16x speedup
137
- scale_factor = 0.25
138
  small_frame = cv2.resize(rgb_frame, (0, 0), fx=scale_factor, fy=scale_factor)
139
 
140
  # Detect faces on the smaller frame
141
- face_locations_small = face_recognition.face_locations(small_frame)
142
 
143
  if len(face_locations_small) > 0:
144
  # Scale bounding box back to original resolution
 
3
  from torchvision import transforms
4
  import cv2
5
  import numpy as np
 
6
  from typing import List, Generator, Tuple
7
  import os
8
  import base64
 
21
  transforms.Normalize(MEAN, STD)
22
  ])
23
 
24
+ # OpenCV DNN face detector (lightweight, no dlib needed)
25
+ # Using OpenCV's built-in DNN face detector
26
+ _face_detector = None
27
+
28
+ def get_face_detector():
29
+ """
30
+ Get or initialize the OpenCV DNN face detector.
31
+ Uses OpenCV's built-in Caffe model for face detection.
32
+ """
33
+ global _face_detector
34
+ if _face_detector is None:
35
+ # Use OpenCV's built-in Haar Cascade as fallback (always available)
36
+ cascade_path = cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
37
+ _face_detector = cv2.CascadeClassifier(cascade_path)
38
+ return _face_detector
39
+
40
+
41
+ def detect_faces_opencv(frame: np.ndarray) -> List[Tuple[int, int, int, int]]:
42
+ """
43
+ Detect faces using OpenCV's Haar Cascade detector.
44
+
45
+ Args:
46
+ frame: RGB image as numpy array
47
+
48
+ Returns:
49
+ List of face locations as (top, right, bottom, left) tuples
50
+ (same format as face_recognition library for compatibility)
51
+ """
52
+ detector = get_face_detector()
53
+
54
+ # Convert to grayscale for Haar cascade
55
+ gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
56
+
57
+ # Detect faces
58
+ faces = detector.detectMultiScale(
59
+ gray,
60
+ scaleFactor=1.1,
61
+ minNeighbors=5,
62
+ minSize=(30, 30),
63
+ flags=cv2.CASCADE_SCALE_IMAGE
64
+ )
65
+
66
+ # Convert from (x, y, w, h) to (top, right, bottom, left) format
67
+ face_locations = []
68
+ for (x, y, w, h) in faces:
69
+ top = y
70
+ right = x + w
71
+ bottom = y + h
72
+ left = x
73
+ face_locations.append((top, right, bottom, left))
74
+
75
+ return face_locations
76
+
77
 
78
  class ValidationDataset(Dataset):
79
  """
 
94
 
95
  # Extract frames from video
96
  for i, frame in enumerate(self.frame_extract(self.video_path)):
97
+ # Convert BGR to RGB
98
+ rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
99
+
100
+ # Detect face in frame using OpenCV
101
+ faces = detect_faces_opencv(rgb_frame)
102
  try:
103
  top, right, bottom, left = faces[0]
104
+ frame = rgb_frame[top:bottom, left:right, :]
105
  except (IndexError, ValueError):
106
  # No face detected, use full frame
107
+ frame = rgb_frame
108
 
109
  frames.append(self.transform(frame))
110
 
 
148
  output_dir: Directory to save preprocessed images
149
 
150
  Returns:
151
+ Tuple of (preprocessed_tensor, preprocessed_images_list, face_cropped_images_list, faces_found)
152
  """
153
  preprocessed_images = []
154
  face_cropped_images = []
 
187
  cv2.imwrite(preprocessed_path, cv2.cvtColor(rgb_frame, cv2.COLOR_RGB2BGR))
188
  preprocessed_images.append(preprocessed_path)
189
 
190
+ # Face detection using OpenCV (much lighter than dlib/face_recognition)
191
+ # Using scaled frame for faster detection
192
+ scale_factor = 0.5 # Less aggressive scaling since Haar is already fast
193
  small_frame = cv2.resize(rgb_frame, (0, 0), fx=scale_factor, fy=scale_factor)
194
 
195
  # Detect faces on the smaller frame
196
+ face_locations_small = detect_faces_opencv(small_frame)
197
 
198
  if len(face_locations_small) > 0:
199
  # Scale bounding box back to original resolution
requirements.txt CHANGED
@@ -2,7 +2,6 @@ fastapi==0.115.0
2
  uvicorn[standard]==0.32.0
3
  python-multipart==0.0.12
4
  opencv-python-headless==4.10.0.84
5
- face-recognition==1.3.0
6
  pillow==11.0.0
7
  numpy==1.26.4
8
  python-dotenv==1.0.1
 
2
  uvicorn[standard]==0.32.0
3
  python-multipart==0.0.12
4
  opencv-python-headless==4.10.0.84
 
5
  pillow==11.0.0
6
  numpy==1.26.4
7
  python-dotenv==1.0.1