├── .gitattributes ├── .gitignore ├── .vscode └── settings.json ├── Attendance System.db ├── README.md ├── attendance_window.py ├── attendance_window_new.py ├── check_attendance.py ├── main_window.py ├── other_images ├── default.png └── logo.png ├── registration_images ├── Year1 │ ├── 1.jpg │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.jpg │ ├── 8.jpg │ └── 9.jpg └── Year2 │ ├── 1.jpg │ ├── 1.png │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.png │ ├── 16.png │ ├── 19.png │ ├── 2.jpg │ ├── 3.jpg │ ├── 33.png │ ├── 39.png │ ├── 4.jpg │ ├── 45.png │ ├── 47.png │ ├── 5.jpg │ ├── 6.jpg │ ├── 61.png │ ├── 67.png │ ├── 7.jpg │ ├── 70.png │ ├── 8.jpg │ └── 9.jpg ├── registration_window.py ├── support_files └── haarcascade_frontalface_default.xml ├── trainer └── trainer.yml └── videos └── IT301.mp4 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | 49 | __pycache__ 50 | temp 51 | .vscode -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.linting.pylintEnabled": false 3 | } -------------------------------------------------------------------------------- /Attendance System.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/Attendance System.db -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Automated_Attendance_System 2 | 3 | Automatic Attendance System is designed to collect and manage student’s attendance records from video camera devices installed in a class rooms. Based on the verification of student identification in the video cameras, attendance will be updated in data base. Attendance will be taken in every class at particular interval of time. 4 | 5 | ## GUI: 6 | The GUI of this project "Automated Attendance System" has been made using PyQt4 module of Python. It is basically seperated into three 7 | windows: 8 | 1.Main Window 9 | 2.Registration Window 10 | 3.Attendance Window 11 | 12 | ## FACE EXTRACTION & FACE DETECTION: 13 | The face detection and extraction part has been executed by the OpenCv(cv2) module of Python. Haar Casscade Classifiers have been used for 14 | frontal face detection. 15 | 16 | ## DATABASE HANDLING: 17 | The database handling i.e. storing student's information and attendance has been done in this project using sqlite3 module in Python. 18 | 19 | ## IMAGE ENHANCEMENT: 20 | The enhancement of image quality like adjusting brightness, sharpness ,etc will be done using PIL module in python 21 | 22 | ## WORKING: 23 | The program can be executed by running the main_window.py after you have installed libraries like PyQt4, cv2, numpy and PIL.The GUI will guide you to two windows one is the Registeration Window where a student can registered and the other is Attendance Window where attendance can be marked for a particular subject on a specific date.The other option is to check attendance for a subject on a given date. 24 | 25 | ## Getting Started 26 | To deploy this project on local machine you have to download complete code on your system.The program can be executed by running the main_window.py. 27 | 28 | ## Prerequisites 29 | What things you need to install the software and how to install them 30 | 31 | ``` 32 | Python 3.0 or later 33 | Python Libraries: 34 | * PIL 35 | * PyQt4 36 | * numpy 37 | * cv2 38 | ``` 39 | 40 | ## Built With 41 | * [Python](https://www.python.org/) - The programming language used 42 | * [PyQt4](https://pypi.python.org/pypi/PyQt4) - GUI Management 43 | * [cv2](https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_image_display/py_image_display.html) - Face Recognisation 44 | 45 | ## Contributing 46 | Project Head - [Subham Kumar Singh Rajput](https://github.com/mesksr) 47 | Project subordinates: 48 | [Dilpreet Singh Chawla](https://github.com/iamdsc) 49 | [Pranit De](https://github.com/Pranit18De) 50 | [Omkar Ajnadkar](https://github.com/Omkar-Ajnadkar) 51 | Pratik Gupta 52 | 53 | ## Versioning 54 | We use [GitHub](http://github.com/) for versioning. 55 | 56 | ## License 57 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 58 | -------------------------------------------------------------------------------- /attendance_window.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import os 4 | import time 5 | from PIL import Image, ImageEnhance, ImageStat 6 | import shutil 7 | import sqlite3 8 | import datetime 9 | import math 10 | 11 | from check_attendance import CheckAttendance 12 | from PyQt4 import QtGui,QtCore 13 | 14 | 15 | def improve_image(file_name): 16 | img = Image.open(file_name) 17 | stat = ImageStat.Stat(img) 18 | orglvl = stat.mean[0] 19 | 20 | #1 Brightness 21 | brght = ImageEnhance.Brightness(img) 22 | if (orglvl<100): 23 | x = 100/orglvl 24 | brght_img = brght.enhance(x) 25 | else: 26 | brght_img = brght.enhance(1.0) 27 | 28 | 29 | #2 Sharpness 30 | contrast = ImageEnhance.Sharpness(brght_img) 31 | shrp_img = contrast.enhance(1.0) 32 | 33 | #3 Color 34 | color = ImageEnhance.Color(shrp_img) 35 | clr_img = color.enhance(0.0) 36 | 37 | #4 Resize 38 | rsz_img = clr_img.resize((200, 200), Image.ANTIALIAS) 39 | return rsz_img 40 | 41 | conn=sqlite3.connect('Attendance System.db') 42 | c=conn.cursor() 43 | 44 | class AttendanceWindow(QtGui.QMainWindow): 45 | #Attendance Window 46 | def __init__(self): 47 | super(AttendanceWindow, self).__init__() 48 | self.setGeometry(300,50,800,600) 49 | self.setWindowTitle("Attendance") 50 | self.setWindowIcon(QtGui.QIcon('other_images/logo.png')) 51 | 52 | #Heading 53 | h=QtGui.QLabel(self) 54 | h.setAlignment(QtCore.Qt.AlignCenter) 55 | h.setGeometry(QtCore.QRect(200,20,400,50)) 56 | h.setStyleSheet("QLabel { background-color : blue;color :white ; }") 57 | font=QtGui.QFont("Times",20,QtGui.QFont.Bold) 58 | h.setFont(font) 59 | h.setText("ATTENDANCE") 60 | 61 | #Label and Subject code entry 62 | l=QtGui.QLabel(self) 63 | l.setAlignment(QtCore.Qt.AlignCenter) 64 | l.setGeometry(QtCore.QRect(275,140,250,30)) 65 | l.setStyleSheet("QLabel { background-color:green;color: white;}") 66 | font=QtGui.QFont("Times",16,QtGui.QFont.Bold) 67 | l.setFont(font) 68 | l.setText("ENTER SUB-CODE") 69 | 70 | self.e = QtGui.QLineEdit(self) 71 | self.e.setGeometry(275,175,250,50) 72 | self.e.setAlignment(QtCore.Qt.AlignCenter) 73 | self.e.setFont(QtGui.QFont("Times",18,QtGui.QFont.Bold)) 74 | 75 | #Recording Button 76 | b1=QtGui.QPushButton(self) 77 | b1.setText("RECORD AND MARK") 78 | b1.setStyleSheet("QPushButton { background-color : gray;color : black ; }") 79 | b1.setFont(font) 80 | b1.setGeometry(250,300,300,50) 81 | b1.clicked.connect(self.record_and_mark) 82 | 83 | #Check Attendance button to check specific subject's Attendance 84 | b2=QtGui.QPushButton(self) 85 | b2.setText("CHECK ATTENDANCE") 86 | b2.setStyleSheet("QPushButton { background-color : gray;color : black ; }") 87 | b2.setFont(font) 88 | b2.setGeometry(250,425,300,50) 89 | b2.clicked.connect(self.create_check_attendance) 90 | 91 | #Button to go back to Attendance Window 92 | b1=QtGui.QPushButton(self) 93 | b1.setText("<< BACK") 94 | b1.setFont(QtGui.QFont("Times",12,QtGui.QFont.Bold)) 95 | b1.setGeometry(40,540,80,20) 96 | b1.setStyleSheet("QPushButton { background-color : blue;color : white;}") 97 | b1.clicked.connect(self.back) 98 | 99 | def back(self): 100 | self.close() 101 | 102 | def create_check_attendance(self): 103 | #To check Validity of Subject Code 104 | sub=["IT401","IT201"] #TO DO - GET THESE FROM TABLE 105 | if self.e.text() in sub: 106 | self._check_attendance = CheckAttendance(self.e.text()) 107 | self._check_attendance.show() 108 | 109 | def record_and_mark(self): 110 | self.record() #to record the video and save it to folder 'videos' 111 | self.get_snaps() #to get snaps from the recorded video 112 | self.extract_faces() #to read all faces from the snaps 113 | self.match() #match extracted faces to those in database and update the database 114 | 115 | def record(self): 116 | #to save video with the name self.e.text() 117 | return 118 | 119 | def get_snaps(self): 120 | print ("cleaning past data") 121 | shutil.rmtree("temp",ignore_errors=True) 122 | print ("creating directories") 123 | os.mkdir("temp") 124 | os.mkdir("temp/presentFaces") 125 | os.mkdir("temp/frames") 126 | os.mkdir("temp/rawPresentFaces") 127 | print ("starting taking snaps") 128 | video_name = str(self.e.text()) 129 | crop_time = 2 130 | time_gap = 2 131 | #cv2 object created that uses the video capture function to open the video file 132 | cap = cv2.VideoCapture("videos/"+video_name+".mp4") 133 | fps = int(cap.get(cv2.CAP_PROP_FPS)) 134 | length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) 135 | count = fps*(crop_time) 136 | i = 0 137 | cap.set(1,68) 138 | while (cap.isOpened()): 139 | ret , frame = cap.read() 140 | if(count>length): 141 | break 142 | cv2.waitKey(3) 143 | if( (count == (crop_time*fps + i*time_gap*fps)) &(count < length)): 144 | cv2.imwrite('temp/frames/frame'+str(i)+'.jpg',frame) 145 | i = i+1 146 | print('snap taken @', count) 147 | count = count + 1 148 | cap.release() 149 | cv2.destroyAllWindows() 150 | print (i, "snaps taken") 151 | 152 | def extract_faces(self): 153 | i=0 154 | face_cascade = cv2.CascadeClassifier("support_files/haarcascade_frontalface_default.xml") 155 | for eachImg in os.listdir("temp/frames"): 156 | print(eachImg, 'read') 157 | img = cv2.imread("temp/frames/" + eachImg, 0) 158 | faces = face_cascade.detectMultiScale(img) 159 | for(x,y,w,h) in faces: 160 | sub_face = img[y:y+h, x:x+w] 161 | face_file_name = "temp/rawPresentFaces/face_" + str(i) + ".jpg" 162 | cv2.imwrite(face_file_name, sub_face) 163 | new_image = improve_image(face_file_name) 164 | new_image.save("temp/presentFaces/face_" + str(i) + ".jpg") 165 | i=i+1 166 | cv2.waitKey(0) 167 | cv2.destroyAllWindows() 168 | print (i, 'faces read') 169 | 170 | def match(self): 171 | print ("matching starts") 172 | subject = str(self.e.text()) 173 | 174 | # getting all the rolls, names of year 2 students from database 175 | xyear = (int(subject[2])+1)//2 176 | 177 | recognizer = cv2.face.LBPHFaceRecognizer_create() 178 | detector= cv2.CascadeClassifier("support_files/haarcascade_frontalface_default.xml") 179 | 180 | #create empth face list 181 | faceSamples=[] 182 | #create empty ID list 183 | Ids=[] 184 | 185 | def getImagesAndLabels(path, faceSamples, Ids): 186 | #get the path of all the files in the folder 187 | imagePaths=[os.path.join(path,f) for f in os.listdir(path)] 188 | #now looping through all the image paths and loading the Ids and the images 189 | for imagePath in imagePaths: 190 | #loading the image and converting it to gray scale 191 | pilImage=Image.open(imagePath).convert('L') 192 | #converting the PIL image into numpy array 193 | imageNp=np.array(pilImage,'uint8') 194 | #getting Id from image 195 | Id=int(os.path.split(imagePath)[1].split(".")[0]) 196 | # extract face from image sample 197 | faces=detector.detectMultiScale(imageNp) 198 | #append that in the list as well as Id of it 199 | for (x,y,w,h) in faces: 200 | faceSamples.append(imageNp[y:y+h,x:x+w]) 201 | Ids.append(Id) 202 | cv2.waitKey(100) 203 | return faceSamples,Ids 204 | 205 | def faceDetector(path): 206 | recognizer.read("trainer/trainer.yml") 207 | present = [] 208 | imagePaths=[os.path.join(path,f) for f in os.listdir(path)] 209 | for imagePath in imagePaths: 210 | img = cv2.imread(imagePath) 211 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 212 | id, conf = recognizer.predict(gray) 213 | present.append(id) 214 | present = set(present) 215 | return list(present) 216 | 217 | shutil.rmtree("trainer",ignore_errors=True) 218 | os.mkdir("trainer") 219 | faces, Ids = getImagesAndLabels("registration_images/Year"+str(xyear), faceSamples, Ids) 220 | recognizer.train(faces, np.array(Ids)) 221 | recognizer.write('trainer/trainer.yml') 222 | present = faceDetector("temp/presentFaces") 223 | print(present) 224 | 225 | 226 | 227 | query='SELECT * FROM YEAR{};'.format(xyear) 228 | c.execute(query) 229 | rolls = [] 230 | names = [] 231 | for row in c.fetchall(): 232 | rolls.append(row[0]) 233 | names.append(row[1]) 234 | 235 | temp = [] 236 | for r in rolls: 237 | if (r in present): 238 | temp.append('P') 239 | else: 240 | temp.append('A') 241 | 242 | date = str(datetime.date.today().year)+str(datetime.date.today().month)+str(datetime.date.today().day) 243 | query="INSERT INTO {} VALUES ({},'{}');".format(subject, date, "','".join(temp)) 244 | print (query) 245 | c.execute(query) 246 | print ("Query executed") 247 | 248 | 249 | 250 | 251 | if __name__ == '__main__': 252 | app = QtGui.QApplication([]) 253 | gui = AttendanceWindow() 254 | gui.show() 255 | app.exec_() 256 | c.close() 257 | conn.commit() 258 | print ("Data committed") 259 | conn.close() 260 | -------------------------------------------------------------------------------- /attendance_window_new.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import os 4 | import time 5 | from PIL import Image, ImageEnhance, ImageStat 6 | import shutil 7 | import sqlite3 8 | import datetime 9 | import math 10 | import face_recognition 11 | 12 | from check_attendance import CheckAttendance 13 | from PyQt4 import QtGui,QtCore 14 | 15 | def improve_image(file_name): 16 | img = Image.open(file_name) 17 | stat = ImageStat.Stat(img) 18 | orglvl = stat.mean[0] 19 | 20 | #1 Brightness 21 | brght = ImageEnhance.Brightness(img) 22 | if (orglvl<100): 23 | x = 100/orglvl 24 | brght_img = brght.enhance(x) 25 | else: 26 | brght_img = brght.enhance(1.0) 27 | 28 | 29 | #2 Sharpness 30 | contrast = ImageEnhance.Sharpness(brght_img) 31 | shrp_img = contrast.enhance(1.0) 32 | 33 | #3 Color 34 | color = ImageEnhance.Color(shrp_img) 35 | clr_img = color.enhance(0.0) 36 | 37 | #4 Resize 38 | rsz_img = clr_img.resize((200, 200), Image.ANTIALIAS) 39 | return rsz_img 40 | 41 | conn=sqlite3.connect('Attendance System.db') 42 | c=conn.cursor() 43 | 44 | class AttendanceWindow(QtGui.QMainWindow): 45 | #Attendance Window 46 | def __init__(self): 47 | super(AttendanceWindow, self).__init__() 48 | self.setGeometry(300,50,800,600) 49 | self.setWindowTitle("Attendance") 50 | self.setWindowIcon(QtGui.QIcon('other_images/logo.png')) 51 | 52 | #Heading 53 | h=QtGui.QLabel(self) 54 | h.setAlignment(QtCore.Qt.AlignCenter) 55 | h.setGeometry(QtCore.QRect(200,20,400,50)) 56 | h.setStyleSheet("QLabel { background-color : blue;color :white ; }") 57 | font=QtGui.QFont("Times",20,QtGui.QFont.Bold) 58 | h.setFont(font) 59 | h.setText("ATTENDANCE") 60 | 61 | #Label and Subject code entry 62 | l=QtGui.QLabel(self) 63 | l.setAlignment(QtCore.Qt.AlignCenter) 64 | l.setGeometry(QtCore.QRect(275,140,250,30)) 65 | l.setStyleSheet("QLabel { background-color:green;color: white;}") 66 | font=QtGui.QFont("Times",16,QtGui.QFont.Bold) 67 | l.setFont(font) 68 | l.setText("ENTER SUB-CODE") 69 | 70 | self.e = QtGui.QLineEdit(self) 71 | self.e.setGeometry(275,175,250,50) 72 | self.e.setAlignment(QtCore.Qt.AlignCenter) 73 | self.e.setFont(QtGui.QFont("Times",18,QtGui.QFont.Bold)) 74 | 75 | #Recording Button 76 | b1=QtGui.QPushButton(self) 77 | b1.setText("RECORD AND MARK") 78 | b1.setStyleSheet("QPushButton { background-color : gray;color : black ; }") 79 | b1.setFont(font) 80 | b1.setGeometry(250,300,300,50) 81 | b1.clicked.connect(self.record_and_mark) 82 | 83 | #Check Attendance button to check specific subject's Attendance 84 | b2=QtGui.QPushButton(self) 85 | b2.setText("CHECK ATTENDANCE") 86 | b2.setStyleSheet("QPushButton { background-color : gray;color : black ; }") 87 | b2.setFont(font) 88 | b2.setGeometry(250,425,300,50) 89 | b2.clicked.connect(self.create_check_attendance) 90 | 91 | def create_check_attendance(self): 92 | #To check Validity of Subject Code 93 | sub=["IT301","IT302"] #TO DO - GET THESE FROM TABLE 94 | if self.e.text() in sub: 95 | self._check_attendance = CheckAttendance(self.e.text()) 96 | self._check_attendance.show() 97 | 98 | def record_and_mark(self): 99 | self.record() #to record the video and save it to folder 'videos' 100 | self.get_snaps() #to get snaps from the recorded video 101 | self.extract_faces() #to read all faces from the snaps 102 | self.match() #match extracted faces to those in database and update the database 103 | 104 | def record(self): 105 | #to save video with the name self.e.text() 106 | return 107 | 108 | def get_snaps(self): 109 | shutil.rmtree("temp",ignore_errors=True) 110 | os.mkdir("temp") 111 | os.mkdir("temp/presentFaces") 112 | os.mkdir("temp/frames") 113 | os.mkdir("temp/rawPresentFaces") 114 | video_name = str(self.e.text()) 115 | crop_time = 2 116 | time_gap = 2 117 | #cv2 object created that uses the video capture function to open the video file 118 | cap = cv2.VideoCapture("videos/"+video_name+".mp4") 119 | fps = int(cap.get(cv2.CAP_PROP_FPS)) 120 | length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) 121 | count = fps*(crop_time) 122 | i = 0 123 | cap.set(1,68) 124 | while (cap.isOpened()): 125 | ret , frame = cap.read() 126 | if(count>length): 127 | break 128 | cv2.waitKey(3) 129 | if( (count == (crop_time*fps + i*time_gap*fps)) &(count < length)): 130 | cv2.imwrite('temp/frames/frame'+str(i)+'.jpg',frame) 131 | i = i+1 132 | print('snap taken @', count) 133 | count = count + 1 134 | cap.release() 135 | cv2.destroyAllWindows() 136 | print (i, "snaps taken") 137 | 138 | 139 | def extract_faces(self): 140 | i=0 141 | face_cascade = cv2.CascadeClassifier("support_files/haarcascade_frontalface_default.xml") 142 | for eachImg in os.listdir("temp/frames"): 143 | print(eachImg, 'read') 144 | img = cv2.imread("temp/frames/" + eachImg, 0) 145 | faces = face_cascade.detectMultiScale(img) 146 | for(x,y,w,h) in faces: 147 | sub_face = img[y:y+h, x:x+w] 148 | face_file_name = "temp/rawPresentFaces/face_" + str(i) + ".jpg" 149 | cv2.imwrite(face_file_name, sub_face) 150 | new_image = improve_image(face_file_name) 151 | new_image.save("temp/presentFaces/face_" + str(i) + ".jpg") 152 | i=i+1 153 | cv2.waitKey(0) 154 | cv2.destroyAllWindows() 155 | print (i, 'faces read') 156 | 157 | def match(self): 158 | subject = str(self.e.text()) 159 | xyear = (int(subject[2])+1)//2 160 | # registration picts are in "registration_images/Year2" -> picts are labelled with roll no. 161 | # extracted faces are in "temp/presentFaces" 162 | 163 | present = {} 164 | known_faces = [] 165 | known_faces_names = [] 166 | path = "registration_images/Year"+str(xyear) 167 | imagePaths=[os.path.join(path,f) for f in os.listdir(path)] 168 | for imagePath in imagePaths: 169 | img = face_recognition.load_image_file(imagePath) 170 | known_faces_names.append(imagePath.split(".")[0].split("\\")[1]) 171 | if len(face_recognition.face_encodings(img)) != 0: 172 | known_faces.append(face_recognition.face_encodings(img)[0]) 173 | # print(known_faces_names) 174 | path = "temp/presentFaces" 175 | imagePaths=[os.path.join(path,f) for f in os.listdir(path)] 176 | for imagePath in imagePaths: 177 | img = face_recognition.load_image_file(imagePath) 178 | try: 179 | unknown_face_encoading = face_recognition.face_encodings(img)[0] 180 | except IndexError: 181 | continue 182 | print(imagePath," Read...") 183 | results = face_recognition.compare_faces(known_faces, unknown_face_encoading) 184 | indices = [i for i, x in enumerate(results) if x == True] 185 | for each in indices: 186 | present[known_faces_names[each]] = "Present" 187 | print(present) 188 | 189 | #present = {'33': 'Present', '70': 'Present', '39': 'Present', '67': 'Present', '1': 'Present'}#this dictionary will have the rolls of all students with status. 190 | 191 | # getting all the rolls, names of year 2 students from database 192 | xyear = (int(subject[2])+1)//2 193 | 194 | query='SELECT * FROM YEAR{};'.format(xyear) 195 | c.execute(query) 196 | rolls = [] 197 | names = [] 198 | for row in c.fetchall(): 199 | rolls.append(row[0]) 200 | names.append(row[1]) 201 | 202 | temp = [] 203 | for r in rolls: 204 | if (r in present): 205 | temp.append('P') 206 | else: 207 | temp.append('A') 208 | 209 | rolls = list(map(str, rolls)) 210 | query='INSERT INTO VALUES (20171018,{});'.format(subject, ','.join(rolls), ','.join(temp)) 211 | print (query) 212 | c.execute(query) 213 | 214 | 215 | if __name__ == '__main__': 216 | app = QtGui.QApplication([]) 217 | gui = AttendanceWindow() 218 | gui.show() 219 | app.exec_() 220 | c.close() 221 | conn.commit() 222 | print ("Data committed") 223 | conn.close() -------------------------------------------------------------------------------- /check_attendance.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtGui,QtCore 2 | import sqlite3 3 | import datetime 4 | 5 | 6 | conn=sqlite3.connect('Attendance System.db') 7 | c=conn.cursor() 8 | 9 | class CheckAttendance(QtGui.QMainWindow): 10 | def __init__(self,sub="IT301"): 11 | self.subject=sub 12 | 13 | super(CheckAttendance, self).__init__() 14 | self.setGeometry(300,50,800,600) 15 | self.setWindowTitle("Check Attendance") 16 | self.setWindowIcon(QtGui.QIcon('other_images/logo.png')) 17 | 18 | #Heading 19 | h=QtGui.QLabel(self) 20 | h.setAlignment(QtCore.Qt.AlignCenter) 21 | h.setGeometry(QtCore.QRect(250,20,300,40)) 22 | h.setStyleSheet("QLabel { background-color : blue;color :white ; }") 23 | font=QtGui.QFont("Times",16,QtGui.QFont.Bold) 24 | h.setFont(font) 25 | h.setText("CHECK ATTENDANCE") 26 | 27 | #Label and Date Entry Spinbox 28 | l2=QtGui.QLabel(self) 29 | l2.setAlignment(QtCore.Qt.AlignCenter) 30 | l2.setGeometry(QtCore.QRect(230,100,80,30)) 31 | l2.setStyleSheet("QLabel { background-color : gray;color :black ; }") 32 | font1=QtGui.QFont("Times",14,QtGui.QFont.Bold) 33 | l2.setFont(font1) 34 | l2.setText("DATE") 35 | 36 | self.dd=QtGui.QSpinBox(self) 37 | self.dd.setAlignment(QtCore.Qt.AlignCenter) 38 | self.dd.setGeometry(330,100,50,30) 39 | self.dd.setFont(font1) 40 | self.dd.setRange(1,31) 41 | self.dd.setValue(datetime.date.today().day) 42 | 43 | self.mm=QtGui.QSpinBox(self) 44 | self.mm.setAlignment(QtCore.Qt.AlignCenter) 45 | self.mm.setGeometry(380,100,50,30) 46 | self.mm.setFont(font1) 47 | self.mm.setRange(1,12) 48 | self.mm.setValue(datetime.date.today().month) 49 | 50 | self.yyyy=QtGui.QSpinBox(self) 51 | self.yyyy.setGeometry(430,100,70,30) 52 | self.yyyy.setFont(font1) 53 | self.yyyy.setRange(2014,2050) 54 | self.yyyy.setValue(datetime.date.today().year) 55 | 56 | #Go Button to check specific Date's Attendance 57 | b=QtGui.QPushButton(self) 58 | b.setText("GO!") 59 | b.setFont(font1) 60 | b.setGeometry(510,100,60,30) 61 | b.setStyleSheet("QPushButton { background-color : green;color : white ; }") 62 | b.clicked.connect(self.show_database) 63 | 64 | #Text Area To display database 65 | self.text=QtGui.QTextEdit(self) 66 | self.text.setGeometry(40,170,720,350) 67 | self.text.setFont(font1) 68 | 69 | #Default Display of Subject's Total Attendance on every date 70 | xyear = (int(self.subject[2])+1)//2 71 | query='SELECT * FROM YEAR{}'.format(xyear) 72 | c.execute(query) 73 | rolls = [] 74 | names = [] 75 | for row in c.fetchall(): 76 | rolls.append(row[0]) 77 | names.append(row[1]) 78 | 79 | self.text.insertPlainText('Roll\tName\tAttendance %\n') 80 | 81 | for i in range(len(rolls)): 82 | query='SELECT ['+ str(rolls[i]) + '] FROM {}'.format(self.subject) 83 | print (query) 84 | c.execute(query) 85 | p = 0 #present 86 | a = 0 #absent 87 | for row in c.fetchall(): 88 | if (row[0] == 'P'): 89 | p += 1 90 | else: 91 | a += 1 92 | self.text.insertPlainText(str(rolls[i])+'\t'+str(names[i])+'\t'+str((100*p)/(p+a))+'\n') 93 | 94 | #Button to go back to Attendance Window 95 | b1=QtGui.QPushButton(self) 96 | b1.setText("<< BACK") 97 | b1.setFont(QtGui.QFont("Times",12,QtGui.QFont.Bold)) 98 | b1.setGeometry(40,540,80,20) 99 | b1.setStyleSheet("QPushButton { background-color : blue;color : white;}") 100 | b1.clicked.connect(self.back) 101 | 102 | def back(self): 103 | self.close() 104 | 105 | def show_database(self): 106 | #To display attendance on specific date 107 | date=str(self.yyyy.value())+str(self.mm.value())+str(self.dd.value()) 108 | self.text.clear() 109 | temp = 'Roll\tName\t'+self.format_date(date) 110 | self.text.insertPlainText(temp+'\n') 111 | 112 | xyear = (int(self.subject[2])+1)//2 113 | query='SELECT * FROM YEAR{}'.format(xyear) 114 | c.execute(query) 115 | rolls = [] 116 | names = [] 117 | for row in c.fetchall(): 118 | rolls.append(row[0]) 119 | names.append(row[1]) 120 | 121 | for i in range(len(rolls)): 122 | query='SELECT Date, ['+ str(rolls[i]) + '] FROM {} where Date = {}'.format(self.subject, date) 123 | print (query) 124 | c.execute(query) 125 | temp = str(rolls[i])+'\t'+str(names[i])+'\t' 126 | for row in c.fetchall(): 127 | temp += (row[1]) 128 | self.text.insertPlainText(temp+'\n') 129 | 130 | def format_date(self, s): 131 | year = s[:4] 132 | month = s[4:6] 133 | date = s[6:] 134 | return date+'-'+month+'-'+year 135 | 136 | if __name__ == '__main__': 137 | app = QtGui.QApplication([]) 138 | gui = CheckAttendance() 139 | gui.show() 140 | app.exec_() 141 | c.close() 142 | conn.close() 143 | 144 | -------------------------------------------------------------------------------- /main_window.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtGui,QtCore 2 | from registration_window import RegistrationWindow 3 | from attendance_window import AttendanceWindow 4 | 5 | class MainWindow(QtGui.QMainWindow): 6 | #Main Window of Interface 7 | def __init__(self): 8 | super(MainWindow, self).__init__() 9 | self._registration_window = None 10 | self._attendance_window = None 11 | self.setGeometry(300,50,800,600) 12 | self.setWindowTitle("Automated Attendance System") 13 | self.setWindowIcon(QtGui.QIcon('other_images/logo.png')) 14 | 15 | #Heading 16 | h=QtGui.QLabel(self) 17 | h.setAlignment(QtCore.Qt.AlignCenter) 18 | h.setGeometry(QtCore.QRect(100,30,600,60)) 19 | h.setStyleSheet("QLabel { background-color : blue;color :white ; }") 20 | font=QtGui.QFont("Times",20,QtGui.QFont.Bold) 21 | h.setFont(font) 22 | h.setText("AUTOMATED ATTENDANCE SYSTEM") 23 | 24 | #Registration Button for opening registration window 25 | b1=QtGui.QPushButton(self) 26 | b1.setText("REGISTRATION") 27 | font1=QtGui.QFont("Times",16,QtGui.QFont.Bold) 28 | b1.setFont(font1) 29 | b1.setGeometry(450,200,200,50) 30 | b1.setStyleSheet("QPushButton { background-color : gray;color :black ; }") 31 | b1.clicked.connect(self.create_registration_window) 32 | 33 | #Attendance Button for opening attendance window 34 | b2=QtGui.QPushButton(self) 35 | b2.setText("ATTENDANCE") 36 | b2.setFont(font1) 37 | b2.setGeometry(450,350,200,50) 38 | b2.setStyleSheet("QPushButton { background-color : gray;color :black ; }") 39 | b2.clicked.connect(self.create_attendance_window) 40 | 41 | #Adding Logo of college 42 | pic =QtGui.QLabel(self) 43 | pic.setGeometry(80,150,300,350) 44 | pic.setPixmap(QtGui.QPixmap("other_images/logo.png")) 45 | 46 | def create_registration_window(self): 47 | #Function for opening Registration window 48 | self._registration_window = RegistrationWindow() 49 | self._registration_window.show() 50 | self.close() 51 | 52 | def create_attendance_window(self): 53 | #Function for opening Attendance window 54 | self._attendance_window = AttendanceWindow() 55 | self._attendance_window.show() 56 | self.close() 57 | 58 | if __name__ == '__main__': 59 | app = QtGui.QApplication([]) 60 | gui = MainWindow() 61 | gui.show() 62 | app.exec_() 63 | -------------------------------------------------------------------------------- /other_images/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/other_images/default.png -------------------------------------------------------------------------------- /other_images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/other_images/logo.png -------------------------------------------------------------------------------- /registration_images/Year1/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/1.jpg -------------------------------------------------------------------------------- /registration_images/Year1/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/10.jpg -------------------------------------------------------------------------------- /registration_images/Year1/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/11.jpg -------------------------------------------------------------------------------- /registration_images/Year1/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/12.jpg -------------------------------------------------------------------------------- /registration_images/Year1/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/2.jpg -------------------------------------------------------------------------------- /registration_images/Year1/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/3.jpg -------------------------------------------------------------------------------- /registration_images/Year1/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/4.jpg -------------------------------------------------------------------------------- /registration_images/Year1/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/5.jpg -------------------------------------------------------------------------------- /registration_images/Year1/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/6.jpg -------------------------------------------------------------------------------- /registration_images/Year1/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/7.jpg -------------------------------------------------------------------------------- /registration_images/Year1/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/8.jpg -------------------------------------------------------------------------------- /registration_images/Year1/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year1/9.jpg -------------------------------------------------------------------------------- /registration_images/Year2/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/1.jpg -------------------------------------------------------------------------------- /registration_images/Year2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/1.png -------------------------------------------------------------------------------- /registration_images/Year2/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/10.jpg -------------------------------------------------------------------------------- /registration_images/Year2/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/11.jpg -------------------------------------------------------------------------------- /registration_images/Year2/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/12.jpg -------------------------------------------------------------------------------- /registration_images/Year2/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/13.png -------------------------------------------------------------------------------- /registration_images/Year2/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/16.png -------------------------------------------------------------------------------- /registration_images/Year2/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/19.png -------------------------------------------------------------------------------- /registration_images/Year2/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/2.jpg -------------------------------------------------------------------------------- /registration_images/Year2/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/3.jpg -------------------------------------------------------------------------------- /registration_images/Year2/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/33.png -------------------------------------------------------------------------------- /registration_images/Year2/39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/39.png -------------------------------------------------------------------------------- /registration_images/Year2/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/4.jpg -------------------------------------------------------------------------------- /registration_images/Year2/45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/45.png -------------------------------------------------------------------------------- /registration_images/Year2/47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/47.png -------------------------------------------------------------------------------- /registration_images/Year2/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/5.jpg -------------------------------------------------------------------------------- /registration_images/Year2/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/6.jpg -------------------------------------------------------------------------------- /registration_images/Year2/61.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/61.png -------------------------------------------------------------------------------- /registration_images/Year2/67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/67.png -------------------------------------------------------------------------------- /registration_images/Year2/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/7.jpg -------------------------------------------------------------------------------- /registration_images/Year2/70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/70.png -------------------------------------------------------------------------------- /registration_images/Year2/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/8.jpg -------------------------------------------------------------------------------- /registration_images/Year2/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/registration_images/Year2/9.jpg -------------------------------------------------------------------------------- /registration_window.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import sqlite3 3 | from PyQt4 import QtGui,QtCore 4 | 5 | 6 | class RegistrationWindow(QtGui.QMainWindow): 7 | #Registration window for student registration 8 | 9 | def __init__(self): 10 | super(RegistrationWindow, self).__init__() 11 | 12 | #Creating Registration Window 13 | self.setGeometry(300,50,800,600) 14 | self.setWindowTitle("Registration") 15 | self.setWindowIcon(QtGui.QIcon('other_images/logo.png')) 16 | 17 | #Heading 18 | h=QtGui.QLabel(self) 19 | h.setAlignment(QtCore.Qt.AlignCenter) 20 | h.setGeometry(QtCore.QRect(100,30,600,60)) 21 | h.setStyleSheet("QLabel { background-color : blue;color :white ; }") 22 | font=QtGui.QFont("Times",20,QtGui.QFont.Bold) 23 | h.setFont(font) 24 | h.setText("REGISTRATION") 25 | 26 | #Pseudo photo ID to be replaced by Student's Photo 27 | self.pic=QtGui.QLabel(self) 28 | self.pic.setGeometry(50,120,320,320) 29 | self.pic.setPixmap(QtGui.QPixmap("other_images/default.png")) 30 | 31 | #Button for opening Webcam and take photo 32 | b=QtGui.QPushButton(self) 33 | b.setText("CLICK") 34 | b.setFont(QtGui.QFont("Times",12,QtGui.QFont.Bold)) 35 | b.setGeometry(100,420,100,30) 36 | b.clicked.connect(self.take_photo) 37 | 38 | #SET OF ENTRIES 39 | #Taking Student's Name 40 | l1=QtGui.QLabel(self) 41 | l1.setAlignment(QtCore.Qt.AlignCenter) 42 | l1.setGeometry(QtCore.QRect(310,150,130,30)) 43 | l1.setStyleSheet("QLabel { background-color : gray;color :black ; }") 44 | font=QtGui.QFont("Times",14,QtGui.QFont.Bold) 45 | l1.setFont(font) 46 | l1.setText("NAME") 47 | 48 | self.e1=QtGui.QLineEdit(self) 49 | self.e1.setGeometry(450,150,300,30) 50 | self.e1.setAlignment(QtCore.Qt.AlignCenter) 51 | font1=QtGui.QFont("Arial",14) 52 | self.e1.setFont(font1) 53 | 54 | #Taking Student's Registration Number 55 | l2=QtGui.QLabel(self) 56 | l2.setAlignment(QtCore.Qt.AlignCenter) 57 | l2.setGeometry(QtCore.QRect(310,250,130,30)) 58 | l2.setStyleSheet("QLabel { background-color : gray;color :black ; }") 59 | l2.setFont(font) 60 | l2.setText("ROLL NO.") 61 | 62 | self.e2=QtGui.QLineEdit(self) 63 | self.e2.setGeometry(450,250,300,30) 64 | self.e2.setAlignment(QtCore.Qt.AlignCenter) 65 | self.e2.setFont(font1) 66 | 67 | #Taking Student's Year of Study 68 | l3=QtGui.QLabel(self) 69 | l3.setAlignment(QtCore.Qt.AlignCenter) 70 | l3.setGeometry(QtCore.QRect(310,350,130,30)) 71 | l3.setStyleSheet("QLabel { background-color : gray;color :black ; }") 72 | l3.setFont(font) 73 | l3.setText("YEAR") 74 | 75 | self.e3=QtGui.QLineEdit(self) 76 | self.e3.setGeometry(450,350,300,30) 77 | self.e3.setAlignment(QtCore.Qt.AlignCenter) 78 | self.e3.setFont(font1) 79 | 80 | #Button for clearing fields 81 | b2=QtGui.QPushButton(self) 82 | b2.setText("RESET") 83 | b2.setFont(QtGui.QFont("Times",12,QtGui.QFont.Bold)) 84 | b2.setGeometry(650,450,100,30) 85 | b2.setStyleSheet("QPushButton { background-color : red ;color : white ; }") 86 | self.entries=[self.e1,self.e2,self.e3] 87 | b2.clicked.connect(self.erase) 88 | 89 | #Label for displaying message 90 | self.l4=QtGui.QLabel(self) 91 | self.l4.setAlignment(QtCore.Qt.AlignCenter) 92 | self.l4.setStyleSheet("QLabel { color:green ; }") 93 | self.l4.setFont(QtGui.QFont('Times',13)) 94 | 95 | #Button for submission of data and storing in database 96 | b1=QtGui.QPushButton(self) 97 | b1.setText("SUBMIT") 98 | b1.setFont(QtGui.QFont("Times",12,QtGui.QFont.Bold)) 99 | b1.setGeometry(520,450,100,30) 100 | b1.setStyleSheet("QPushButton { background-color : green;color : white ; }") 101 | b1.clicked.connect(self.store_in_database) 102 | 103 | #Button to go back to Attendance Window 104 | b1=QtGui.QPushButton(self) 105 | b1.setText("<< BACK") 106 | b1.setFont(QtGui.QFont("Times",12,QtGui.QFont.Bold)) 107 | b1.setGeometry(40,540,80,20) 108 | b1.setStyleSheet("QPushButton { background-color : blue;color : white;}") 109 | b1.clicked.connect(self.back) 110 | 111 | def back(self): 112 | self.close() 113 | 114 | def erase(self): 115 | #function for clearing fields and changing to default 116 | for entry in self.entries: 117 | entry.clear() 118 | self.pic.setPixmap(QtGui.QPixmap("other_images/default.png")) 119 | self.l4.setText("") 120 | 121 | def take_photo(self): 122 | #Function for clicking,displaying and storing photo 123 | check_value = self.check() 124 | if (check_value == 1): 125 | self.l4.setGeometry(QtCore.QRect(40,500,250,30)) 126 | self.l4.setText("Invalid Name") 127 | elif (check_value == 2): 128 | self.l4.setGeometry(QtCore.QRect(40,500,250,30)) 129 | self.l4.setText("Roll - Out of Range") 130 | elif (check_value == 3): 131 | self.l4.setGeometry(QtCore.QRect(40,500,250,30)) 132 | self.l4.setText("Year should be between 1 to 4") 133 | else: 134 | face_cascade=cv2.CascadeClassifier('support_files/haarcascade_frontalface_default.xml') 135 | cap=cv2.VideoCapture(0) 136 | while True: 137 | ret,img=cap.read() 138 | gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 139 | face=face_cascade.detectMultiScale(gray,1.3,5) 140 | for (x,y,w,h) in face: 141 | roi_color=img[y:y+h,x:x+w] 142 | cv2.imwrite(str(r'C:\\Users\\mesksr\\Documents\\GitHub\\automatic-attendance-system\\registration_images\\Year' + 143 | str(self.e3.text())+'\\'+str(self.e2.text())+'.png'),roi_color) 144 | cv2.imshow('img',img) 145 | k=cv2.waitKey(30) & 0xff 146 | if k==27: 147 | break 148 | cap.release() 149 | cv2.destroyAllWindows() 150 | self.pic.setPixmap(QtGui.QPixmap(str(r'C:\\Users\\mesksr\\Documents\\GitHub\\automatic-attendance-system\\registration_images\\Year' + 151 | str(self.e3.text())+'\\'+str(self.e2.text())+'.png'))) 152 | 153 | def store_in_database(self): 154 | #Function for storing information in database 155 | check_value = self.check() 156 | print ('>>', check_value) 157 | if (check_value == 0): 158 | conn=sqlite3.connect('Attendance System.db') 159 | c=conn.cursor() 160 | c.execute('CREATE TABLE IF NOT EXISTS YEAR' + str(self.e3.text()) + ' (Roll INT, Name TEXT)') 161 | (name,regno,year)=(self.e1.text(),int(self.e2.text()),int(self.e3.text())) 162 | c.execute('INSERT INTO YEAR' + str(self.e3.text()) + ' (Roll,Name) VALUES(?,?)',(regno,name)) 163 | conn.commit() 164 | c.close() 165 | conn.close() 166 | #Displaying message after successful submission 167 | self.l4.setGeometry(QtCore.QRect(40,500,250,30)) 168 | self.l4.setText("Successfully Registered") 169 | elif (check_value == 1): 170 | self.l4.setGeometry(QtCore.QRect(40,500,250,30)) 171 | self.l4.setText("Invalid Name") 172 | elif (check_value == 2): 173 | self.l4.setGeometry(QtCore.QRect(40,500,250,30)) 174 | self.l4.setText("Roll - Out of Range") 175 | elif (check_value == 3): 176 | self.l4.setGeometry(QtCore.QRect(40,500,250,30)) 177 | self.l4.setText("Year should be between 1 to 4") 178 | elif (check_value == 4): 179 | self.l4.setGeometry(QtCore.QRect(40,500,250,30)) 180 | self.l4.setText("Click again please.") 181 | 182 | 183 | def check(self): 184 | name = self.e1.text() 185 | if (len(name) == 0): 186 | return 1 187 | 188 | for i in range(10): 189 | if (str(i) in name): 190 | return 1 191 | 192 | try: 193 | roll = int(self.e2.text()) 194 | if (roll < 1 or roll > 100): 195 | return 2 196 | except: 197 | return 2 198 | 199 | try: 200 | year = int(self.e3.text()) 201 | if (year < 1 or year > 4): 202 | return 3 203 | except: 204 | return 3 205 | 206 | try: 207 | img = cv2.imread(r'C:\\Users\\mesksr\\Documents\\GitHub\\automatic-attendance-system\\registration_images\\Year' + 208 | str(self.e3.text())+'\\'+str(self.e2.text())+'.png', 0) 209 | face_cascade=cv2.CascadeClassifier('support_files/haarcascade_frontalface_default.xml') 210 | faces = face_cascade.detectMultiScale(img, 1.3, 5) 211 | print (len(faces), 'face(s) detected') 212 | if (len(faces) != 1): 213 | return 4 214 | except: 215 | return 4 216 | 217 | return 0 218 | 219 | 220 | if __name__ == '__main__': 221 | app = QtGui.QApplication([]) 222 | gui = RegistrationWindow() 223 | gui.show() 224 | app.exec_() 225 | -------------------------------------------------------------------------------- /videos/IT301.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mesksr/automatic-attendance-system/b35b26c67b363f1630b7f38ba49a27ccd120d938/videos/IT301.mp4 --------------------------------------------------------------------------------