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

View File

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