pranav-5644's picture
added initial files
00f8748
raw
history blame
8.72 kB
# firstly import the necessary libraries :
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
# we are going to use harr cacade first
HaarCascade = cv2.CascadeClassifier(cv2.samples.findFile(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'))
# if harr cascade is unable to detect we will keep mtcnn for that case
# Initialize the MTCNN detector
mtcnn = MTCNN()
# we are going to use Facenet architecture for creating the embeddings from faces
model_face = FaceNet()
def process_image(image_path):
image = cv2.imread(image_path,cv2.IMREAD_UNCHANGED)
# for this example we are not resizing the image dimensions :
resized=image
image_rgb = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
# we need to adjust the size of window in cv 2 to display the image
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.waitKey(0)
cv2.destroyAllWindows()
# convert the image back to RGB format and adjust the brighness and contrast after processing
final = cv2.cvtColor(image_rgb, cv2.COLOR_BGR2RGB)
final = cv2.convertScaleAbs(final, alpha=1, beta=0) # Adjust alpha and beta as needed
# save the image with bounding boxes as image_detected.jpg
cv2.imwrite('image_detected.jpg',final)
folder_name = 'attendance_folder'
if not os.path.exists(folder_name):
os.mkdir(folder_name)
# List all files in the folder
file_list = os.listdir(folder_name)
face_images = []
# Iterate through the files and remove them
for file in file_list:
file_path = os.path.join(folder_name, file)
if os.path.isfile(file_path):
os.remove(file_path)
# Save the cropped photos in the folder named attendance_class
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)
# we need to adjust the size of window in cv 2 to display the image
# folder_name = 'attendance_folder'
# if not os.path.exists(folder_name):
# os.mkdir(folder_name)
# List all files in the folder
# file_list = os.listdir(folder_name)
# face_images = []
# # Iterate through the files and remove them
# for file in file_list:
# file_path = os.path.join(folder_name, file)
# if os.path.isfile(file_path):
# os.remove(file_path)
# cv2.namedWindow("output", cv2.WINDOW_NORMAL)
# cv2.resizeWindow("output", resized.shape[0],resized.shape[1])
# for face in faces:
# x, y, w, h = face['box']
# cv2.rectangle(image_rgb, (x, y), (x+w, y+h), (0, 255, 0), 2)
# cv2.imshow("output", image_rgb)
# # cv2.waitKey(0)
# 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)
# cv2.destroyAllWindows()
# # convert the image back to RGB format and adjust the brighness and contrast after processing
# final = cv2.cvtColor(image_rgb, cv2.COLOR_BGR2RGB)
# final = cv2.convertScaleAbs(final, alpha=1, beta=0) # Adjust alpha and beta as needed
# # save the image with bounding boxes as image_detected.jpg
# cv2.imwrite('image_detected.jpg',final)
def intermediate_process(gbr1):
# detect the face in the cropped photo :
harr = HaarCascade.detectMultiScale(gbr1,1.1,4)
# if the face is detected then get the width and height
if len(harr)>0:
x1, y1, width, height = harr[0]
# if harr cascade is unable to detect the face use mtcnn
else:
faces_mtcnn = mtcnn.detect_faces(gbr1)
if len(faces_mtcnn)>0:
x1, y1, width, height = faces_mtcnn[0]['box']
else :
# if no face is detected in the image just use the top left 10x10 pixels
x1, y1, width, height = 1, 1, 10, 10
x1, y1 = abs(x1), abs(y1)
x2, y2 = x1 + width, y1 + height
#convert from bgr to rgb
gbr = cv2.cvtColor(gbr1, cv2.COLOR_BGR2RGB)
gbr = Image.fromarray(gbr) # Convert from OpenCV to PIL
# convert image as numpy array
gbr_array = asarray(gbr)
# crop the face , resize it and store in face
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]
# Create the directory if it does not exist
if not os.path.exists(folder_name):
os.makedirs(folder_name)
# Unzip the file
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(folder_name)
folder=folder_name+'/'
# now generate the embeddings :
# intialize empty dictionary in which we will store the embeddings with name of the person
database = {}
# iterate through all the images in the training images folder
for filename in listdir(folder):
path = folder + filename
gbr1 = cv2.imread(folder + filename)
gbr, face = intermediate_process(gbr1)
# facenet takes as input 4 dimensional array so we expand dimension
face = expand_dims(face, axis=0)
signature = model_face.embeddings(face)
# store the array in the database
database[os.path.splitext(filename)[0]] = signature
cv2.destroyAllWindows()
# make a file named data_processed.pkl and store the database in it
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()
# same procedure as training
folder = 'attendance_folder/'
file_list = os.listdir(folder)
predicted=[]
# Set up the plot
num_images = len(file_list)
num_rows = math.ceil(num_images / 4) if math.ceil(num_images / 4)>0 else 1 # Ceiling division to calculate the number of rows
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
# Plot the image with the identity text
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')
# print(identity)
# cv2.namedWindow("output", cv2.WINDOW_NORMAL)
# cv2.resizeWindow("output", gbr1.shape[0],gbr1.shape[1])
# cv2.putText(gbr1,identity, (100,100),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 2, cv2.LINE_AA)
# cv2.rectangle(gbr1,(x1,y1),(x2,y2), (0,255,0), 2)
# cv2.imshow("output",gbr1)
# cv2.waitKey(0)
predicted.append(identity)
# Hide any remaining empty subplots
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()
# store the name of people present in a text file
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')