Spaces:
Sleeping
Sleeping
Vinh.Vu commited on
Commit ·
bb58d5b
1
Parent(s): d92592b
Detect multiple faces
Browse files- App/app.py +28 -12
App/app.py
CHANGED
|
@@ -115,7 +115,7 @@ def extract_faces_from_video(video_path):
|
|
| 115 |
results = face_det.detect(mp_image)
|
| 116 |
for detection in results.detections:
|
| 117 |
score = detection.categories[0].score
|
| 118 |
-
if
|
| 119 |
bbox = detection.bounding_box
|
| 120 |
bx, by, bw, bh = bbox.origin_x, bbox.origin_y, bbox.width, bbox.height
|
| 121 |
h, w = image_rgb.shape[:2]
|
|
@@ -135,12 +135,9 @@ def extract_faces_from_video(video_path):
|
|
| 135 |
return faces
|
| 136 |
|
| 137 |
|
| 138 |
-
def create_processed_video(video_path, output_path,
|
| 139 |
-
"""Re-encode video with face bounding boxes and
|
| 140 |
logger.info('Creating processed video with bounding boxes: %s', output_path)
|
| 141 |
-
is_real = avg_score is not None and avg_score > 0.5
|
| 142 |
-
label = 'REAL' if is_real else 'FAKE'
|
| 143 |
-
color = (0, 255, 0) if is_real else (0, 0, 255) # green / red in BGR
|
| 144 |
|
| 145 |
cap = cv2.VideoCapture(video_path)
|
| 146 |
fps = cap.get(cv2.CAP_PROP_FPS) or 30
|
|
@@ -167,13 +164,32 @@ def create_processed_video(video_path, output_path, avg_score):
|
|
| 167 |
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=image_rgb)
|
| 168 |
results = face_det.detect(mp_image)
|
| 169 |
for detection in results.detections:
|
| 170 |
-
|
| 171 |
-
if
|
| 172 |
bbox = detection.bounding_box
|
| 173 |
-
|
| 174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
cv2.rectangle(frame, (x, y), (x + bw, y + bh), color, 2)
|
| 176 |
-
text = f'{label} {
|
| 177 |
cv2.putText(frame, text, (x, y - 10),
|
| 178 |
cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
|
| 179 |
out.write(frame)
|
|
@@ -287,7 +303,7 @@ def process_video_job(job_id, filepath, unique_name):
|
|
| 287 |
logger.info('[Job %s] Starting video processing', job_id)
|
| 288 |
processed_name = f"processed_{unique_name}"
|
| 289 |
processed_path = os.path.join(app.config['UPLOAD_FOLDER'], processed_name)
|
| 290 |
-
create_processed_video(filepath, processed_path
|
| 291 |
|
| 292 |
logger.info('[Job %s] Video processing done', job_id)
|
| 293 |
jobs[job_id].update({
|
|
|
|
| 115 |
results = face_det.detect(mp_image)
|
| 116 |
for detection in results.detections:
|
| 117 |
score = detection.categories[0].score
|
| 118 |
+
if score > 0.5:
|
| 119 |
bbox = detection.bounding_box
|
| 120 |
bx, by, bw, bh = bbox.origin_x, bbox.origin_y, bbox.width, bbox.height
|
| 121 |
h, w = image_rgb.shape[:2]
|
|
|
|
| 135 |
return faces
|
| 136 |
|
| 137 |
|
| 138 |
+
def create_processed_video(video_path, output_path, face_scores=None):
|
| 139 |
+
"""Re-encode video with face bounding boxes and per-face REAL/FAKE label."""
|
| 140 |
logger.info('Creating processed video with bounding boxes: %s', output_path)
|
|
|
|
|
|
|
|
|
|
| 141 |
|
| 142 |
cap = cv2.VideoCapture(video_path)
|
| 143 |
fps = cap.get(cv2.CAP_PROP_FPS) or 30
|
|
|
|
| 164 |
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=image_rgb)
|
| 165 |
results = face_det.detect(mp_image)
|
| 166 |
for detection in results.detections:
|
| 167 |
+
det_score = detection.categories[0].score
|
| 168 |
+
if det_score > 0.5:
|
| 169 |
bbox = detection.bounding_box
|
| 170 |
+
bx, by, bw, bh = bbox.origin_x, bbox.origin_y, bbox.width, bbox.height
|
| 171 |
+
x, y = max(0, bx), max(0, by)
|
| 172 |
+
|
| 173 |
+
# Crop and predict this face individually
|
| 174 |
+
margin_x = int(bw * 0.3)
|
| 175 |
+
margin_y = int(bh * 0.3)
|
| 176 |
+
x1 = max(0, bx - margin_x)
|
| 177 |
+
x2 = min(w, bx + bw + margin_x)
|
| 178 |
+
y1 = max(0, by - margin_y)
|
| 179 |
+
y2 = min(h, by + bh + margin_y)
|
| 180 |
+
crop = image_rgb[y1:y2, x1:x2]
|
| 181 |
+
if crop.size > 0:
|
| 182 |
+
crop_resized = cv2.resize(crop, (INPUT_SIZE, INPUT_SIZE))
|
| 183 |
+
face_input = np.array([crop_resized], dtype='float32') / 255.0
|
| 184 |
+
score = float(model.predict(face_input, verbose=0)[0][0])
|
| 185 |
+
else:
|
| 186 |
+
score = 0.0
|
| 187 |
+
|
| 188 |
+
is_real = score > 0.5
|
| 189 |
+
label = 'REAL' if is_real else 'FAKE'
|
| 190 |
+
color = (0, 255, 0) if is_real else (0, 0, 255)
|
| 191 |
cv2.rectangle(frame, (x, y), (x + bw, y + bh), color, 2)
|
| 192 |
+
text = f'{label} {score:.2f}'
|
| 193 |
cv2.putText(frame, text, (x, y - 10),
|
| 194 |
cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
|
| 195 |
out.write(frame)
|
|
|
|
| 303 |
logger.info('[Job %s] Starting video processing', job_id)
|
| 304 |
processed_name = f"processed_{unique_name}"
|
| 305 |
processed_path = os.path.join(app.config['UPLOAD_FOLDER'], processed_name)
|
| 306 |
+
create_processed_video(filepath, processed_path)
|
| 307 |
|
| 308 |
logger.info('[Job %s] Video processing done', job_id)
|
| 309 |
jobs[job_id].update({
|