new interface

This commit is contained in:
Sefik Ilkin Serengil 2023-01-24 22:57:35 +00:00
parent dec0c34b2d
commit 700867c7db
7 changed files with 713 additions and 72 deletions

View File

@ -46,7 +46,7 @@ A modern [**face recognition pipeline**](https://sefiks.com/2020/05/01/a-gentle-
**Face Verification** - [`Demo`](https://youtu.be/KRCvkNCOphE) **Face Verification** - [`Demo`](https://youtu.be/KRCvkNCOphE)
This function verifies face pairs as same person or different persons. It expects exact image paths as inputs. Passing numpy or base64 encoded images is also welcome. Then, it is going to return a dictionary and you should check just its verified key. Verification function can also handle many faces in the face pairs. In this case, the most similar faces will be compared. This function verifies face pairs as same person or different persons. It expects exact image paths as inputs. Passing numpy or base64 encoded images is also welcome. Then, it is going to return a dictionary and you should check just its verified key.
```python ```python
result = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg") result = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg")
@ -54,9 +54,11 @@ result = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg")
<p align="center"><img src="https://raw.githubusercontent.com/serengil/deepface/master/icon/stock-1.jpg" width="95%" height="95%"></p> <p align="center"><img src="https://raw.githubusercontent.com/serengil/deepface/master/icon/stock-1.jpg" width="95%" height="95%"></p>
Verification function can also handle many faces in the face pairs. In this case, the most similar faces will be compared.
**Face recognition** - [`Demo`](https://youtu.be/Hrjp-EStM_s) **Face recognition** - [`Demo`](https://youtu.be/Hrjp-EStM_s)
[Face recognition](https://sefiks.com/2020/05/25/large-scale-face-recognition-for-deep-learning/) requires applying face verification many times. Herein, deepface has an out-of-the-box find function to handle this action. It's going to look for the identity of input image in the database path and it will return list of pandas data frame as output. Result is going to be the size of faces appearing in the image path. [Face recognition](https://sefiks.com/2020/05/25/large-scale-face-recognition-for-deep-learning/) requires applying face verification many times. Herein, deepface has an out-of-the-box find function to handle this action. It's going to look for the identity of input image in the database path and it will return list of pandas data frame as output. Result is going to be the size of faces appearing in the source image.
```python ```python

View File

@ -66,21 +66,13 @@ def analyze():
toc = time.time() toc = time.time()
resp = {} resp_obj["trx_id"] = trx_id
resp_obj["seconds"] = toc-tic
resp["trx_id"] = trx_id return resp_obj, 200
resp["seconds"] = toc-tic
if isinstance(resp_obj, list):
for idx, instance in enumerate(resp_obj):
resp[f"instance_{idx+1}"] = instance
elif isinstance(resp_obj, dict):
resp["instance_1"] = resp_obj
return resp, 200
def analyzeWrapper(req, trx_id = 0): def analyzeWrapper(req, trx_id = 0):
resp_obj = jsonify({'success': False}) resp_obj = {}
instances = [] instances = []
if "img" in list(req.keys()): if "img" in list(req.keys()):
@ -90,32 +82,46 @@ def analyzeWrapper(req, trx_id = 0):
instances.append(item) instances.append(item)
if len(instances) == 0: if len(instances) == 0:
return jsonify({'success': False, 'error': 'you must pass at least one img object in your request'}), 205 return {'success': False, 'error': 'you must pass at least one img object in your request'}
print("Analyzing ", len(instances)," instances") print("Analyzing ", len(instances)," instances")
#--------------------------- #---------------------------
detector_backend = 'opencv' detector_backend = 'opencv'
actions= ['emotion', 'age', 'gender', 'race'] actions= ['emotion', 'age', 'gender', 'race']
align = True
enforce_detection = True
if "actions" in list(req.keys()): if "actions" in list(req.keys()):
actions = req["actions"] actions = req["actions"]
if "detector_backend" in list(req.keys()): if "detector_backend" in list(req.keys()):
detector_backend = req["detector_backend"] detector_backend = req["detector_backend"]
if "align" in list(req.keys()):
align = req["align"]
if "enforce_detection" in list(req.keys()):
enforce_detection = req["enforce_detection"]
#--------------------------- #---------------------------
try: try:
resp_obj = DeepFace.analyze(instances, actions = actions) resp_obj["demographies"] = {}
for idx, instance in enumerate(instances):
demographies = DeepFace.analyze(img_path = instance,
detector_backend = detector_backend,
actions = actions, align = align,
enforce_detection = enforce_detection)
resp_obj["demographies"][f"img_{idx+1}"] = demographies
except Exception as err: except Exception as err:
print("Exception: ", str(err)) print("Exception: ", str(err))
return jsonify({'success': False, 'error': str(err)}), 205 return jsonify({'success': False, 'error': str(err)}), 205
#--------------- #---------------
#print(resp_obj)
return resp_obj return resp_obj
@app.route('/verify', methods=['POST']) @app.route('/verify', methods=['POST'])
@ -146,62 +152,58 @@ def verify():
def verifyWrapper(req, trx_id = 0): def verifyWrapper(req, trx_id = 0):
resp_obj = jsonify({'success': False}) resp_obj = {}
model_name = "VGG-Face"; distance_metric = "cosine"; detector_backend = "opencv" model_name = "VGG-Face"; distance_metric = "cosine"; detector_backend = "opencv"
align = True; enforce_detection = True
if "model_name" in list(req.keys()): if "model_name" in list(req.keys()):
model_name = req["model_name"] model_name = req["model_name"]
if "distance_metric" in list(req.keys()): if "distance_metric" in list(req.keys()):
distance_metric = req["distance_metric"] distance_metric = req["distance_metric"]
if "detector_backend" in list(req.keys()): if "detector_backend" in list(req.keys()):
detector_backend = req["detector_backend"] detector_backend = req["detector_backend"]
if "align" in list(req.keys()):
align = req["align"]
if "enforce_detection" in list(req.keys()):
enforce_detection = req["enforce_detection"]
#---------------------- #----------------------
instances = []
if "img" in list(req.keys()):
raw_content = req["img"] #list
for item in raw_content: #item is in type of dict
instance = []
img1 = item["img1"]; img2 = item["img2"]
validate_img1 = False
if len(img1) > 11 and img1[0:11] == "data:image/":
validate_img1 = True
validate_img2 = False
if len(img2) > 11 and img2[0:11] == "data:image/":
validate_img2 = True
if validate_img1 != True or validate_img2 != True:
return jsonify({'success': False, 'error': 'you must pass both img1 and img2 as base64 encoded string'}), 205
instance.append(img1); instance.append(img2)
instances.append(instance)
#--------------------------
if len(instances) == 0:
return jsonify({'success': False, 'error': 'you must pass at least one img object in your request'}), 205
print("Input request of ", trx_id, " has ",len(instances)," pairs to verify")
#--------------------------
try: try:
resp_obj = DeepFace.verify(instances if "img" in list(req.keys()):
, model_name = model_name raw_content = req["img"] #list
, distance_metric = distance_metric
, detector_backend = detector_backend
)
if model_name == "Ensemble": #issue 198. if len(raw_content) == 0:
for key in resp_obj: #issue 198. return jsonify({'success': False, 'error': 'you must pass at least one img object in your request'}), 205
resp_obj[key]['verified'] = bool(resp_obj[key]['verified'])
print("Input request of ", trx_id, " has ",len(raw_content)," pairs to verify")
results = []
for idx, item in enumerate(raw_content): #item is in type of dict
img1 = item["img1"]; img2 = item["img2"]
validate_img1 = False
if len(img1) > 11 and img1[0:11] == "data:image/":
validate_img1 = True
validate_img2 = False
if len(img2) > 11 and img2[0:11] == "data:image/":
validate_img2 = True
if validate_img1 != True or validate_img2 != True:
return jsonify({'success': False, 'error': 'you must pass both img1 and img2 as base64 encoded string'}), 205
result = DeepFace.verify(img1_path=img1,
img2_path=img2,
model_name=model_name,
detector_backend=detector_backend,
distance_metric=distance_metric,
align=align,
enforce_detection=enforce_detection,
)
results.append(result)
resp_obj[f"pairs"] = results
except Exception as err: except Exception as err:
resp_obj = jsonify({'success': False, 'error': str(err)}), 205 resp_obj = jsonify({'success': False, 'error': str(err)}), 205
return resp_obj return resp_obj
@ -238,7 +240,7 @@ def representWrapper(req, trx_id = 0):
#------------------------------------- #-------------------------------------
#find out model #find out model
model_name = "VGG-Face"; distance_metric = "cosine"; detector_backend = 'opencv' model_name = "VGG-Face"; detector_backend = 'opencv'
if "model_name" in list(req.keys()): if "model_name" in list(req.keys()):
model_name = req["model_name"] model_name = req["model_name"]
@ -267,7 +269,7 @@ def representWrapper(req, trx_id = 0):
try: try:
embedding = DeepFace.represent(img embedding_objs = DeepFace.represent(img
, model_name = model_name , model_name = model_name
, detector_backend = detector_backend , detector_backend = detector_backend
) )
@ -280,7 +282,16 @@ def representWrapper(req, trx_id = 0):
#print("embedding is ", len(embedding)," dimensional vector") #print("embedding is ", len(embedding)," dimensional vector")
resp_obj = {} resp_obj = {}
resp_obj["embedding"] = embedding faces = []
for embedding_obj in embedding_objs:
face = {}
face["embedding"] = embedding_obj["embedding"]
face["facial_area"] = embedding_obj["facial_area"]
face["model_name"] = model_name
face["detector_backend"] = detector_backend
faces.append(face)
resp_obj["embeddings"] = faces
#------------------------------------- #-------------------------------------

View File

@ -473,7 +473,10 @@ def find(img_path, db_path, model_name ='VGG-Face', distance_metric = 'cosine',
target_representation = target_embedding_obj[0]["embedding"] target_representation = target_embedding_obj[0]["embedding"]
result_df = df.copy() #df will be filtered in each img result_df = df.copy() #df will be filtered in each img
#TODO: add facial area in df 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 = [] distances = []
for index, instance in df.iterrows(): for index, instance in df.iterrows():

View File

@ -31,10 +31,7 @@ def findThreshold(model_name, distance_metric):
'Facenet512': {'cosine': 0.30, 'euclidean': 23.56, 'euclidean_l2': 1.04}, 'Facenet512': {'cosine': 0.30, 'euclidean': 23.56, 'euclidean_l2': 1.04},
'ArcFace': {'cosine': 0.68, 'euclidean': 4.15, 'euclidean_l2': 1.13}, 'ArcFace': {'cosine': 0.68, 'euclidean': 4.15, 'euclidean_l2': 1.13},
'Dlib': {'cosine': 0.07, 'euclidean': 0.6, 'euclidean_l2': 0.4}, 'Dlib': {'cosine': 0.07, 'euclidean': 0.6, 'euclidean_l2': 0.4},
#TODO: find the best threshold values
'SFace': {'cosine': 0.5932763306134152, 'euclidean': 10.734038121282206, 'euclidean_l2': 1.055836701022614}, 'SFace': {'cosine': 0.5932763306134152, 'euclidean': 10.734038121282206, 'euclidean_l2': 1.055836701022614},
'OpenFace': {'cosine': 0.10, 'euclidean': 0.55, 'euclidean_l2': 0.55}, 'OpenFace': {'cosine': 0.10, 'euclidean': 0.55, 'euclidean_l2': 0.55},
'DeepFace': {'cosine': 0.23, 'euclidean': 64, 'euclidean_l2': 0.64}, 'DeepFace': {'cosine': 0.23, 'euclidean': 64, 'euclidean_l2': 0.64},
'DeepID': {'cosine': 0.015, 'euclidean': 45, 'euclidean_l2': 0.17} 'DeepID': {'cosine': 0.015, 'euclidean': 45, 'euclidean_l2': 0.17}

View File

@ -197,7 +197,7 @@ def find_target_size(model_name):
"Facenet512": (160, 160), "Facenet512": (160, 160),
"OpenFace": (96, 96), "OpenFace": (96, 96),
"DeepFace": (152, 152), "DeepFace": (152, 152),
"DeepID": (55, 47), #TODO: might be opposite "DeepID": (47, 55),
"Dlib": (150, 150), "Dlib": (150, 150),
"ArcFace": (112, 112), "ArcFace": (112, 112),
"SFace": (112, 112) "SFace": (112, 112)

View File

@ -85,9 +85,7 @@ def analysis(db_path, model_name = 'VGG-Face', detector_backend = 'opencv', dist
#----------------------- #-----------------------
pbar = tqdm(range(0, len(employees)), desc='Finding embeddings') pbar = tqdm(range(0, len(employees)), desc='Finding embeddings')
#TODO: why don't you store those embeddings in a pickle file similar to find function?
embeddings = [] embeddings = []
#for employee in employees: #for employee in employees:
for index in pbar: for index in pbar:

630
tests/visual_tests.ipynb Normal file

File diff suppressed because one or more lines are too long