Akshayram1 commited on
Commit
f531490
·
verified ·
1 Parent(s): 8e3ec7c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +136 -78
app.py CHANGED
@@ -4,7 +4,7 @@ import mediapipe as mp
4
  import streamlit as st
5
  from PIL import Image
6
  import numpy as np
7
- from deepface import DeepFace
8
  import pandas as pd
9
  from datetime import datetime
10
 
@@ -17,13 +17,26 @@ def initialize_database():
17
  if not os.path.exists("database"):
18
  os.makedirs("database")
19
  if not os.path.exists("database/records.csv"):
20
- df = pd.DataFrame(columns=['name', 'image_path', 'date_added'])
21
  df.to_csv("database/records.csv", index=False)
22
 
 
 
 
 
 
 
 
 
23
  # Function to add face to database
24
  def add_to_database(image, name):
25
  initialize_database()
26
 
 
 
 
 
 
27
  # Save image to database folder
28
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
29
  image_path = f"database/{name}_{timestamp}.jpg"
@@ -34,117 +47,147 @@ def add_to_database(image, name):
34
  new_record = pd.DataFrame({
35
  'name': [name],
36
  'image_path': [image_path],
 
37
  'date_added': [datetime.now().strftime("%Y-%m-%d %H:%M:%S")]
38
  })
39
  df = pd.concat([df, new_record], ignore_index=True)
40
  df.to_csv("database/records.csv", index=False)
41
- return image_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
  # Function to detect faces and perform recognition
44
  def detect_and_recognize_faces(image, output_folder="output"):
45
  if not os.path.exists(output_folder):
46
  os.makedirs(output_folder)
47
 
48
- # Convert image to RGB for MediaPipe
49
- image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 
 
 
 
 
 
 
 
50
 
51
- # Detect faces
52
- with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection:
53
- results = face_detection.process(image_rgb)
54
- face_images = []
55
- face_results = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
- if results.detections:
58
- df = pd.read_csv("database/records.csv")
 
 
 
 
 
 
 
59
 
60
- for idx, detection in enumerate(results.detections):
61
- bboxC = detection.location_data.relative_bounding_box
62
- h, w, _ = image.shape
63
-
64
- # Get coordinates
65
- x_min = int(bboxC.xmin * w)
66
- y_min = int(bboxC.ymin * h)
67
- box_width = int(bboxC.width * w)
68
- box_height = int(bboxC.height * h)
69
-
70
- # Extract face
71
- face_image = image[y_min:y_min + box_height, x_min:x_min + box_width]
72
- face_images.append(face_image)
73
-
74
- # Save detected face
75
- face_output_path = os.path.join(output_folder, f"face_{idx+1}.jpg")
76
- cv2.imwrite(face_output_path, face_image)
77
-
78
- # Perform face recognition if database is not empty
79
- if not df.empty:
80
- try:
81
- matches = []
82
- for _, row in df.iterrows():
83
- try:
84
- result = DeepFace.verify(
85
- img1_path=face_output_path,
86
- img2_path=row['image_path'],
87
- model_name='VGG-Face',
88
- distance_metric='cosine'
89
- )
90
- if result['verified']:
91
- matches.append((row['name'], result['distance']))
92
- except Exception as e:
93
- continue
94
-
95
- if matches:
96
- # Get the best match (lowest distance)
97
- best_match = min(matches, key=lambda x: x[1])
98
- face_results.append(f"Match found: {best_match[0]}")
99
- # Draw name on image
100
- cv2.putText(image, best_match[0], (x_min, y_min - 10),
101
- cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36,255,12), 2)
102
- else:
103
- face_results.append("No match found")
104
- except Exception as e:
105
- face_results.append(f"Recognition error: {str(e)}")
106
-
107
- # Draw detection box
108
- mp_drawing.draw_detection(image, detection)
109
 
110
- return image, face_images, face_results
 
 
 
 
 
 
 
 
 
 
111
 
112
  # Streamlit UI
113
  st.title("Face Recognition System")
114
 
115
  # Sidebar for database management
116
  st.sidebar.header("Database Management")
117
- upload_for_db = st.sidebar.file_uploader("Add face to database", type=["jpg", "jpeg", "png"])
118
  if upload_for_db:
119
  person_name = st.sidebar.text_input("Enter person's name")
120
  if st.sidebar.button("Add to Database") and person_name:
121
  file_bytes = np.asarray(bytearray(upload_for_db.read()), dtype=np.uint8)
122
  img = cv2.imdecode(file_bytes, 1)
123
- image_path = add_to_database(img, person_name)
124
- st.sidebar.success(f"Added {person_name} to database!")
 
 
 
125
 
126
- # Main interface for face detection and recognition
127
  st.header("Face Detection and Recognition")
128
- uploaded_file = st.file_uploader("Choose an image for recognition", type=["jpg", "jpeg", "png"])
129
 
130
  if uploaded_file is not None:
131
- # Convert uploaded file to image
132
  file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
133
  image = cv2.imdecode(file_bytes, 1)
134
 
135
- # Process image
136
- output_folder = "output"
137
- detected_image, face_images, face_results = detect_and_recognize_faces(image, output_folder)
138
 
139
  # Display results
140
- st.subheader("Results")
141
  st.image(cv2.cvtColor(detected_image, cv2.COLOR_BGR2RGB),
142
- caption="Detected and Recognized Faces",
143
  use_column_width=True)
144
 
145
- # Display extracted faces and recognition results
146
  if face_images:
147
- cols = st.columns(len(face_images))
 
148
  for idx, (face, result, col) in enumerate(zip(face_images, face_results, cols)):
149
  with col:
150
  st.image(cv2.cvtColor(face, cv2.COLOR_BGR2RGB),
@@ -152,12 +195,27 @@ if uploaded_file is not None:
152
  use_column_width=True)
153
  st.write(result)
154
  else:
155
- st.write("No faces detected.")
156
 
157
  # Display database contents
158
  if st.sidebar.checkbox("Show Database Contents"):
159
  try:
160
  df = pd.read_csv("database/records.csv")
161
- st.sidebar.dataframe(df)
 
162
  except:
163
- st.sidebar.write("Database is empty or not initialized.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  import streamlit as st
5
  from PIL import Image
6
  import numpy as np
7
+ import face_recognition
8
  import pandas as pd
9
  from datetime import datetime
10
 
 
17
  if not os.path.exists("database"):
18
  os.makedirs("database")
19
  if not os.path.exists("database/records.csv"):
20
+ df = pd.DataFrame(columns=['name', 'image_path', 'encoding', 'date_added'])
21
  df.to_csv("database/records.csv", index=False)
22
 
23
+ # Function to compute face encoding
24
+ def get_face_encoding(image):
25
+ rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
26
+ encodings = face_recognition.face_encodings(rgb_image)
27
+ if encodings:
28
+ return encodings[0]
29
+ return None
30
+
31
  # Function to add face to database
32
  def add_to_database(image, name):
33
  initialize_database()
34
 
35
+ # Get face encoding
36
+ encoding = get_face_encoding(image)
37
+ if encoding is None:
38
+ return None, "No face detected in the image"
39
+
40
  # Save image to database folder
41
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
42
  image_path = f"database/{name}_{timestamp}.jpg"
 
47
  new_record = pd.DataFrame({
48
  'name': [name],
49
  'image_path': [image_path],
50
+ 'encoding': [encoding.tolist()],
51
  'date_added': [datetime.now().strftime("%Y-%m-%d %H:%M:%S")]
52
  })
53
  df = pd.concat([df, new_record], ignore_index=True)
54
  df.to_csv("database/records.csv", index=False)
55
+ return image_path, "Successfully added to database"
56
+
57
+ def find_best_match(face_encoding, known_encodings, known_names, tolerance=0.6):
58
+ """
59
+ Find the best match for a face encoding among known encodings
60
+ Returns name and confidence score of the best match, or None if no match found
61
+ """
62
+ if not known_encodings or not known_names:
63
+ return None, 0
64
+
65
+ # Calculate face distances
66
+ face_distances = face_recognition.face_distance(known_encodings, face_encoding)
67
+
68
+ if len(face_distances) > 0:
69
+ best_match_index = np.argmin(face_distances)
70
+ best_match_distance = face_distances[best_match_index]
71
+
72
+ # Convert distance to confidence score (0-100%)
73
+ confidence = (1 - best_match_distance) * 100
74
+
75
+ # Only return match if distance is below tolerance
76
+ if best_match_distance <= tolerance:
77
+ return known_names[best_match_index], confidence
78
+
79
+ return None, 0
80
 
81
  # Function to detect faces and perform recognition
82
  def detect_and_recognize_faces(image, output_folder="output"):
83
  if not os.path.exists(output_folder):
84
  os.makedirs(output_folder)
85
 
86
+ # Convert image to RGB
87
+ rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
88
+
89
+ # Get face locations and encodings
90
+ face_locations = face_recognition.face_locations(rgb_image, model="cnn")
91
+ face_encodings = face_recognition.face_encodings(rgb_image, face_locations)
92
+
93
+ face_images = []
94
+ face_results = []
95
+ recognition_details = []
96
 
97
+ # Load database
98
+ try:
99
+ df = pd.read_csv("database/records.csv")
100
+ if not df.empty:
101
+ known_encodings = [np.array(eval(enc)) for enc in df['encoding']]
102
+ known_names = df['name'].tolist()
103
+ else:
104
+ known_encodings = []
105
+ known_names = []
106
+ except Exception as e:
107
+ st.error(f"Error loading database: {str(e)}")
108
+ known_encodings = []
109
+ known_names = []
110
+
111
+ # Process each detected face
112
+ for idx, (face_location, face_encoding) in enumerate(zip(face_locations, face_encodings)):
113
+ top, right, bottom, left = face_location
114
+
115
+ # Extract and save face image
116
+ face_image = image[top:bottom, left:right]
117
+ face_images.append(face_image)
118
+
119
+ face_output_path = os.path.join(output_folder, f"face_{idx+1}.jpg")
120
+ cv2.imwrite(face_output_path, face_image)
121
 
122
+ # Find best match
123
+ matched_name, confidence = find_best_match(face_encoding, known_encodings, known_names)
124
+
125
+ if matched_name and confidence > 0:
126
+ result = f"Match: {matched_name}\nConfidence: {confidence:.1f}%"
127
+ color = (36, 255, 12) # Green for match
128
+ else:
129
+ result = "No match in database"
130
+ color = (0, 0, 255) # Red for no match
131
 
132
+ face_results.append(result)
133
+ recognition_details.append({
134
+ 'location': (left, top, right, bottom),
135
+ 'color': color,
136
+ 'text': result.split('\n')[0]
137
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
+ # Draw results on image
140
+ for detail in recognition_details:
141
+ left, top, right, bottom = detail['location']
142
+ # Draw rectangle around face
143
+ cv2.rectangle(image, (left, top), (right, bottom), detail['color'], 2)
144
+ # Draw text above face
145
+ cv2.putText(image, detail['text'],
146
+ (left, max(0, top - 10)),
147
+ cv2.FONT_HERSHEY_SIMPLEX, 0.6, detail['color'], 2)
148
+
149
+ return image, face_images, face_results
150
 
151
  # Streamlit UI
152
  st.title("Face Recognition System")
153
 
154
  # Sidebar for database management
155
  st.sidebar.header("Database Management")
156
+ upload_for_db = st.sidebar.file_uploader("Add face to database", type=["jpg", "jpeg", "png"], key="db_uploader")
157
  if upload_for_db:
158
  person_name = st.sidebar.text_input("Enter person's name")
159
  if st.sidebar.button("Add to Database") and person_name:
160
  file_bytes = np.asarray(bytearray(upload_for_db.read()), dtype=np.uint8)
161
  img = cv2.imdecode(file_bytes, 1)
162
+ image_path, message = add_to_database(img, person_name)
163
+ if image_path:
164
+ st.sidebar.success(f"Added {person_name} to database!")
165
+ else:
166
+ st.sidebar.error(message)
167
 
168
+ # Main interface
169
  st.header("Face Detection and Recognition")
170
+ uploaded_file = st.file_uploader("Choose an image for recognition", type=["jpg", "jpeg", "png"], key="recognition_uploader")
171
 
172
  if uploaded_file is not None:
173
+ # Load and process image
174
  file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
175
  image = cv2.imdecode(file_bytes, 1)
176
 
177
+ with st.spinner("Processing image..."):
178
+ output_folder = "output"
179
+ detected_image, face_images, face_results = detect_and_recognize_faces(image, output_folder)
180
 
181
  # Display results
182
+ st.subheader("Recognition Results")
183
  st.image(cv2.cvtColor(detected_image, cv2.COLOR_BGR2RGB),
184
+ caption="Processed Image",
185
  use_column_width=True)
186
 
187
+ # Display extracted faces and results
188
  if face_images:
189
+ st.subheader("Detected Faces")
190
+ cols = st.columns(min(len(face_images), 4)) # Limit to 4 columns max
191
  for idx, (face, result, col) in enumerate(zip(face_images, face_results, cols)):
192
  with col:
193
  st.image(cv2.cvtColor(face, cv2.COLOR_BGR2RGB),
 
195
  use_column_width=True)
196
  st.write(result)
197
  else:
198
+ st.warning("No faces detected in the image.")
199
 
200
  # Display database contents
201
  if st.sidebar.checkbox("Show Database Contents"):
202
  try:
203
  df = pd.read_csv("database/records.csv")
204
+ display_df = df.drop('encoding', axis=1) # Don't show encodings
205
+ st.sidebar.dataframe(display_df)
206
  except:
207
+ st.sidebar.write("Database is empty or not initialized.")
208
+
209
+ # Add clear database button
210
+ if st.sidebar.button("Clear Database"):
211
+ try:
212
+ # Remove all files in database directory
213
+ for file in os.listdir("database"):
214
+ file_path = os.path.join("database", file)
215
+ if os.path.isfile(file_path):
216
+ os.remove(file_path)
217
+ # Reinitialize database
218
+ initialize_database()
219
+ st.sidebar.success("Database cleared successfully!")
220
+ except Exception as e:
221
+ st.sidebar.error(f"Error clearing database: {str(e)}")