Spaces:
Paused
Paused
chawin.chen
commited on
Commit
·
bf03b10
1
Parent(s):
7a6cb13
init
Browse files- config.py +2 -0
- face_analyzer.py +66 -30
config.py
CHANGED
|
@@ -298,6 +298,8 @@ IMG_QUALITY = float(os.environ.get("IMG_QUALITY", 0.5))
|
|
| 298 |
FACE_CONFIDENCE = float(os.environ.get("FACE_CONFIDENCE", 0.7))
|
| 299 |
AGE_CONFIDENCE = float(os.environ.get("AGE_CONFIDENCE", 0.99))
|
| 300 |
GENDER_CONFIDENCE = float(os.environ.get("GENDER_CONFIDENCE", 1.1))
|
|
|
|
|
|
|
| 301 |
UPSCALE_SIZE = int(os.environ.get("UPSCALE_SIZE", 2))
|
| 302 |
SAVE_QUALITY = int(os.environ.get("SAVE_QUALITY", 85))
|
| 303 |
REALESRGAN_MODEL = os.environ.get("REALESRGAN_MODEL", "realesr-general-x4v3")
|
|
|
|
| 298 |
FACE_CONFIDENCE = float(os.environ.get("FACE_CONFIDENCE", 0.7))
|
| 299 |
AGE_CONFIDENCE = float(os.environ.get("AGE_CONFIDENCE", 0.99))
|
| 300 |
GENDER_CONFIDENCE = float(os.environ.get("GENDER_CONFIDENCE", 1.1))
|
| 301 |
+
# 是否启用 DeepFace 的情绪识别(默认开启;关闭可减少推理耗时)
|
| 302 |
+
DEEPFACE_EMOTION_ENABLED = os.environ.get("DEEPFACE_EMOTION_ENABLED", "true").lower() in ("1", "true", "on")
|
| 303 |
UPSCALE_SIZE = int(os.environ.get("UPSCALE_SIZE", 2))
|
| 304 |
SAVE_QUALITY = int(os.environ.get("SAVE_QUALITY", 85))
|
| 305 |
REALESRGAN_MODEL = os.environ.get("REALESRGAN_MODEL", "realesr-general-x4v3")
|
face_analyzer.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import os
|
| 2 |
import random
|
| 3 |
import time
|
| 4 |
-
from typing import List, Dict, Any
|
| 5 |
|
| 6 |
import cv2
|
| 7 |
import numpy as np
|
|
@@ -485,7 +485,7 @@ class EnhancedFaceAnalyzer:
|
|
| 485 |
raise e
|
| 486 |
|
| 487 |
def _predict_age_emotion_with_deepface(
|
| 488 |
-
self, face_image: np.ndarray
|
| 489 |
) -> Dict[str, Any]:
|
| 490 |
"""使用DeepFace预测年龄、情绪(并返回可用的性别信息用于回退)"""
|
| 491 |
if not DEEPFACE_AVAILABLE:
|
|
@@ -496,10 +496,11 @@ class EnhancedFaceAnalyzer:
|
|
| 496 |
raise ValueError("无效的人脸图像")
|
| 497 |
|
| 498 |
try:
|
|
|
|
| 499 |
# DeepFace分析 - 禁用进度条和详细输出
|
| 500 |
result = DeepFace.analyze(
|
| 501 |
img_path=face_image,
|
| 502 |
-
actions=
|
| 503 |
enforce_detection=False,
|
| 504 |
detector_backend="skip",
|
| 505 |
silent=True # 禁用进度条输出
|
|
@@ -511,8 +512,12 @@ class EnhancedFaceAnalyzer:
|
|
| 511 |
|
| 512 |
# 提取信息
|
| 513 |
age = result.get("age", 25)
|
| 514 |
-
|
| 515 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 516 |
# 性别信息(用于在HowCuteAmI置信度低时回退)
|
| 517 |
deep_gender = result.get("dominant_gender", "Woman")
|
| 518 |
deep_gender_conf = result.get("gender", {}).get(deep_gender, 50.0) / 100.0
|
|
@@ -576,6 +581,10 @@ class EnhancedFaceAnalyzer:
|
|
| 576 |
# 使用HowCuteAmI预测颜值和性别
|
| 577 |
beauty_gender_result = self._predict_beauty_gender_with_howcuteami(face)
|
| 578 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 579 |
# 首先获取HowCuteAmI的年龄/性别预测置信度
|
| 580 |
howcuteami_age_confidence = beauty_gender_result.get("age_confidence", 0)
|
| 581 |
gender_confidence = beauty_gender_result.get("gender_confidence", 0)
|
|
@@ -586,9 +595,9 @@ class EnhancedFaceAnalyzer:
|
|
| 586 |
# 如果HowCuteAmI的年龄置信度低于阈值,则使用DeepFace的年龄
|
| 587 |
agec = config.AGE_CONFIDENCE
|
| 588 |
if howcuteami_age_confidence < agec:
|
| 589 |
-
#
|
| 590 |
age_emotion_result = self._predict_age_emotion_with_deepface(
|
| 591 |
-
face_image
|
| 592 |
)
|
| 593 |
deep_age = age_emotion_result["age"]
|
| 594 |
logger.info(
|
|
@@ -602,8 +611,8 @@ class EnhancedFaceAnalyzer:
|
|
| 602 |
"beauty_raw_score": beauty_gender_result["beauty_raw_score"],
|
| 603 |
"age": deep_age,
|
| 604 |
"age_confidence": age_emotion_result["age_confidence"],
|
| 605 |
-
"emotion": age_emotion_result
|
| 606 |
-
"emotion_analysis": age_emotion_result
|
| 607 |
"model_used": "hybrid_deepface_age",
|
| 608 |
"age_model_used": "DeepFace",
|
| 609 |
"gender_model_used": "HowCuteAmI",
|
|
@@ -613,6 +622,16 @@ class EnhancedFaceAnalyzer:
|
|
| 613 |
logger.info(
|
| 614 |
f"HowCuteAmI age confidence ({howcuteami_age_confidence}) is high enough, value={age}; using HowCuteAmI for age prediction"
|
| 615 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 616 |
# 合并结果,保留HowCuteAmI的年龄预测
|
| 617 |
result = {
|
| 618 |
"gender": beauty_gender_result["gender"], # 先用HowCuteAmI,后面可能回退
|
|
@@ -621,8 +640,8 @@ class EnhancedFaceAnalyzer:
|
|
| 621 |
"beauty_raw_score": beauty_gender_result["beauty_raw_score"],
|
| 622 |
"age": beauty_gender_result["age"],
|
| 623 |
"age_confidence": beauty_gender_result["age_confidence"],
|
| 624 |
-
"emotion":
|
| 625 |
-
"emotion_analysis":
|
| 626 |
"model_used": "hybrid",
|
| 627 |
"age_model_used": "HowCuteAmI",
|
| 628 |
"gender_model_used": "HowCuteAmI",
|
|
@@ -632,8 +651,8 @@ class EnhancedFaceAnalyzer:
|
|
| 632 |
try:
|
| 633 |
how_gender = beauty_gender_result.get("gender")
|
| 634 |
how_conf = float(beauty_gender_result.get("gender_confidence", 0) or 0)
|
| 635 |
-
deep_gender = age_emotion_result.get("gender")
|
| 636 |
-
deep_conf = float(age_emotion_result.get("gender_confidence", 0) or 0)
|
| 637 |
|
| 638 |
final_gender = result.get("gender")
|
| 639 |
final_conf = float(result.get("gender_confidence", 0) or 0)
|
|
@@ -714,10 +733,12 @@ class EnhancedFaceAnalyzer:
|
|
| 714 |
raise ValueError("无效的人脸图像")
|
| 715 |
|
| 716 |
try:
|
|
|
|
|
|
|
| 717 |
# DeepFace分析 - 禁用进度条和详细输出
|
| 718 |
result = DeepFace.analyze(
|
| 719 |
img_path=face_image,
|
| 720 |
-
actions=
|
| 721 |
enforce_detection=False,
|
| 722 |
detector_backend="skip",
|
| 723 |
silent=True # 禁用进度条输出
|
|
@@ -740,8 +761,12 @@ class EnhancedFaceAnalyzer:
|
|
| 740 |
gender = "Male"
|
| 741 |
|
| 742 |
# DeepFace没有内置颜值评分,这里使用简单的启发式方法
|
| 743 |
-
|
| 744 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 745 |
|
| 746 |
# 基于情绪和年龄的简单颜值估算
|
| 747 |
happiness_score = emotion_scores.get("happy", 0) / 100
|
|
@@ -835,10 +860,10 @@ class EnhancedFaceAnalyzer:
|
|
| 835 |
)
|
| 836 |
elif model_type == ModelType.HOWCUTEAMI:
|
| 837 |
prediction_result = self._predict_with_howcuteami(face_resized)
|
| 838 |
-
# 非混合模式也进行性别合并:引入DeepFace
|
| 839 |
try:
|
| 840 |
age_emotion_result = self._predict_age_emotion_with_deepface(
|
| 841 |
-
face_for_deepface
|
| 842 |
)
|
| 843 |
how_gender = prediction_result.get("gender")
|
| 844 |
how_conf = float(prediction_result.get("gender_confidence", 0) or 0)
|
|
@@ -848,13 +873,17 @@ class EnhancedFaceAnalyzer:
|
|
| 848 |
final_conf = float(prediction_result.get("gender_confidence", 0) or 0)
|
| 849 |
if (str(how_gender) == "Female") or (str(deep_gender) == "Female"):
|
| 850 |
final_gender = "Female"
|
| 851 |
-
final_conf = max(
|
| 852 |
-
|
|
|
|
|
|
|
| 853 |
prediction_result["gender_model_used"] = "Combined(H+DF)"
|
| 854 |
elif (str(how_gender) == "Male") and (str(deep_gender) == "Male"):
|
| 855 |
final_gender = "Male"
|
| 856 |
-
final_conf = max(
|
| 857 |
-
|
|
|
|
|
|
|
| 858 |
prediction_result["gender_model_used"] = "Combined(H+DF)"
|
| 859 |
prediction_result["gender"] = final_gender
|
| 860 |
prediction_result["gender_confidence"] = round(float(final_conf), 4)
|
|
@@ -875,13 +904,17 @@ class EnhancedFaceAnalyzer:
|
|
| 875 |
final_conf = float(prediction_result.get("gender_confidence", 0) or 0)
|
| 876 |
if (str(how_gender) == "Female") or (str(deep_gender) == "Female"):
|
| 877 |
final_gender = "Female"
|
| 878 |
-
final_conf = max(
|
| 879 |
-
|
|
|
|
|
|
|
| 880 |
prediction_result["gender_model_used"] = "Combined(H+DF)"
|
| 881 |
elif (str(how_gender) == "Male") and (str(deep_gender) == "Male"):
|
| 882 |
final_gender = "Male"
|
| 883 |
-
final_conf = max(
|
| 884 |
-
|
|
|
|
|
|
|
| 885 |
prediction_result["gender_model_used"] = "Combined(H+DF)"
|
| 886 |
prediction_result["gender"] = final_gender
|
| 887 |
prediction_result["gender_confidence"] = round(float(final_conf), 4)
|
|
@@ -892,7 +925,9 @@ class EnhancedFaceAnalyzer:
|
|
| 892 |
prediction_result = self._predict_with_hybrid_model(
|
| 893 |
face_resized, face_for_deepface
|
| 894 |
)
|
| 895 |
-
logger.warning(
|
|
|
|
|
|
|
| 896 |
|
| 897 |
except Exception as e:
|
| 898 |
logger.error(f"Prediction failed, using default values: {e}")
|
|
@@ -1016,8 +1051,8 @@ class EnhancedFaceAnalyzer:
|
|
| 1016 |
"age_model_used": prediction_result.get("age_model_used", prediction_result.get("model_used", model_type.value)),
|
| 1017 |
"beauty_score": prediction_result.get("beauty_score", 0),
|
| 1018 |
"beauty_raw_score": prediction_result.get("beauty_raw_score", 0),
|
| 1019 |
-
"emotion": prediction_result.get("emotion"
|
| 1020 |
-
"emotion_analysis": prediction_result.get("emotion_analysis"
|
| 1021 |
# "facial_features": facial_features, # 五官分析
|
| 1022 |
"bounding_box": {
|
| 1023 |
"x1": int(face_box[0]),
|
|
@@ -1054,12 +1089,13 @@ class EnhancedFaceAnalyzer:
|
|
| 1054 |
if DEEPFACE_AVAILABLE:
|
| 1055 |
try:
|
| 1056 |
import tempfile
|
|
|
|
| 1057 |
with tempfile.NamedTemporaryFile(suffix='.webp', delete=False) as tmp_file:
|
| 1058 |
cv2.imwrite(tmp_file.name, test_image, [cv2.IMWRITE_WEBP_QUALITY, 95])
|
| 1059 |
# 预热DeepFace - 使用最小的actions集合
|
| 1060 |
DeepFace.analyze(
|
| 1061 |
img_path=tmp_file.name,
|
| 1062 |
-
actions=["age", "emotion", "gender"],
|
| 1063 |
detector_backend="yolov8",
|
| 1064 |
enforce_detection=False,
|
| 1065 |
silent=True
|
|
|
|
| 1 |
import os
|
| 2 |
import random
|
| 3 |
import time
|
| 4 |
+
from typing import List, Dict, Any, Optional
|
| 5 |
|
| 6 |
import cv2
|
| 7 |
import numpy as np
|
|
|
|
| 485 |
raise e
|
| 486 |
|
| 487 |
def _predict_age_emotion_with_deepface(
|
| 488 |
+
self, face_image: np.ndarray, include_emotion: bool = True
|
| 489 |
) -> Dict[str, Any]:
|
| 490 |
"""使用DeepFace预测年龄、情绪(并返回可用的性别信息用于回退)"""
|
| 491 |
if not DEEPFACE_AVAILABLE:
|
|
|
|
| 496 |
raise ValueError("无效的人脸图像")
|
| 497 |
|
| 498 |
try:
|
| 499 |
+
actions = ["age", "gender", "emotion"] if include_emotion else ["age", "gender"]
|
| 500 |
# DeepFace分析 - 禁用进度条和详细输出
|
| 501 |
result = DeepFace.analyze(
|
| 502 |
img_path=face_image,
|
| 503 |
+
actions=actions,
|
| 504 |
enforce_detection=False,
|
| 505 |
detector_backend="skip",
|
| 506 |
silent=True # 禁用进度条输出
|
|
|
|
| 512 |
|
| 513 |
# 提取信息
|
| 514 |
age = result.get("age", 25)
|
| 515 |
+
if include_emotion:
|
| 516 |
+
emotion = result.get("dominant_emotion", "neutral")
|
| 517 |
+
emotion_scores = result.get("emotion", {}) or {}
|
| 518 |
+
else:
|
| 519 |
+
emotion = "neutral"
|
| 520 |
+
emotion_scores = {"neutral": 100.0}
|
| 521 |
# 性别信息(用于在HowCuteAmI置信度低时回退)
|
| 522 |
deep_gender = result.get("dominant_gender", "Woman")
|
| 523 |
deep_gender_conf = result.get("gender", {}).get(deep_gender, 50.0) / 100.0
|
|
|
|
| 581 |
# 使用HowCuteAmI预测颜值和性别
|
| 582 |
beauty_gender_result = self._predict_beauty_gender_with_howcuteami(face)
|
| 583 |
|
| 584 |
+
# Hybrid 模式下可配置是否启用 DeepFace 情绪识别(默认启用)。
|
| 585 |
+
deepface_emotion_enabled = bool(getattr(config, "DEEPFACE_EMOTION_ENABLED", True))
|
| 586 |
+
age_emotion_result: Optional[Dict[str, Any]] = None
|
| 587 |
+
|
| 588 |
# 首先获取HowCuteAmI的年龄/性别预测置信度
|
| 589 |
howcuteami_age_confidence = beauty_gender_result.get("age_confidence", 0)
|
| 590 |
gender_confidence = beauty_gender_result.get("gender_confidence", 0)
|
|
|
|
| 595 |
# 如果HowCuteAmI的年龄置信度低于阈值,则使用DeepFace的年龄
|
| 596 |
agec = config.AGE_CONFIDENCE
|
| 597 |
if howcuteami_age_confidence < agec:
|
| 598 |
+
# 需要 DeepFace 年龄时,仍调用 DeepFace(但可按开关选择是否同时跑 emotion)
|
| 599 |
age_emotion_result = self._predict_age_emotion_with_deepface(
|
| 600 |
+
face_image, include_emotion=deepface_emotion_enabled
|
| 601 |
)
|
| 602 |
deep_age = age_emotion_result["age"]
|
| 603 |
logger.info(
|
|
|
|
| 611 |
"beauty_raw_score": beauty_gender_result["beauty_raw_score"],
|
| 612 |
"age": deep_age,
|
| 613 |
"age_confidence": age_emotion_result["age_confidence"],
|
| 614 |
+
"emotion": age_emotion_result.get("emotion") or "neutral",
|
| 615 |
+
"emotion_analysis": age_emotion_result.get("emotion_analysis") or {"neutral": 100.0},
|
| 616 |
"model_used": "hybrid_deepface_age",
|
| 617 |
"age_model_used": "DeepFace",
|
| 618 |
"gender_model_used": "HowCuteAmI",
|
|
|
|
| 622 |
logger.info(
|
| 623 |
f"HowCuteAmI age confidence ({howcuteami_age_confidence}) is high enough, value={age}; using HowCuteAmI for age prediction"
|
| 624 |
)
|
| 625 |
+
# 情绪识别完全可选:关闭时直接返回默认值,避免多一次 DeepFace 推理。
|
| 626 |
+
if deepface_emotion_enabled:
|
| 627 |
+
age_emotion_result = self._predict_age_emotion_with_deepface(
|
| 628 |
+
face_image, include_emotion=True
|
| 629 |
+
)
|
| 630 |
+
emotion = age_emotion_result.get("emotion") or "neutral"
|
| 631 |
+
emotion_analysis = age_emotion_result.get("emotion_analysis") or {"neutral": 100.0}
|
| 632 |
+
else:
|
| 633 |
+
emotion = "neutral"
|
| 634 |
+
emotion_analysis = {"neutral": 100.0}
|
| 635 |
# 合并结果,保留HowCuteAmI的年龄预测
|
| 636 |
result = {
|
| 637 |
"gender": beauty_gender_result["gender"], # 先用HowCuteAmI,后面可能回退
|
|
|
|
| 640 |
"beauty_raw_score": beauty_gender_result["beauty_raw_score"],
|
| 641 |
"age": beauty_gender_result["age"],
|
| 642 |
"age_confidence": beauty_gender_result["age_confidence"],
|
| 643 |
+
"emotion": emotion,
|
| 644 |
+
"emotion_analysis": emotion_analysis,
|
| 645 |
"model_used": "hybrid",
|
| 646 |
"age_model_used": "HowCuteAmI",
|
| 647 |
"gender_model_used": "HowCuteAmI",
|
|
|
|
| 651 |
try:
|
| 652 |
how_gender = beauty_gender_result.get("gender")
|
| 653 |
how_conf = float(beauty_gender_result.get("gender_confidence", 0) or 0)
|
| 654 |
+
deep_gender = age_emotion_result.get("gender") if age_emotion_result else None
|
| 655 |
+
deep_conf = float(age_emotion_result.get("gender_confidence", 0) or 0) if age_emotion_result else 0.0
|
| 656 |
|
| 657 |
final_gender = result.get("gender")
|
| 658 |
final_conf = float(result.get("gender_confidence", 0) or 0)
|
|
|
|
| 733 |
raise ValueError("无效的人脸图像")
|
| 734 |
|
| 735 |
try:
|
| 736 |
+
deepface_emotion_enabled = bool(getattr(config, "DEEPFACE_EMOTION_ENABLED", True))
|
| 737 |
+
actions = ["age", "gender", "emotion"] if deepface_emotion_enabled else ["age", "gender"]
|
| 738 |
# DeepFace分析 - 禁用进度条和详细输出
|
| 739 |
result = DeepFace.analyze(
|
| 740 |
img_path=face_image,
|
| 741 |
+
actions=actions,
|
| 742 |
enforce_detection=False,
|
| 743 |
detector_backend="skip",
|
| 744 |
silent=True # 禁用进度条输出
|
|
|
|
| 761 |
gender = "Male"
|
| 762 |
|
| 763 |
# DeepFace没有内置颜值评分,这里使用简单的启发式方法
|
| 764 |
+
if deepface_emotion_enabled:
|
| 765 |
+
emotion = result.get("dominant_emotion", "neutral")
|
| 766 |
+
emotion_scores = result.get("emotion", {}) or {}
|
| 767 |
+
else:
|
| 768 |
+
emotion = "neutral"
|
| 769 |
+
emotion_scores = {"neutral": 100.0}
|
| 770 |
|
| 771 |
# 基于情绪和年龄的简单颜值估算
|
| 772 |
happiness_score = emotion_scores.get("happy", 0) / 100
|
|
|
|
| 860 |
)
|
| 861 |
elif model_type == ModelType.HOWCUTEAMI:
|
| 862 |
prediction_result = self._predict_with_howcuteami(face_resized)
|
| 863 |
+
# 非混合模式也进行性别合并:引入DeepFace性别(不需要 emotion,减少耗时)
|
| 864 |
try:
|
| 865 |
age_emotion_result = self._predict_age_emotion_with_deepface(
|
| 866 |
+
face_for_deepface, include_emotion=False
|
| 867 |
)
|
| 868 |
how_gender = prediction_result.get("gender")
|
| 869 |
how_conf = float(prediction_result.get("gender_confidence", 0) or 0)
|
|
|
|
| 873 |
final_conf = float(prediction_result.get("gender_confidence", 0) or 0)
|
| 874 |
if (str(how_gender) == "Female") or (str(deep_gender) == "Female"):
|
| 875 |
final_gender = "Female"
|
| 876 |
+
final_conf = max(
|
| 877 |
+
how_conf if how_gender == "Female" else 0,
|
| 878 |
+
deep_conf if deep_gender == "Female" else 0,
|
| 879 |
+
)
|
| 880 |
prediction_result["gender_model_used"] = "Combined(H+DF)"
|
| 881 |
elif (str(how_gender) == "Male") and (str(deep_gender) == "Male"):
|
| 882 |
final_gender = "Male"
|
| 883 |
+
final_conf = max(
|
| 884 |
+
how_conf if how_gender == "Male" else 0,
|
| 885 |
+
deep_conf if deep_gender == "Male" else 0,
|
| 886 |
+
)
|
| 887 |
prediction_result["gender_model_used"] = "Combined(H+DF)"
|
| 888 |
prediction_result["gender"] = final_gender
|
| 889 |
prediction_result["gender_confidence"] = round(float(final_conf), 4)
|
|
|
|
| 904 |
final_conf = float(prediction_result.get("gender_confidence", 0) or 0)
|
| 905 |
if (str(how_gender) == "Female") or (str(deep_gender) == "Female"):
|
| 906 |
final_gender = "Female"
|
| 907 |
+
final_conf = max(
|
| 908 |
+
how_conf if how_gender == "Female" else 0,
|
| 909 |
+
deep_conf if deep_gender == "Female" else 0,
|
| 910 |
+
)
|
| 911 |
prediction_result["gender_model_used"] = "Combined(H+DF)"
|
| 912 |
elif (str(how_gender) == "Male") and (str(deep_gender) == "Male"):
|
| 913 |
final_gender = "Male"
|
| 914 |
+
final_conf = max(
|
| 915 |
+
how_conf if how_gender == "Male" else 0,
|
| 916 |
+
deep_conf if deep_gender == "Male" else 0,
|
| 917 |
+
)
|
| 918 |
prediction_result["gender_model_used"] = "Combined(H+DF)"
|
| 919 |
prediction_result["gender"] = final_gender
|
| 920 |
prediction_result["gender_confidence"] = round(float(final_conf), 4)
|
|
|
|
| 925 |
prediction_result = self._predict_with_hybrid_model(
|
| 926 |
face_resized, face_for_deepface
|
| 927 |
)
|
| 928 |
+
logger.warning(
|
| 929 |
+
f"Model {model_type.value} is not available, using hybrid mode"
|
| 930 |
+
)
|
| 931 |
|
| 932 |
except Exception as e:
|
| 933 |
logger.error(f"Prediction failed, using default values: {e}")
|
|
|
|
| 1051 |
"age_model_used": prediction_result.get("age_model_used", prediction_result.get("model_used", model_type.value)),
|
| 1052 |
"beauty_score": prediction_result.get("beauty_score", 0),
|
| 1053 |
"beauty_raw_score": prediction_result.get("beauty_raw_score", 0),
|
| 1054 |
+
"emotion": prediction_result.get("emotion") or "neutral",
|
| 1055 |
+
"emotion_analysis": prediction_result.get("emotion_analysis") or {"neutral": 100.0},
|
| 1056 |
# "facial_features": facial_features, # 五官分析
|
| 1057 |
"bounding_box": {
|
| 1058 |
"x1": int(face_box[0]),
|
|
|
|
| 1089 |
if DEEPFACE_AVAILABLE:
|
| 1090 |
try:
|
| 1091 |
import tempfile
|
| 1092 |
+
deepface_emotion_enabled = bool(getattr(config, "DEEPFACE_EMOTION_ENABLED", True))
|
| 1093 |
with tempfile.NamedTemporaryFile(suffix='.webp', delete=False) as tmp_file:
|
| 1094 |
cv2.imwrite(tmp_file.name, test_image, [cv2.IMWRITE_WEBP_QUALITY, 95])
|
| 1095 |
# 预热DeepFace - 使用最小的actions集合
|
| 1096 |
DeepFace.analyze(
|
| 1097 |
img_path=tmp_file.name,
|
| 1098 |
+
actions=["age", "gender", "emotion"] if deepface_emotion_enabled else ["age", "gender"],
|
| 1099 |
detector_backend="yolov8",
|
| 1100 |
enforce_detection=False,
|
| 1101 |
silent=True
|