modularization face recognition

This commit is contained in:
Xu-jianwen 2021-08-13 10:24:23 +08:00
parent 415c648dbc
commit 350acecec0
4 changed files with 196 additions and 0 deletions

View File

@ -0,0 +1,71 @@
import os
from tqdm import tqdm
import pickle
import numpy as np
import pandas as pd
import cv2
import time
import os
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from deepface import DeepFace
from deepface.commons import functions, distance as dst
def encode(db_path, model_name='VGG-Face', detector_backend='retinaface'):
model = DeepFace.build_model(model_name)
print(model_name, "is built")
# threshold = dst.findThreshold(model_name, distance_metric)
input_shape = functions.find_input_shape(model); input_shape_x = input_shape[0]; input_shape_y = input_shape[1]
text_color = (255, 255, 255)
employees = []
if os.path.isdir(db_path) == True:
for r, d, f in os.walk(db_path):
for file in f:
if('.jpg' in file):
exact_path = r + "/" + file
employees.append(exact_path)
if os.path.isdir(db_path) == True:
file_name = "representations_%s.pkl" % (model_name)
file_name = file_name.replace("-", "_").lower()
if os.path.exists(db_path+"/"+file_name):
print("Representations for images in ",db_path," folder were previously stored in ", file_name, ". If you added new instances after this file creation, then please delete this file and call find function again. It will create it again.")
f = open(db_path+'/'+file_name, 'rb')
embeddings = pickle.load(f)
print("There are ", len(embeddings)," representations found in ",file_name)
else:
if len(employees) == 0:
print("WARNING: There is no image in this path ( ", db_path,") . Face recognition will not be performed.")
if len(employees) > 0:
input_shape = functions.find_input_shape(model)
input_shape_x = input_shape[0]; input_shape_y = input_shape[1]
tic = time.time()
pbar = tqdm(range(0, len(employees)), desc='Finding embeddings')
embeddings = []
for index in pbar:
employee = employees[index]
pbar.set_description("Finding embedding for %s" % (employee.split("/")[-1]))
embedding = []
img = functions.preprocess_face(img = employee, target_size = (input_shape_y, input_shape_x), enforce_detection = False, detector_backend = detector_backend)
img_representation = model.predict(img)[0,:]
embedding.append(employee)
embedding.append(img_representation)
embeddings.append(embedding)
f = open(db_path+'/'+file_name, "wb")
pickle.dump(embeddings, f)
f.close()
toc = time.time()
print("Embeddings found for given data set in ", toc-tic," seconds")
return employees, embeddings

32
video_face/detect.py Normal file
View File

@ -0,0 +1,32 @@
import os
from tqdm import tqdm
import pickle
import numpy as np
import pandas as pd
import cv2
import time
import os
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from deepface import DeepFace
from deepface.commons import functions, realtime, distance as dst
from deepface.detectors import FaceDetector
def face_det(frame, detector_backend, rec_model_input_size, smallest_faces=30):
face_detector = FaceDetector.build_model(detector_backend)
faces = FaceDetector.detect_faces(face_detector, detector_backend, frame, align = False)
size_x = rec_model_input_size[0]; size_y = rec_model_input_size[1]
detected_faces = []
face_imgs = []
for face, (x, y, w, h) in faces:
if w > smallest_faces:
# cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 1) #draw rectangle to main image
detected_face = frame[int(y):int(y+h), int(x):int(x+w)] #crop detected face
detected_face = functions.preprocess_face(img = detected_face, target_size = (size_y, size_x), enforce_detection = False, detector_backend = 'opencv')
detected_faces.append((x,y,w,h))
face_imgs.append(detected_face)
if len(face_imgs) > 0:
face_imgs = np.vstack(face_imgs)
return detected_faces, face_imgs

63
video_face/main.py Normal file
View File

@ -0,0 +1,63 @@
import os
from tqdm import tqdm
import pickle
import numpy as np
import pandas as pd
import cv2
import time
import os
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from deepface import DeepFace
from deepface.commons import functions, realtime, distance as dst
from database_encode import encode
from detect import face_det
from recognize import face_recognize
def main(db_path, model_name = 'VGG-Face', detector_backend = 'retinaface', distance_metric = 'cosine', source = 0, smallest_faces=30):
model = DeepFace.build_model(model_name)
print(model_name, "is built")
input_shape = functions.find_input_shape(model)
threshold = dst.findThreshold(model_name, distance_metric)
employees, db_embeddings = encode(db_path, model_name=model_name, detector_backend=detector_backend)
db_embeddings = [db_embeddings[i][1] for i in range(len(db_embeddings))]
db_embeddings = np.vstack(db_embeddings)
frame_count = 0
cap = cv2.VideoCapture(source)
while True:
frame_count += 1
ret, frame = cap.read()
if frame is None:
break
if frame_count % 10 == 0:
detected_faces, face_imgs = face_det(frame, detector_backend, rec_model_input_size=input_shape, smallest_faces=30)
if len(face_imgs) > 0:
shortest_distance, pred = face_recognize(face_imgs, db_embeddings, model, model_name, distance_metric)
labels = [employees[i] for i in pred]
for i, detected_face in enumerate(detected_faces):
x = detected_face[0]; y = detected_face[1]
w = detected_face[2]; h = detected_face[3]
cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 1)
if shortest_distance[i] <= threshold:
label = labels[i]
cv2.putText(frame, label, (x, y+h+10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
else:
label = 'unknown'
cv2.putText(frame, label, (x, y+h+10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
print("best_distance:{}, threshhold:{}, label:{}".format(shortest_distance, threshold, label))
cv2.imshow('img', frame)
if cv2.waitKey(1) & 0xFF == ord('q'): #press q to quit
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main("D:/face/320_no_mask/", model_name = 'VGG-Face', detector_backend = 'ssd',
# source='rtsp://admin:123456@192.168.123.235:554/stream1',
source="C:/Users/DELL/Desktop/face_det/320.mp4",
distance_metric='cosine', smallest_faces=20)

30
video_face/recognize.py Normal file
View File

@ -0,0 +1,30 @@
import os
from tqdm import tqdm
import pickle
import numpy as np
import pandas as pd
import cv2
import os
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from deepface.commons import functions, realtime, distance as dst
def face_recognize(faces, db_embeddings, model, model_name, distance_metric):
# threshold = dst.findThreshold(model_name, distance_metric)
embeddings = model.predict(faces)
if distance_metric == 'cosine':
distance = np.matmul(embeddings, np.transpose(db_embeddings))
elif distance_metric == 'euclidean':
distance = dst.findEuclideanDistance(embeddings, db_embeddings)
elif distance_metric == 'euclidean_l2':
distance = dst.findEuclideanDistance(dst.l2_normalize(embeddings), dst.l2_normalize(db_embeddings))
shortest_distance = np.max(distance, axis=1)
pred = np.argmax(distance, axis=1)
return shortest_distance, pred