chawin.chen commited on
Commit ·
12e11fd
1
Parent(s): 834f756
fix: replace facial landmarks with robust bounding boxes in face_verify
Browse files- api_routes.py +23 -38
api_routes.py
CHANGED
|
@@ -4561,17 +4561,13 @@ async def face_similarity_verification(
|
|
| 4561 |
img1_region = facial_areas.get("img1", {})
|
| 4562 |
img2_region = facial_areas.get("img2", {})
|
| 4563 |
|
| 4564 |
-
|
| 4565 |
-
if analyzer is None:
|
| 4566 |
-
_ensure_analyzer()
|
| 4567 |
-
|
| 4568 |
-
def _apply_landmarks_on_original(
|
| 4569 |
source_image: np.ndarray,
|
| 4570 |
region: dict,
|
| 4571 |
label: str,
|
| 4572 |
) -> Tuple[np.ndarray, bool]:
|
| 4573 |
-
if
|
| 4574 |
-
return source_image, False
|
| 4575 |
try:
|
| 4576 |
x = max(0, region.get("x", 0))
|
| 4577 |
y = max(0, region.get("y", 0))
|
|
@@ -4579,19 +4575,21 @@ async def face_similarity_verification(
|
|
| 4579 |
h = region.get("h", 0)
|
| 4580 |
x_end = min(source_image.shape[1], x + w)
|
| 4581 |
y_end = min(source_image.shape[0], y + h)
|
|
|
|
| 4582 |
if x_end <= x or y_end <= y:
|
| 4583 |
-
return source_image, False
|
|
|
|
| 4584 |
result_img = source_image.copy()
|
| 4585 |
-
|
| 4586 |
-
|
| 4587 |
-
result_img
|
| 4588 |
return result_img, True
|
| 4589 |
except Exception as exc:
|
| 4590 |
-
logger.warning(f"Failed to draw
|
| 4591 |
-
return source_image, False
|
| 4592 |
|
| 4593 |
-
original_output_img1,
|
| 4594 |
-
original_output_img2,
|
| 4595 |
|
| 4596 |
if save_image_high_quality(original_output_img1, original_path1, quality=SAVE_QUALITY):
|
| 4597 |
await _record_output_file(
|
|
@@ -4600,8 +4598,8 @@ async def face_similarity_verification(
|
|
| 4600 |
category="original",
|
| 4601 |
extra={
|
| 4602 |
"source": "face_verify",
|
| 4603 |
-
"role": "
|
| 4604 |
-
"
|
| 4605 |
},
|
| 4606 |
)
|
| 4607 |
if save_image_high_quality(original_output_img2, original_path2, quality=SAVE_QUALITY):
|
|
@@ -4611,8 +4609,8 @@ async def face_similarity_verification(
|
|
| 4611 |
category="original",
|
| 4612 |
extra={
|
| 4613 |
"source": "face_verify",
|
| 4614 |
-
"role": "
|
| 4615 |
-
"
|
| 4616 |
},
|
| 4617 |
)
|
| 4618 |
|
|
@@ -4635,39 +4633,26 @@ async def face_similarity_verification(
|
|
| 4635 |
|
| 4636 |
face_path1 = os.path.join(IMAGES_DIR, face_filename1)
|
| 4637 |
face_path2 = os.path.join(IMAGES_DIR, face_filename2)
|
| 4638 |
-
|
| 4639 |
-
|
| 4640 |
-
|
| 4641 |
-
return face_img, False
|
| 4642 |
-
try:
|
| 4643 |
-
return analyzer.facial_analyzer.draw_facial_landmarks(face_img.copy()), True
|
| 4644 |
-
except Exception as exc:
|
| 4645 |
-
logger.warning(f"Failed to draw facial landmarks on face{face_index}: {exc}")
|
| 4646 |
-
return face_img, False
|
| 4647 |
-
|
| 4648 |
-
face_output_img1, face1_has_landmarks = _prepare_face_image(face_img1, 1)
|
| 4649 |
-
face_output_img2, face2_has_landmarks = _prepare_face_image(face_img2, 2)
|
| 4650 |
-
|
| 4651 |
-
if save_image_high_quality(face_output_img1, face_path1, quality=SAVE_QUALITY):
|
| 4652 |
await _record_output_file(
|
| 4653 |
file_path=face_path1,
|
| 4654 |
nickname=nickname,
|
| 4655 |
category="face",
|
| 4656 |
extra={
|
| 4657 |
"source": "face_verify",
|
| 4658 |
-
"role": "
|
| 4659 |
-
"with_landmarks": face1_has_landmarks,
|
| 4660 |
},
|
| 4661 |
)
|
| 4662 |
-
if save_image_high_quality(
|
| 4663 |
await _record_output_file(
|
| 4664 |
file_path=face_path2,
|
| 4665 |
nickname=nickname,
|
| 4666 |
category="face",
|
| 4667 |
extra={
|
| 4668 |
"source": "face_verify",
|
| 4669 |
-
"role": "
|
| 4670 |
-
"with_landmarks": face2_has_landmarks,
|
| 4671 |
},
|
| 4672 |
)
|
| 4673 |
except Exception as e:
|
|
|
|
| 4561 |
img1_region = facial_areas.get("img1", {})
|
| 4562 |
img2_region = facial_areas.get("img2", {})
|
| 4563 |
|
| 4564 |
+
def _apply_box_on_original(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4565 |
source_image: np.ndarray,
|
| 4566 |
region: dict,
|
| 4567 |
label: str,
|
| 4568 |
) -> Tuple[np.ndarray, bool]:
|
| 4569 |
+
if not region:
|
| 4570 |
+
return source_image.copy(), False
|
| 4571 |
try:
|
| 4572 |
x = max(0, region.get("x", 0))
|
| 4573 |
y = max(0, region.get("y", 0))
|
|
|
|
| 4575 |
h = region.get("h", 0)
|
| 4576 |
x_end = min(source_image.shape[1], x + w)
|
| 4577 |
y_end = min(source_image.shape[0], y + h)
|
| 4578 |
+
|
| 4579 |
if x_end <= x or y_end <= y:
|
| 4580 |
+
return source_image.copy(), False
|
| 4581 |
+
|
| 4582 |
result_img = source_image.copy()
|
| 4583 |
+
# 绘制绿色矩形框,厚度根据图片尺寸动态调整
|
| 4584 |
+
thickness = max(2, int(round(min(source_image.shape[:2]) / 200)))
|
| 4585 |
+
cv2.rectangle(result_img, (x, y), (x_end, y_end), (0, 255, 0), thickness)
|
| 4586 |
return result_img, True
|
| 4587 |
except Exception as exc:
|
| 4588 |
+
logger.warning(f"Failed to draw face box on original image {label}: {exc}")
|
| 4589 |
+
return source_image.copy(), False
|
| 4590 |
|
| 4591 |
+
original_output_img1, original1_has_box = _apply_box_on_original(image1, img1_region, "1")
|
| 4592 |
+
original_output_img2, original2_has_box = _apply_box_on_original(image2, img2_region, "2")
|
| 4593 |
|
| 4594 |
if save_image_high_quality(original_output_img1, original_path1, quality=SAVE_QUALITY):
|
| 4595 |
await _record_output_file(
|
|
|
|
| 4598 |
category="original",
|
| 4599 |
extra={
|
| 4600 |
"source": "face_verify",
|
| 4601 |
+
"role": "original1",
|
| 4602 |
+
"has_box": original1_has_box,
|
| 4603 |
},
|
| 4604 |
)
|
| 4605 |
if save_image_high_quality(original_output_img2, original_path2, quality=SAVE_QUALITY):
|
|
|
|
| 4609 |
category="original",
|
| 4610 |
extra={
|
| 4611 |
"source": "face_verify",
|
| 4612 |
+
"role": "original2",
|
| 4613 |
+
"has_box": original2_has_box,
|
| 4614 |
},
|
| 4615 |
)
|
| 4616 |
|
|
|
|
| 4633 |
|
| 4634 |
face_path1 = os.path.join(IMAGES_DIR, face_filename1)
|
| 4635 |
face_path2 = os.path.join(IMAGES_DIR, face_filename2)
|
| 4636 |
+
|
| 4637 |
+
# 直接保存裁剪图,不进行特征点绘制
|
| 4638 |
+
if save_image_high_quality(face_img1, face_path1, quality=SAVE_QUALITY):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4639 |
await _record_output_file(
|
| 4640 |
file_path=face_path1,
|
| 4641 |
nickname=nickname,
|
| 4642 |
category="face",
|
| 4643 |
extra={
|
| 4644 |
"source": "face_verify",
|
| 4645 |
+
"role": "face1",
|
|
|
|
| 4646 |
},
|
| 4647 |
)
|
| 4648 |
+
if save_image_high_quality(face_img2, face_path2, quality=SAVE_QUALITY):
|
| 4649 |
await _record_output_file(
|
| 4650 |
file_path=face_path2,
|
| 4651 |
nickname=nickname,
|
| 4652 |
category="face",
|
| 4653 |
extra={
|
| 4654 |
"source": "face_verify",
|
| 4655 |
+
"role": "face2",
|
|
|
|
| 4656 |
},
|
| 4657 |
)
|
| 4658 |
except Exception as e:
|