90 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
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 |