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:
raise ValueError("Spoof detected in the given image.") if anti_spoofing is True and img_obj.get("is_real", True) is False:
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), # resize input image
img_obj["facial_area"], img_content = preprocessing.resize_image(img=img_content, target_size=(224, 224))
img_obj["confidence"]
obj = {}
# facial attribute analysis
pbar = tqdm(
range(0, len(actions)),
desc="Finding actions",
disable=silent if len(actions) > 1 else True,
) )
for img_obj in img_objs if img_obj["face"].size > 0 for index in pbar:
] action = actions[index]
pbar.set_description(f"Action: {action}")
if not face_data: if action == "emotion":
return [] emotion_predictions = modeling.build_model(
task="facial_attribute", model_name="Emotion"
).predict(img_content)
sum_of_predictions = emotion_predictions.sum()
# Unpack the face data obj["emotion"] = {}
valid_faces, face_regions, face_confidences = zip(*face_data) for i, emotion_label in enumerate(Emotion.labels):
faces_array = np.array(valid_faces) emotion_prediction = 100 * emotion_predictions[i] / sum_of_predictions
# Initialize the results list with face regions and confidence scores obj["emotion"][emotion_label] = emotion_prediction
results = [{"region": region, "face_confidence": conf}
for region, conf in zip(face_regions, face_confidences)] obj["dominant_emotion"] = Emotion.labels[np.argmax(emotion_predictions)]
# Iterate over the actions and perform analysis
pbar = tqdm( elif action == "age":
actions, apparent_age = modeling.build_model(
desc="Finding actions", task="facial_attribute", model_name="Age"
disable=silent if len(actions) > 1 else True, ).predict(img_content)
) # int cast is for exception - object of type 'float32' is not JSON serializable
for action in pbar: print(apparent_age.shape)
pbar.set_description(f"Action: {action}") obj["age"] = int(apparent_age)
model = modeling.build_model(task="facial_attribute", model_name=action.capitalize())
predictions = model.predict(faces_array) elif action == "gender":
# If the model returns a single prediction, reshape it to match the number of faces. gender_predictions = modeling.build_model(
# Determine the correct shape of predictions by using number of faces and predictions shape. task="facial_attribute", model_name="Gender"
# Example: For 1 face with Emotion model, predictions will be reshaped to (1, 7). ).predict(img_content)
if faces_array.shape[0] == 1 and len(predictions.shape) == 1: obj["gender"] = {}
# For models like `Emotion`, which return a single prediction for a single face for i, gender_label in enumerate(Gender.labels):
predictions = predictions.reshape(1, -1) gender_prediction = 100 * gender_predictions[i]
# Update the results with the predictions obj["gender"][gender_label] = gender_prediction
# ----------------------------------------
# For emotion, calculate the percentage of each emotion and find the dominant emotion obj["dominant_gender"] = Gender.labels[np.argmax(gender_predictions)]
if action == "emotion":
emotion_results = [ elif action == "race":
{ race_predictions = modeling.build_model(
"emotion": { task="facial_attribute", model_name="Race"
label: 100 * pred[i] / pred.sum() ).predict(img_content)
for i, label in enumerate(Emotion.labels) sum_of_predictions = race_predictions.sum()
},
"dominant_emotion": Emotion.labels[np.argmax(pred)] obj["race"] = {}
} for i, race_label in enumerate(Race.labels):
for pred in predictions race_prediction = 100 * race_predictions[i] / sum_of_predictions
] obj["race"][race_label] = race_prediction
for result, emotion_result in zip(results, emotion_results):
result.update(emotion_result) obj["dominant_race"] = Race.labels[np.argmax(race_predictions)]
# ----------------------------------------
# For age, find the dominant age category (0-100) # -----------------------------
elif action == "age": # mention facial areas
age_results = [{"age": int(np.argmax(pred) if len(pred.shape) > 0 else pred)} obj["region"] = img_region
for pred in predictions] # include image confidence
for result, age_result in zip(results, age_results): obj["face_confidence"] = img_confidence
result.update(age_result)
# ---------------------------------------- resp_objects.append(obj)
# For gender, calculate the percentage of each gender and find the dominant gender
elif action == "gender": return resp_objects
gender_results = [
{
"gender": {
label: 100 * pred[i]
for i, label in enumerate(Gender.labels)
},
"dominant_gender": Gender.labels[np.argmax(pred)]
}
for pred in 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":
race_results = [
{
"race": {
label: 100 * pred[i] / pred.sum()
for i, label in enumerate(Race.labels)
},
"dominant_race": Race.labels[np.argmax(pred)]
}
for pred in predictions
]
for result, race_result in zip(results, race_results):
result.update(race_result)
return results