Clustering based on VGG and mtcnn

Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
James Ketr 2023-01-06 14:18:21 -08:00
parent 798712aa7f
commit ce05de871b
2 changed files with 25 additions and 16 deletions

View File

@ -7,8 +7,7 @@ from sqlite3 import Error
from PIL import Image
import numpy as np
from deepface import DeepFace
from retinaface import RetinaFace
from deepface.detectors import FaceDetector
sqlite3.register_adapter(np.array, lambda arr: arr.tobytes())
sqlite3.register_converter("array", np.frombuffer)
@ -21,8 +20,11 @@ class NpEncoder(json.JSONEncoder):
return float(obj)
if isinstance(obj, np.ndarray):
return obj.tolist()
model = DeepFace.build_model('ArcFace')
model_name = 'VGG-Face' # 'ArcFace'
detector_backend = 'mtcnn' # 'retinaface'
model = DeepFace.build_model(model_name)
face_detector = FaceDetector.build_model(detector_backend)
input_shape = DeepFace.functions.find_input_shape(model)
def create_connection(db_file):
@ -134,7 +136,7 @@ with conn:
SELECT faces.id,facedescriptors.descriptors,faces.faceConfidence,faces.photoId
FROM faces
JOIN facedescriptors ON (faces.descriptorId=facedescriptors.id)
WHERE faces.identityId IS null
WHERE faces.identityId IS null AND faces.faceConfidence>0.945
''')
for row in res.fetchall():
id, descriptors, confidence, photoId = row
@ -162,28 +164,35 @@ with conn:
if face2['scanned']:
continue
face = {
'between': (face1['id'], face2['id'])
'between': (face1['id'], face2['id']),
'confidence': (face1['confidence'], face2['confidence'])
}
face['distanceCosine'] = findCosineDistance(
face1['descriptors'],
face2['descriptors']
)
face['distanceEuclidian'] = findEuclideanDistance(
face['distanceEuclidean'] = findEuclideanDistance(
face1['descriptors'],
face2['descriptors']
)
face['distanceEuclidianL2'] = findEuclideanDistance(
face['distanceEuclideanL2'] = findEuclideanDistance(
l2_normalize(face1['descriptors']),
l2_normalize(face2['descriptors'])
)
face['scoring'] = 0
if face['distanceCosine'] < 0.65:
if model_name == 'VGG-Face':
thresholds = {'cosine': 0.40, 'euclidean': 0.60, 'euclidean_l2': 0.86}
elif model_name == 'ArcFace':
thresholds = {'cosine': 0.68, 'euclidean': 4.15, 'euclidean_l2': 1.13}
if face['distanceCosine'] < thresholds['cosine']:
face['scoring'] += 1
if face['distanceEuclidian'] < 4.00:
if face['distanceEuclidean'] < thresholds['euclidean']:
face['scoring'] += 1
if face['distanceEuclidianL2'] < 1.055:
if face['distanceEuclideanL2'] < thresholds['euclidean_l2']:
face['scoring'] += 1
if face['scoring'] == 3: # Same face!
@ -214,11 +223,13 @@ with conn:
for member in identity['members']:
face1 = member['between'][0]
face2 = member['between'][1]
path1 = f'faces/{"{:02d}".format(face1 % 10)}'
path2 = f'faces/{"{:02d}".format(face2 % 10)}'
print('<div>')
print(f'<img src="faces/{face1%10}/{face1}.jpg"/>')
print(f'<img src="faces/{face2%10}/{face2}.jpg"/>')
print(f'<img src="{path1}/{face1}.jpg"/>{member["confidence"][0]}')
print(f'<img src="{path2}/{face2}.jpg"/>{member["confidence"][1]}')
print('</div>')
print(f'<div>Distance: {member["distanceCosine"]}, {member["distanceEuclidian"]}, {member["distanceEuclidianL2"]}</div>')
print(f'<div>Distance: {member["distanceCosine"]}, {member["distanceEuclidean"]}, {member["distanceEuclideanL2"]}</div>')
print('</div>')
print('</div>')

View File

@ -52,8 +52,6 @@ class NpEncoder(json.JSONEncoder):
return float(obj)
if isinstance(obj, np.ndarray):
return obj.tolist()
models = ["VGG-Face", "Facenet", "Facenet512", "OpenFace", "DeepFace", "DeepID", "ArcFace", "Dlib", "SFace"]
model_name = 'VGG-Face' # 'ArcFace'
detector_backend = 'mtcnn' # 'retinaface'