Spaces:
Sleeping
Sleeping
hakandinger
commited on
Commit
·
e04e6b0
1
Parent(s):
3d7d0e2
fix: handle ZeroDivisionError in embedding extraction
Browse files- app.py +64 -20
- core/comparator.py +0 -2
app.py
CHANGED
|
@@ -311,38 +311,82 @@ class FaceDetector:
|
|
| 311 |
|
| 312 |
def extract_embeddings(self, face_img: np.ndarray) -> Tuple[Optional[np.ndarray], Optional[np.ndarray]]:
|
| 313 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
detector, recognizer = self.models
|
| 315 |
bboxes, kpss = detector.autodetect(face_img, max_num=1)
|
| 316 |
if len(bboxes) == 0:
|
|
|
|
| 317 |
return None, None
|
| 318 |
kps = kpss[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
embedding = recognizer.get(face_img, kps)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 320 |
return embedding, kps
|
| 321 |
except Exception as e:
|
| 322 |
logger.error(f"Embedding çıkarma hatası: {e}")
|
| 323 |
return None, None
|
| 324 |
|
| 325 |
def calculate_face_quality(self, face_img: np.ndarray, face_size: float, kps: np.ndarray) -> float:
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 346 |
def process_frame(self, frame: np.ndarray) -> List[Dict]:
|
| 347 |
frame = cv2.resize(frame, (0, 0), fx=self.config.resize_factor, fy=self.config.resize_factor)
|
| 348 |
detector, _ = self.models
|
|
|
|
| 311 |
|
| 312 |
def extract_embeddings(self, face_img: np.ndarray) -> Tuple[Optional[np.ndarray], Optional[np.ndarray]]:
|
| 313 |
try:
|
| 314 |
+
if face_img is None or face_img.size == 0:
|
| 315 |
+
logger.warning("Boş veya None face_img")
|
| 316 |
+
return None, None
|
| 317 |
+
|
| 318 |
+
if face_img.shape[0] < 10 or face_img.shape[1] < 10:
|
| 319 |
+
logger.warning(f"Yüz çok küçük: {face_img.shape}")
|
| 320 |
+
return None, None
|
| 321 |
+
|
| 322 |
detector, recognizer = self.models
|
| 323 |
bboxes, kpss = detector.autodetect(face_img, max_num=1)
|
| 324 |
if len(bboxes) == 0:
|
| 325 |
+
logger.warning("Yüz tespit edilemedi")
|
| 326 |
return None, None
|
| 327 |
kps = kpss[0]
|
| 328 |
+
if kps is None or len(kps) < 5:
|
| 329 |
+
logger.warning("Geçersiz keypoints")
|
| 330 |
+
return None, None
|
| 331 |
+
|
| 332 |
embedding = recognizer.get(face_img, kps)
|
| 333 |
+
|
| 334 |
+
if embedding is None:
|
| 335 |
+
logger.warning("Embedding None döndü")
|
| 336 |
+
return None, None
|
| 337 |
+
|
| 338 |
+
if np.isnan(embedding).any() or np.isinf(embedding).any():
|
| 339 |
+
logger.warning("Embedding NaN veya Inf içeriyor")
|
| 340 |
+
return None, None
|
| 341 |
+
|
| 342 |
+
if np.allclose(embedding, 0):
|
| 343 |
+
logger.warning("Embedding sıfır vektör")
|
| 344 |
+
return None, None
|
| 345 |
+
|
| 346 |
return embedding, kps
|
| 347 |
except Exception as e:
|
| 348 |
logger.error(f"Embedding çıkarma hatası: {e}")
|
| 349 |
return None, None
|
| 350 |
|
| 351 |
def calculate_face_quality(self, face_img: np.ndarray, face_size: float, kps: np.ndarray) -> float:
|
| 352 |
+
try:
|
| 353 |
+
quality_score = 0
|
| 354 |
+
if face_size <= 0:
|
| 355 |
+
logger.warning("Geçersiz face_size: <= 0")
|
| 356 |
+
return 0.0
|
| 357 |
+
|
| 358 |
+
# Size score
|
| 359 |
+
size_score = min(face_size / 5000, 2.0)
|
| 360 |
+
quality_score += size_score
|
| 361 |
+
|
| 362 |
+
# Keypoint kontrolü
|
| 363 |
+
if kps is None or len(kps) < 5:
|
| 364 |
+
logger.warning("Geçersiz keypoints")
|
| 365 |
+
return quality_score
|
| 366 |
+
|
| 367 |
+
left_eye, right_eye = kps[0], kps[1]
|
| 368 |
+
eye_distance = np.linalg.norm(left_eye - right_eye)
|
| 369 |
+
face_width = np.sqrt(face_size)
|
| 370 |
+
if face_width <= 0:
|
| 371 |
+
logger.warning("face_width <= 0")
|
| 372 |
+
return quality_score
|
| 373 |
+
eye_ratio = eye_distance / face_width
|
| 374 |
+
angle_score = min(eye_ratio * 3, 2.0)
|
| 375 |
+
quality_score += angle_score
|
| 376 |
+
gray = cv2.cvtColor(face_img, cv2.COLOR_BGR2GRAY)
|
| 377 |
+
blur_var = cv2.Laplacian(gray, cv2.CV_64F).var()
|
| 378 |
+
blur_score = min(blur_var / 500, 2.0)
|
| 379 |
+
quality_score += blur_score
|
| 380 |
+
left_mouth, right_mouth = kps[3], kps[4]
|
| 381 |
+
mouth_distance = np.linalg.norm(left_mouth - right_mouth)
|
| 382 |
+
mouth_ratio = mouth_distance / face_width
|
| 383 |
+
symmetry_score = min(mouth_ratio * 3, 2.0)
|
| 384 |
+
quality_score += symmetry_score
|
| 385 |
+
return quality_score
|
| 386 |
+
except Exception as e:
|
| 387 |
+
logger.error(f"Quality hesaplama hatası: {e}")
|
| 388 |
+
return 1.0
|
| 389 |
+
|
| 390 |
def process_frame(self, frame: np.ndarray) -> List[Dict]:
|
| 391 |
frame = cv2.resize(frame, (0, 0), fx=self.config.resize_factor, fy=self.config.resize_factor)
|
| 392 |
detector, _ = self.models
|
core/comparator.py
CHANGED
|
@@ -407,12 +407,10 @@ Her iki videoda da bulunan kişiler:
|
|
| 407 |
|
| 408 |
report += f"""
|
| 409 |
### Video 1
|
| 410 |
-
- **Yol**: {result.metadata['video1']['path']}
|
| 411 |
- **Süre**: {result.metadata['video1']['duration']:.1f} saniye
|
| 412 |
- **FPS**: {result.metadata['video1']['fps']}
|
| 413 |
|
| 414 |
### Video 2
|
| 415 |
-
- **Yol**: {result.metadata['video2']['path']}
|
| 416 |
- **Süre**: {result.metadata['video2']['duration']:.1f} saniye
|
| 417 |
- **FPS**: {result.metadata['video2']['fps']}
|
| 418 |
|
|
|
|
| 407 |
|
| 408 |
report += f"""
|
| 409 |
### Video 1
|
|
|
|
| 410 |
- **Süre**: {result.metadata['video1']['duration']:.1f} saniye
|
| 411 |
- **FPS**: {result.metadata['video1']['fps']}
|
| 412 |
|
| 413 |
### Video 2
|
|
|
|
| 414 |
- **Süre**: {result.metadata['video2']['duration']:.1f} saniye
|
| 415 |
- **FPS**: {result.metadata['video2']['fps']}
|
| 416 |
|