90 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			2.9 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_df,
 | |
|     model_name="Facenet512",
 | |
|     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 = global_df
 | |
| 
 | |
|     # 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 |