Skip to content

Commit

Permalink
Added black as code-formatter (#30)
Browse files Browse the repository at this point in the history
* Added black and flake8 as dev-dependencies

* Updated requirements.txt

* Apply black formatting

* Update README.md
  • Loading branch information
Vibhu-Agarwal authored Dec 12, 2020
1 parent 462956d commit 18b3b19
Show file tree
Hide file tree
Showing 11 changed files with 1,004 additions and 822 deletions.
590 changes: 388 additions & 202 deletions Attendance_app.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# [Attendance-Management-using-Face-Recognition](https://github.com/Marauders-9998/Attendance-Management-using-Face-Recognition)


[![Open Issues](https://img.shields.io/github/issues/Marauders-9998/Attendance-Management-using-Face-Recognition?style=for-the-badge&logo=github)](https://github.com/Marauders-9998/Attendance-Management-using-Face-Recognition/issues) [![Forks](https://img.shields.io/github/forks/Marauders-9998/Attendance-Management-using-Face-Recognition?style=for-the-badge&logo=github)](https://github.com/Marauders-9998/Attendance-Management-using-Face-Recognition/network/members) [![Stars](https://img.shields.io/github/stars/Marauders-9998/Attendance-Management-using-Face-Recognition?style=for-the-badge&logo=reverbnation)](https://github.com/Marauders-9998/Attendance-Management-using-Face-Recognition/stargazers) ![Made with Python](https://img.shields.io/badge/Made%20with-Python-blueviolet?style=for-the-badge&logo=python) [![Slack](https://img.shields.io/badge/Slack-Chat-informational?style=for-the-badge&logo=slack)](https://join.slack.com/t/marauders9998/shared_invite/zt-jwafycfo-2yu9tnWlkHcwRX0fdIclpQ)
[![Open Issues](https://img.shields.io/github/issues/Marauders-9998/Attendance-Management-using-Face-Recognition?style=for-the-badge&logo=github)](https://github.com/Marauders-9998/Attendance-Management-using-Face-Recognition/issues) [![Forks](https://img.shields.io/github/forks/Marauders-9998/Attendance-Management-using-Face-Recognition?style=for-the-badge&logo=github)](https://github.com/Marauders-9998/Attendance-Management-using-Face-Recognition/network/members) [![Stars](https://img.shields.io/github/stars/Marauders-9998/Attendance-Management-using-Face-Recognition?style=for-the-badge&logo=reverbnation)](https://github.com/Marauders-9998/Attendance-Management-using-Face-Recognition/stargazers) ![Made with Python](https://img.shields.io/badge/Made%20with-Python-blueviolet?style=for-the-badge&logo=python) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge)](https://github.com/psf/black) [![Slack](https://img.shields.io/badge/Slack-Chat-informational?style=for-the-badge&logo=slack)](https://join.slack.com/t/marauders9998/shared_invite/zt-jwafycfo-2yu9tnWlkHcwRX0fdIclpQ)

## Objective
This desktop application aims to simplify the process of Attendance Management of different classes and batches using Face Recognition and user-friendly GUI. The management of data and marking of attendance is carried out in Excel files.
Expand Down
10 changes: 6 additions & 4 deletions capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from tkinter import messagebox
import cv2

xml_file = os.path.join(os.getcwd(), 'haarcascade_frontalface_default.xml')
xml_file = os.path.join(os.getcwd(), "haarcascade_frontalface_default.xml")


def detect_faces(cascade_xml, bgr_img, scaleFactor=1.1):
Expand All @@ -17,7 +17,9 @@ def detect_faces(cascade_xml, bgr_img, scaleFactor=1.1):
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Training Image", img)
cv2.waitKey(0)
response = messagebox.askyesno("Verify", "Has you face been properly detected and marked ?")
response = messagebox.askyesno(
"Verify", "Has you face been properly detected and marked ?"
)

cv2.destroyAllWindows()
return response
Expand All @@ -43,7 +45,7 @@ def capture():
elif k % 256 == 32:
# SPACE pressed
img_name = str(datetime.now().strftime("%Y%m%d_%H%M%S"))
img_name = os.path.join(os.getcwd(), 'images', ".temp", img_name + '.jpg')
img_name = os.path.join(os.getcwd(), "images", ".temp", img_name + ".jpg")
cv2.imwrite(img_name, frame)
break

Expand All @@ -53,5 +55,5 @@ def capture():
return img_name, frame


if __name__ == '__main__':
if __name__ == "__main__":
pass
72 changes: 40 additions & 32 deletions excel.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@
from students_list import StudentsList

HEADING_FONT = Font(size=20, bold=True)
ALIGNMENT = Alignment(horizontal='center', vertical='center')
FILL_DATE = PatternFill(fgColor='AFA5EF', fill_type='solid')
FILL_ROLL = PatternFill(fgColor='A5EFAF', fill_type='solid')
FILL_NAME = PatternFill(fgColor='E9EFA5', fill_type='solid')
FILL_TOTAL = PatternFill(fgColor='25F741', fill_type='solid')
FILL_ABSENT = PatternFill(fgColor='FF1010', fill_type='solid')
FILL_PRESENT = PatternFill(fgColor='10FF10', fill_type='solid')
ALIGNMENT = Alignment(horizontal="center", vertical="center")
FILL_DATE = PatternFill(fgColor="AFA5EF", fill_type="solid")
FILL_ROLL = PatternFill(fgColor="A5EFAF", fill_type="solid")
FILL_NAME = PatternFill(fgColor="E9EFA5", fill_type="solid")
FILL_TOTAL = PatternFill(fgColor="25F741", fill_type="solid")
FILL_ABSENT = PatternFill(fgColor="FF1010", fill_type="solid")
FILL_PRESENT = PatternFill(fgColor="10FF10", fill_type="solid")

GAP = 5
DATE_COLUMN = 5

NAMES = ['Marauders']
ROLLS = ['000001']
NAMES = ["Marauders"]
ROLLS = ["000001"]

NUMBER_OF_STUDENTS = len(NAMES)

Expand All @@ -30,11 +30,11 @@ def todays_date():


def month():
return todays_date().strftime('%B')
return todays_date().strftime("%B")


def make_file_name(class_name):
return join(getcwd(), 'extras', class_name, class_name + '.xlsx')
return join(getcwd(), "extras", class_name, class_name + ".xlsx")


def current_month_exists(wb):
Expand All @@ -47,7 +47,7 @@ def current_month_exists(wb):

def set_border(ws, cell_range):
rows = ws[cell_range]
side = Side(border_style='thin', color="FF000000")
side = Side(border_style="thin", color="FF000000")

rows = list(rows)
max_y = len(rows) - 1
Expand All @@ -58,7 +58,7 @@ def set_border(ws, cell_range):
left=cell.border.left,
right=cell.border.right,
top=cell.border.top,
bottom=cell.border.bottom
bottom=cell.border.bottom,
)
if pos_x == 0:
border.left = side
Expand All @@ -78,30 +78,30 @@ def createWorksheet(wb):
global NAMES, ROLLS, NUMBER_OF_STUDENTS
manth = month()
ws = wb.create_sheet(manth)
ws.merge_cells('A1:AN2')
heading = 'Attendance Record for ' + manth
heading = heading + ' ' * 50 + heading + ' ' * 50 + heading
ws['A1'] = heading
ws['A1'].font = HEADING_FONT
ws['A1'].alignment = ALIGNMENT
ws.merge_cells("A1:AN2")
heading = "Attendance Record for " + manth
heading = heading + " " * 50 + heading + " " * 50 + heading
ws["A1"] = heading
ws["A1"].font = HEADING_FONT
ws["A1"].alignment = ALIGNMENT

# ws.sheet_properties.tabColor = 'FFFF66'
ws['A3'] = 'S.No'
ws['B3'] = 'Enrollment'
ws['B3'].fill = FILL_ROLL
ws.merge_cells('C3:D3')
ws['C3'] = 'Name'
ws['C3'].fill = FILL_NAME

cellrange = 'A' + str(GAP - 1) + ':AN' + str(GAP - 1)
ws["A3"] = "S.No"
ws["B3"] = "Enrollment"
ws["B3"].fill = FILL_ROLL
ws.merge_cells("C3:D3")
ws["C3"] = "Name"
ws["C3"].fill = FILL_NAME

cellrange = "A" + str(GAP - 1) + ":AN" + str(GAP - 1)
set_border(ws, cellrange)
for i in range(NUMBER_OF_STUDENTS):
ws.merge_cells(start_row=GAP + i, start_column=3, end_row=GAP + i, end_column=4)
ws.cell(row=GAP + i, column=1, value=str(i + 1))
ws.cell(row=GAP + i, column=2, value=ROLLS[i]).fill = FILL_ROLL
ws.cell(row=GAP + i, column=3, value=NAMES[i]).fill = FILL_NAME

cellrange = 'A' + str(GAP + i) + ':AN' + str(GAP + i)
cellrange = "A" + str(GAP + i) + ":AN" + str(GAP + i)
set_border(ws, cellrange)
today = todays_date()
first_day = date(today.year, today.month, 1)
Expand All @@ -115,9 +115,17 @@ def createWorksheet(wb):
sum_cell_column = DATE_COLUMN + days_in_month + 1
ws.cell(row=3, column=sum_cell_column, value="Total").fill = FILL_TOTAL
for i in range(NUMBER_OF_STUDENTS):
ws.cell(row=GAP + i, column=sum_cell_column,
value="=SUM(" + first_date_column + str(GAP + i) + ":" + last_date_column + str(
GAP + i) + ")").fill = FILL_TOTAL
ws.cell(
row=GAP + i,
column=sum_cell_column,
value="=SUM("
+ first_date_column
+ str(GAP + i)
+ ":"
+ last_date_column
+ str(GAP + i)
+ ")",
).fill = FILL_TOTAL


def mark_absent(wb, studs_absent, class_name):
Expand Down Expand Up @@ -158,5 +166,5 @@ def attendance_workbook(class_name):
return wb


if __name__ == '__main__':
if __name__ == "__main__":
pass
25 changes: 19 additions & 6 deletions face_detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
class FaceDetect:
def __init__(self, class_name):
self.class_name = class_name
self.xml_file = os.path.join(os.getcwd(), 'haarcascade_frontalface_default.xml')
self.face_recognizer_file = os.path.join(os.getcwd(), 'extras', self.class_name, 'face_recognizer_file.xml')
self.xml_file = os.path.join(os.getcwd(), "haarcascade_frontalface_default.xml")
self.face_recognizer_file = os.path.join(
os.getcwd(), "extras", self.class_name, "face_recognizer_file.xml"
)

# detect faces on one image
def detect_faces(self, clf, bgr_img, scaleFactor=1.1):
Expand All @@ -21,7 +23,10 @@ def recognize(self, image_path, identity):
try:
face_recognizer.read(self.face_recognizer_file)
except:
messagebox.showerror('Error', "The class has no data to recongnize from\nor has not been trained yet")
messagebox.showerror(
"Error",
"The class has no data to recongnize from\nor has not been trained yet",
)
return "No Training Data"
test_img = cv2.imread(image_path)
test_img_gray = cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)
Expand All @@ -30,18 +35,26 @@ def recognize(self, image_path, identity):

students_in_pic = set()
for (x, y, w, h) in all_detected:
label, conf = face_recognizer.predict(test_img_gray[y:y + w, x:x + h])
label, conf = face_recognizer.predict(test_img_gray[y: y + w, x: x + h])
# print(conf)
cv2.waitKey(0)
label_text = identity[label]
students_in_pic.add(identity[label])
cv2.rectangle(test_img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(test_img, label_text, (x, y - 5), cv2.FONT_HERSHEY_PLAIN, 1.0, (0, 255, 0), 2)
cv2.putText(
test_img,
label_text,
(x, y - 5),
cv2.FONT_HERSHEY_PLAIN,
1.0,
(0, 255, 0),
2,
)
cv2.imshow("Students in this picture", test_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
return list(students_in_pic)


if __name__ == '__main__':
if __name__ == "__main__":
pass
27 changes: 17 additions & 10 deletions face_train.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@


class FaceTrain:

def __init__(self, class_name):
self.class_name = class_name
self.xml_file = os.path.join(os.getcwd(), 'haarcascade_frontalface_default.xml')
self.xml_file = os.path.join(os.getcwd(), "haarcascade_frontalface_default.xml")

def face_detect(self, image):
img = image.copy()
Expand All @@ -20,10 +19,10 @@ def face_detect(self, image):
return None, None
else:
(x, y, w, h) = faces[0]
return gray[y:y + w, x:x + h], faces[0]
return gray[y: y + w, x: x + h], faces[0]

def prepare_training_data(self):
training_data_dir = os.path.join(os.getcwd(), 'images', self.class_name)
training_data_dir = os.path.join(os.getcwd(), "images", self.class_name)
dirs = os.listdir(training_data_dir)
faces = []
labels = []
Expand All @@ -33,13 +32,17 @@ def prepare_training_data(self):
try:
label = int(dir_name.replace("s", ""))
except:
messagebox.showerror("Error",
"Unable to prepare training data for " + dir_name + "\nfolder in images directory does not follow the naming scheme")
messagebox.showerror(
"Error",
"Unable to prepare training data for "
+ dir_name
+ "\nfolder in images directory does not follow the naming scheme",
)
continue
subject_dir_path = os.path.join(training_data_dir, dir_name)
images = os.listdir(subject_dir_path)
for image_name in images:
if image_name.startswith('.'):
if image_name.startswith("."):
continue
img = cv2.imread(os.path.join(subject_dir_path, image_name))
face, rect = self.face_detect(img)
Expand All @@ -60,11 +63,15 @@ def main(self):
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
face_recognizer.train(faces, np.array(labels))

face_recognizer_file = os.path.join(os.getcwd(), 'extras', self.class_name, 'face_recognizer_file.xml')
face_recognizer_file = os.path.join(
os.getcwd(), "extras", self.class_name, "face_recognizer_file.xml"
)
face_recognizer.save(face_recognizer_file)

messagebox.showinfo("Training Successful", "Trained for {} images".format(len(faces)))
messagebox.showinfo(
"Training Successful", "Trained for {} images".format(len(faces))
)


if __name__ == '__main__':
if __name__ == "__main__":
pass
Loading

0 comments on commit 18b3b19

Please sign in to comment.