from deepface import DeepFace from deepface.commons import functions, distance as dst import pandas as pd import time def face_find( img_path, global_face: list, model_name="Facenet", distance_metric="cosine", enforce_detection=True, detector_backend="opencv", align=True, normalization="base", silent=False, ): tic = time.time() target_size = functions.find_target_size(model_name=model_name) # now, we got representations for facial database df = pd.DataFrame(global_face, columns=["identity", f"{model_name}_representation"]) # img path might have more than once face target_objs = functions.extract_faces( img=img_path, target_size=target_size, detector_backend=detector_backend, grayscale=False, enforce_detection=enforce_detection, align=align, ) resp_obj = [] for target_img, target_region, _ in target_objs: target_embedding_obj = DeepFace.represent( img_path=target_img, model_name=model_name, enforce_detection=enforce_detection, detector_backend="skip", align=align, normalization=normalization, ) target_representation = target_embedding_obj[0]["embedding"] result_df = df.copy() # df will be filtered in each img result_df["source_x"] = target_region["x"] result_df["source_y"] = target_region["y"] result_df["source_w"] = target_region["w"] result_df["source_h"] = target_region["h"] distances = [] for index, instance in df.iterrows(): source_representation = instance[f"{model_name}_representation"] if distance_metric == "cosine": distance = dst.findCosineDistance(source_representation, target_representation) elif distance_metric == "euclidean": distance = dst.findEuclideanDistance(source_representation, target_representation) elif distance_metric == "euclidean_l2": distance = dst.findEuclideanDistance( dst.l2_normalize(source_representation), dst.l2_normalize(target_representation), ) else: raise ValueError(f"invalid distance metric passes - {distance_metric}") distances.append(distance) # --------------------------- result_df[f"{model_name}_{distance_metric}"] = distances threshold = dst.findThreshold(model_name, distance_metric) result_df = result_df.drop(columns=[f"{model_name}_representation"]) result_df = result_df[result_df[f"{model_name}_{distance_metric}"] <= threshold] result_df = result_df.sort_values( by=[f"{model_name}_{distance_metric}"], ascending=True ).reset_index(drop=True) resp_obj.append(result_df) # ----------------------------------- toc = time.time() if not silent: print("find function lasts ", toc - tic, " seconds") return resp_obj