|
|
|
import cv2 |
|
import matplotlib.pyplot as plt |
|
import numpy as np |
|
import os |
|
import zipfile |
|
from os import listdir |
|
from PIL import Image |
|
from numpy import asarray,expand_dims |
|
from matplotlib import pyplot |
|
from keras.models import load_model |
|
from keras_facenet import FaceNet |
|
import pickle |
|
from mtcnn import MTCNN |
|
import math |
|
|
|
|
|
HaarCascade = cv2.CascadeClassifier(cv2.samples.findFile(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')) |
|
|
|
|
|
mtcnn = MTCNN() |
|
|
|
model_face = FaceNet() |
|
|
|
|
|
def process_image(image_path): |
|
image = cv2.imread(image_path,cv2.IMREAD_UNCHANGED) |
|
|
|
resized=image |
|
image_rgb = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB) |
|
|
|
|
|
|
|
|
|
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') |
|
gray_image = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY) |
|
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5) |
|
|
|
cv2.namedWindow("output", cv2.WINDOW_NORMAL) |
|
cv2.resizeWindow("output", resized.shape[0],resized.shape[1]) |
|
for (x, y, w, h) in faces: |
|
cv2.rectangle(image_rgb, (x, y), (x+w, y+h), (0, 255, 0), 2) |
|
cv2.imshow("output", image_rgb) |
|
|
|
cv2.destroyAllWindows() |
|
|
|
|
|
|
|
final = cv2.cvtColor(image_rgb, cv2.COLOR_BGR2RGB) |
|
final = cv2.convertScaleAbs(final, alpha=1, beta=0) |
|
|
|
|
|
cv2.imwrite('image_detected.jpg',final) |
|
|
|
folder_name = 'attendance_folder' |
|
if not os.path.exists(folder_name): |
|
os.mkdir(folder_name) |
|
|
|
file_list = os.listdir(folder_name) |
|
|
|
face_images = [] |
|
|
|
|
|
for file in file_list: |
|
file_path = os.path.join(folder_name, file) |
|
if os.path.isfile(file_path): |
|
os.remove(file_path) |
|
|
|
|
|
for (x, y, w, h) in faces: |
|
face_crop = resized[y:y+h, x:x+w] |
|
face_images.append(face_crop) |
|
face_filename = os.path.join(folder_name, f'face_{x}_{y}.jpg') |
|
cv2.imwrite(face_filename, face_crop) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def intermediate_process(gbr1): |
|
|
|
harr = HaarCascade.detectMultiScale(gbr1,1.1,4) |
|
|
|
|
|
if len(harr)>0: |
|
x1, y1, width, height = harr[0] |
|
|
|
|
|
else: |
|
faces_mtcnn = mtcnn.detect_faces(gbr1) |
|
if len(faces_mtcnn)>0: |
|
x1, y1, width, height = faces_mtcnn[0]['box'] |
|
else : |
|
|
|
x1, y1, width, height = 1, 1, 10, 10 |
|
|
|
|
|
x1, y1 = abs(x1), abs(y1) |
|
x2, y2 = x1 + width, y1 + height |
|
|
|
|
|
gbr = cv2.cvtColor(gbr1, cv2.COLOR_BGR2RGB) |
|
gbr = Image.fromarray(gbr) |
|
|
|
gbr_array = asarray(gbr) |
|
|
|
|
|
face = gbr_array[y1:y2, x1:x2] |
|
face = Image.fromarray(face) |
|
face = face.resize((160, 160)) |
|
face = asarray(face) |
|
return gbr, face |
|
|
|
|
|
def generate_embeddings(zip_path): |
|
|
|
folder_name = os.path.splitext(zip_path)[0] |
|
|
|
|
|
if not os.path.exists(folder_name): |
|
os.makedirs(folder_name) |
|
|
|
|
|
with zipfile.ZipFile(zip_path, 'r') as zip_ref: |
|
zip_ref.extractall(folder_name) |
|
folder=folder_name+'/' |
|
|
|
|
|
database = {} |
|
|
|
|
|
for filename in listdir(folder): |
|
path = folder + filename |
|
gbr1 = cv2.imread(folder + filename) |
|
|
|
gbr, face = intermediate_process(gbr1) |
|
|
|
|
|
face = expand_dims(face, axis=0) |
|
signature = model_face.embeddings(face) |
|
|
|
|
|
database[os.path.splitext(filename)[0]] = signature |
|
|
|
cv2.destroyAllWindows() |
|
|
|
myfile = open("embeddings.pkl", "wb") |
|
pickle.dump(database, myfile) |
|
myfile.close() |
|
|
|
def recognize_faces(embeddigns_path,date): |
|
myfile = open(embeddigns_path, "rb") |
|
database = pickle.load(myfile) |
|
myfile.close() |
|
|
|
folder = 'attendance_folder/' |
|
file_list = os.listdir(folder) |
|
predicted=[] |
|
|
|
num_images = len(file_list) |
|
num_rows = math.ceil(num_images / 4) if math.ceil(num_images / 4)>0 else 1 |
|
fig, axes = plt.subplots(num_rows, 4, figsize=(16, 4*num_rows)) |
|
if(num_rows==1): |
|
axes=axes.reshape(1,4) |
|
for i,filename in enumerate(file_list): |
|
path = os.path.join(folder, filename) |
|
gbr1 = cv2.imread(folder + filename) |
|
|
|
gbr,face = intermediate_process(gbr1) |
|
|
|
face = expand_dims(face, axis=0) |
|
signature = model_face.embeddings(face) |
|
|
|
min_dist=100 |
|
identity=' ' |
|
for key, value in database.items() : |
|
dist = np.linalg.norm(value-signature) |
|
if dist < min_dist: |
|
min_dist = dist |
|
identity = key |
|
|
|
row = i // 4 |
|
col = i % 4 |
|
axes[row, col].imshow(gbr) |
|
axes[row, col].set_title(f"Identity: {identity}", fontsize=25) |
|
axes[row, col].axis('off') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
predicted.append(identity) |
|
|
|
for i in range(num_images, num_rows * 4): |
|
row = i // 4 |
|
col = i % 4 |
|
axes[row, col].axis('off') |
|
|
|
plt.tight_layout() |
|
fig.savefig('image_grid.jpg') |
|
|
|
cv2.destroyAllWindows() |
|
|
|
attendance = [name for name in predicted if name != 'unknown'] |
|
|
|
file_name = f"{date}.txt" |
|
|
|
with open(file_name, 'w') as file: |
|
for item in attendance: |
|
file.write(str(item) + '\n') |
|
|