REVERT demography.py

This commit is contained in:
h-alice 2025-01-16 17:17:25 +08:00
parent 7e719dfdeb
commit 6a7bbdb926
No known key found for this signature in database
GPG Key ID: 5708F34144A70909

View File

@ -1,5 +1,5 @@
# built-in dependencies # built-in dependencies
from typing import Any, Dict, List, Union, Optional from typing import Any, Dict, List, Union
# 3rd party dependencies # 3rd party dependencies
import numpy as np import numpy as np
@ -9,6 +9,7 @@ from tqdm import tqdm
from deepface.modules import modeling, detection, preprocessing from deepface.modules import modeling, detection, preprocessing
from deepface.models.demography import Gender, Race, Emotion from deepface.models.demography import Gender, Race, Emotion
def analyze( def analyze(
img_path: Union[str, np.ndarray], img_path: Union[str, np.ndarray],
actions: Union[tuple, list] = ("emotion", "age", "gender", "race"), actions: Union[tuple, list] = ("emotion", "age", "gender", "race"),
@ -116,6 +117,8 @@ def analyze(
f"Invalid action passed ({repr(action)})). " f"Invalid action passed ({repr(action)})). "
"Valid actions are `emotion`, `age`, `gender`, `race`." "Valid actions are `emotion`, `age`, `gender`, `race`."
) )
# ---------------------------------
resp_objects = []
img_objs = detection.extract_faces( img_objs = detection.extract_faces(
img_path=img_path, img_path=img_path,
@ -127,105 +130,84 @@ def analyze(
anti_spoofing=anti_spoofing, anti_spoofing=anti_spoofing,
) )
if anti_spoofing and any(img_obj.get("is_real", True) is False for img_obj in img_objs): for img_obj in img_objs:
if anti_spoofing is True and img_obj.get("is_real", True) is False:
raise ValueError("Spoof detected in the given image.") raise ValueError("Spoof detected in the given image.")
def preprocess_face(img_obj: Dict[str, Any]) -> Optional[np.ndarray]:
"""
Preprocess the face image for analysis.
"""
img_content = img_obj["face"] img_content = img_obj["face"]
img_region = img_obj["facial_area"]
img_confidence = img_obj["confidence"]
if img_content.shape[0] == 0 or img_content.shape[1] == 0: if img_content.shape[0] == 0 or img_content.shape[1] == 0:
return None continue
img_content = img_content[:, :, ::-1] # BGR to RGB
return preprocessing.resize_image(img=img_content, target_size=(224, 224))
# Filter out empty faces # rgb to bgr
face_data = [ img_content = img_content[:, :, ::-1]
(
preprocess_face(img_obj),
img_obj["facial_area"],
img_obj["confidence"]
)
for img_obj in img_objs if img_obj["face"].size > 0
]
if not face_data: # resize input image
return [] img_content = preprocessing.resize_image(img=img_content, target_size=(224, 224))
# Unpack the face data obj = {}
valid_faces, face_regions, face_confidences = zip(*face_data) # facial attribute analysis
faces_array = np.array(valid_faces)
# Initialize the results list with face regions and confidence scores
results = [{"region": region, "face_confidence": conf}
for region, conf in zip(face_regions, face_confidences)]
# Iterate over the actions and perform analysis
pbar = tqdm( pbar = tqdm(
actions, range(0, len(actions)),
desc="Finding actions", desc="Finding actions",
disable=silent if len(actions) > 1 else True, disable=silent if len(actions) > 1 else True,
) )
for action in pbar: for index in pbar:
action = actions[index]
pbar.set_description(f"Action: {action}") pbar.set_description(f"Action: {action}")
model = modeling.build_model(task="facial_attribute", model_name=action.capitalize())
predictions = model.predict(faces_array)
# If the model returns a single prediction, reshape it to match the number of faces.
# Determine the correct shape of predictions by using number of faces and predictions shape.
# Example: For 1 face with Emotion model, predictions will be reshaped to (1, 7).
if faces_array.shape[0] == 1 and len(predictions.shape) == 1:
# For models like `Emotion`, which return a single prediction for a single face
predictions = predictions.reshape(1, -1)
# Update the results with the predictions
# ----------------------------------------
# For emotion, calculate the percentage of each emotion and find the dominant emotion
if action == "emotion": if action == "emotion":
emotion_results = [ emotion_predictions = modeling.build_model(
{ task="facial_attribute", model_name="Emotion"
"emotion": { ).predict(img_content)
label: 100 * pred[i] / pred.sum() sum_of_predictions = emotion_predictions.sum()
for i, label in enumerate(Emotion.labels)
}, obj["emotion"] = {}
"dominant_emotion": Emotion.labels[np.argmax(pred)] for i, emotion_label in enumerate(Emotion.labels):
} emotion_prediction = 100 * emotion_predictions[i] / sum_of_predictions
for pred in predictions obj["emotion"][emotion_label] = emotion_prediction
]
for result, emotion_result in zip(results, emotion_results): obj["dominant_emotion"] = Emotion.labels[np.argmax(emotion_predictions)]
result.update(emotion_result)
# ----------------------------------------
# For age, find the dominant age category (0-100)
elif action == "age": elif action == "age":
age_results = [{"age": int(np.argmax(pred) if len(pred.shape) > 0 else pred)} apparent_age = modeling.build_model(
for pred in predictions] task="facial_attribute", model_name="Age"
for result, age_result in zip(results, age_results): ).predict(img_content)
result.update(age_result) # int cast is for exception - object of type 'float32' is not JSON serializable
# ---------------------------------------- print(apparent_age.shape)
# For gender, calculate the percentage of each gender and find the dominant gender obj["age"] = int(apparent_age)
elif action == "gender": elif action == "gender":
gender_results = [ gender_predictions = modeling.build_model(
{ task="facial_attribute", model_name="Gender"
"gender": { ).predict(img_content)
label: 100 * pred[i] obj["gender"] = {}
for i, label in enumerate(Gender.labels) for i, gender_label in enumerate(Gender.labels):
}, gender_prediction = 100 * gender_predictions[i]
"dominant_gender": Gender.labels[np.argmax(pred)] obj["gender"][gender_label] = gender_prediction
}
for pred in predictions obj["dominant_gender"] = Gender.labels[np.argmax(gender_predictions)]
]
for result, gender_result in zip(results, gender_results):
result.update(gender_result)
# ----------------------------------------
# For race, calculate the percentage of each race and find the dominant race
elif action == "race": elif action == "race":
race_results = [ race_predictions = modeling.build_model(
{ task="facial_attribute", model_name="Race"
"race": { ).predict(img_content)
label: 100 * pred[i] / pred.sum() sum_of_predictions = race_predictions.sum()
for i, label in enumerate(Race.labels)
}, obj["race"] = {}
"dominant_race": Race.labels[np.argmax(pred)] for i, race_label in enumerate(Race.labels):
} race_prediction = 100 * race_predictions[i] / sum_of_predictions
for pred in predictions obj["race"][race_label] = race_prediction
]
for result, race_result in zip(results, race_results): obj["dominant_race"] = Race.labels[np.argmax(race_predictions)]
result.update(race_result)
return results # -----------------------------
# mention facial areas
obj["region"] = img_region
# include image confidence
obj["face_confidence"] = img_confidence
resp_objects.append(obj)
return resp_objects