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)
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
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>
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](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

View File

@ -66,21 +66,13 @@ def analyze():
toc = time.time()
resp = {}
resp_obj["trx_id"] = trx_id
resp_obj["seconds"] = toc-tic
resp["trx_id"] = trx_id
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
return resp_obj, 200
def analyzeWrapper(req, trx_id = 0):
resp_obj = jsonify({'success': False})
resp_obj = {}
instances = []
if "img" in list(req.keys()):
@ -90,32 +82,46 @@ def analyzeWrapper(req, trx_id = 0):
instances.append(item)
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")
#---------------------------
detector_backend = 'opencv'
actions= ['emotion', 'age', 'gender', 'race']
align = True
enforce_detection = True
if "actions" in list(req.keys()):
actions = req["actions"]
if "detector_backend" in list(req.keys()):
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:
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:
print("Exception: ", str(err))
return jsonify({'success': False, 'error': str(err)}), 205
#---------------
#print(resp_obj)
return resp_obj
@app.route('/verify', methods=['POST'])
@ -146,62 +152,58 @@ def verify():
def verifyWrapper(req, trx_id = 0):
resp_obj = jsonify({'success': False})
resp_obj = {}
model_name = "VGG-Face"; distance_metric = "cosine"; detector_backend = "opencv"
align = True; enforce_detection = True
if "model_name" in list(req.keys()):
model_name = req["model_name"]
if "distance_metric" in list(req.keys()):
distance_metric = req["distance_metric"]
if "detector_backend" in list(req.keys()):
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:
resp_obj = DeepFace.verify(instances
, model_name = model_name
, distance_metric = distance_metric
, detector_backend = detector_backend
)
if "img" in list(req.keys()):
raw_content = req["img"] #list
if model_name == "Ensemble": #issue 198.
for key in resp_obj: #issue 198.
resp_obj[key]['verified'] = bool(resp_obj[key]['verified'])
if len(raw_content) == 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(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:
resp_obj = jsonify({'success': False, 'error': str(err)}), 205
resp_obj = jsonify({'success': False, 'error': str(err)}), 205
return resp_obj
@ -238,7 +240,7 @@ def representWrapper(req, trx_id = 0):
#-------------------------------------
#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()):
model_name = req["model_name"]
@ -267,7 +269,7 @@ def representWrapper(req, trx_id = 0):
try:
embedding = DeepFace.represent(img
embedding_objs = DeepFace.represent(img
, model_name = model_name
, detector_backend = detector_backend
)
@ -280,7 +282,16 @@ def representWrapper(req, trx_id = 0):
#print("embedding is ", len(embedding)," dimensional vector")
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"]
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 = []
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},
'ArcFace': {'cosine': 0.68, 'euclidean': 4.15, 'euclidean_l2': 1.13},
'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},
'OpenFace': {'cosine': 0.10, 'euclidean': 0.55, 'euclidean_l2': 0.55},
'DeepFace': {'cosine': 0.23, 'euclidean': 64, 'euclidean_l2': 0.64},
'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),
"OpenFace": (96, 96),
"DeepFace": (152, 152),
"DeepID": (55, 47), #TODO: might be opposite
"DeepID": (47, 55),
"Dlib": (150, 150),
"ArcFace": (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')
#TODO: why don't you store those embeddings in a pickle file similar to find function?
embeddings = []
#for employee in employees:
for index in pbar:

630
tests/visual_tests.ipynb Normal file

File diff suppressed because one or more lines are too long