vikramjeetthakur commited on
Commit
aac2604
·
verified ·
1 Parent(s): cfe826a

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +175 -0
app.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import cv2
3
+ import face_recognition
4
+ import os
5
+ from datetime import datetime
6
+ import sqlite3
7
+ import pandas as pd
8
+ import numpy as np
9
+ from PIL import Image
10
+
11
+ # --- App Configuration ---
12
+ st.set_page_config(
13
+ page_title="Face Recognition Attendance",
14
+ page_icon="✅",
15
+ layout="wide"
16
+ )
17
+
18
+ # --- Database Connection ---
19
+ conn = sqlite3.connect('attendance.db')
20
+ cursor = conn.cursor()
21
+
22
+ # --- Create Attendance Table (if not exists) ---
23
+ cursor.execute('''
24
+ CREATE TABLE IF NOT EXISTS attendance (
25
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
26
+ name TEXT,
27
+ roll_no TEXT,
28
+ date TEXT,
29
+ time TEXT,
30
+ status TEXT
31
+ )
32
+ ''')
33
+ conn.commit()
34
+
35
+ # --- Load Known Faces ---
36
+ def load_known_faces():
37
+ """Loads known faces from the 'Photos' directory."""
38
+ images = []
39
+ classnames = []
40
+ directory = "Photos"
41
+
42
+ for cls in os.listdir(directory):
43
+ if os.path.splitext(cls)[1] in [".jpg", ".jpeg"]:
44
+ img_path = os.path.join(directory, cls)
45
+ curImg = cv2.imread(img_path)
46
+ images.append(curImg)
47
+ classnames.append(os.path.splitext(cls)[0])
48
+
49
+ return images, classnames
50
+
51
+ # --- Encode Known Faces ---
52
+ def find_encodings(images):
53
+ """Encodes the given images."""
54
+ encodeList = []
55
+ for img in images:
56
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
57
+ encode = face_recognition.face_encodings(img)[0]
58
+ encodeList.append(encode)
59
+ return encodeList
60
+
61
+ # --- Load and Encode Known Faces ---
62
+ Images, classnames = load_known_faces()
63
+ encodeListKnown = find_encodings(Images)
64
+
65
+ # --- Add New Face ---
66
+ def add_new_face():
67
+ """Adds a new face to the system."""
68
+ new_name = st.text_input("Enter your name:")
69
+ roll_no = st.text_input("Enter your roll number:")
70
+
71
+ img_file_buffer = st.camera_input("Take a picture")
72
+ if img_file_buffer is not None and new_name and roll_no:
73
+ image = np.array(Image.open(img_file_buffer)) # Convert to numpy array
74
+ img_path = os.path.join("Photos", f"{new_name}_{roll_no}.jpg")
75
+ cv2.imwrite(img_path, image)
76
+
77
+ # Update known faces and encodings
78
+ global Images, classnames, encodeListKnown
79
+ Images, classnames = load_known_faces()
80
+ encodeListKnown = find_encodings(Images)
81
+
82
+ # Add to database (without updating attendance)
83
+ date = datetime.now().strftime('%Y-%m-%d')
84
+ time = datetime.now().strftime('%H:%M:%S')
85
+ cursor.execute("INSERT INTO attendance (name, roll_no, date, time, status) VALUES (?, ?, ?, ?, 'Registered')",
86
+ (new_name, roll_no, date, time))
87
+ conn.commit()
88
+
89
+ st.success(f"New face added for {new_name} ({roll_no}).")
90
+
91
+ # --- Face Recognition ---
92
+ def recognize_face():
93
+ """Performs face recognition and updates attendance."""
94
+ img_file_buffer = st.camera_input("Take a picture")
95
+ if img_file_buffer is not None:
96
+ with st.spinner("Recognizing face..."):
97
+ image = np.array(Image.open(img_file_buffer)) # Convert to numpy array
98
+ imgS = cv2.resize(image, (0, 0), None, 0.25, 0.25)
99
+ imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)
100
+ facesCurFrame = face_recognition.face_locations(imgS)
101
+ encodesCurFrame = face_recognition.face_encodings(imgS, facesCurFrame)
102
+
103
+ name = "Unknown"
104
+ roll_no = "Unknown"
105
+
106
+ if len(encodesCurFrame) > 0:
107
+ for encodeFace, faceLoc in zip(encodesCurFrame, facesCurFrame):
108
+ matches = face_recognition.compare_faces(encodeListKnown, encodeFace)
109
+ faceDis = face_recognition.face_distance(encodeListKnown, encodeFace)
110
+ matchIndex = np.argmin(faceDis)
111
+
112
+ if matches[matchIndex]:
113
+ name = classnames[matchIndex].split("_")[0]
114
+ roll_no = classnames[matchIndex].split("_")[1]
115
+
116
+ y1, x2, y2, x1 = faceLoc
117
+ y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4
118
+ cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
119
+ cv2.rectangle(image, (x1, y2 - 35), (x2, y2), (0, 255, 0), cv2.FILLED)
120
+ cv2.putText(image, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
121
+
122
+ # Check for duplicate attendance entries
123
+ date = datetime.now().strftime('%Y-%m-%d')
124
+ time = datetime.now().strftime('%H:%M:%S')
125
+ cursor.execute("SELECT * FROM attendance WHERE name=? AND date=? AND time=?", (name, date, time))
126
+ existing_attendance = cursor.fetchone()
127
+
128
+ if existing_attendance:
129
+ st.info(f"Attendance already recorded for {name} at {time}.")
130
+ else:
131
+ # Allow manual marking of attendance
132
+ status = st.radio("Mark Attendance:", ("Present", "Absent"))
133
+ cursor.execute("INSERT INTO attendance (name, roll_no, date, time, status) VALUES (?, ?, ?, ?, ?)",
134
+ (name, roll_no, date, time, status))
135
+ conn.commit()
136
+ st.success(f"Attendance updated for {name} at {time} ({status}).")
137
+
138
+ st.image(image, caption="Detected Face", use_container_width=True)
139
+ if name == "Unknown":
140
+ st.info("Face not recognized.")
141
+
142
+ # --- View Attendance Records ---
143
+ def view_attendance_records():
144
+ """Displays attendance records."""
145
+ st.subheader("Attendance Records")
146
+ cursor.execute("SELECT * FROM attendance ORDER BY date DESC, time DESC")
147
+ records = cursor.fetchall()
148
+
149
+ if records:
150
+ df = pd.DataFrame(records, columns=["ID", "Name", "Roll No", "Date", "Time", "Status"])
151
+ st.table(df)
152
+ else:
153
+ st.info("No attendance records available.")
154
+
155
+ # --- Main App Logic ---
156
+ if __name__ == "__main__":
157
+ st.title("Face Recognition Attendance")
158
+
159
+ # --- Password Protection (Optional) ---
160
+ password = st.text_input("Enter password", type="password")
161
+ if password != "123":
162
+ st.stop()
163
+
164
+ # --- App Sections ---
165
+ app_mode = st.sidebar.selectbox("Select Mode", ["Recognize", "Add New Face", "View Records"])
166
+
167
+ if app_mode == "Recognize":
168
+ recognize_face()
169
+ elif app_mode == "Add New Face":
170
+ add_new_face()
171
+ elif app_mode == "View Records":
172
+ view_attendance_records()
173
+
174
+ # --- Close Database Connection ---
175
+ conn.close()