PrashanthB461 commited on
Commit
3c44d40
Β·
verified Β·
1 Parent(s): f6fb492

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -13
app.py CHANGED
@@ -46,12 +46,25 @@ SF_CREDENTIALS = {
46
  @retry(stop_max_attempt_number=3, wait_fixed=2000)
47
  def connect_to_salesforce():
48
  try:
49
- sf = Salesforce(**SF_CREDENTIALS)
50
- logger.info("Connected to Salesforce")
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  sf.describe()
52
  return sf
53
  except Exception as e:
54
- logger.error(f"Salesforce connection failed: {e}")
55
  raise
56
 
57
  class AttendanceSystem:
@@ -69,12 +82,13 @@ class AttendanceSystem:
69
  self.recognition_cooldown = 5 # seconds
70
  self.video_file_path = None
71
  self.video_processing = False
 
72
 
73
  # Initialize Salesforce
74
  try:
75
  self.sf = connect_to_salesforce()
76
  except Exception as e:
77
- logger.error(f"Error connecting to Salesforce: {e}")
78
  self.sf = None
79
 
80
  # Create directories
@@ -178,10 +192,22 @@ class AttendanceSystem:
178
  image_array = np.array(image)
179
 
180
  try:
 
181
  face_analysis = DeepFace.analyze(img_path=image_array, actions=['emotion'], enforce_detection=True, detector_backend='opencv')
 
 
 
182
 
183
  embedding = DeepFace.represent(img_path=image_array, model_name='Facenet')[0]['embedding']
184
 
 
 
 
 
 
 
 
 
185
  name = name.strip().title()
186
  if name in self.known_face_names:
187
  return f"❌ {name} is already registered!", self.get_registered_workers_info()
@@ -215,6 +241,7 @@ class AttendanceSystem:
215
  logger.warning("Image URL not set due to upload failure")
216
  except Exception as e:
217
  logger.error(f"Error saving to Salesforce: {e}")
 
218
 
219
  self.save_data()
220
 
@@ -227,14 +254,28 @@ class AttendanceSystem:
227
  except Exception as e:
228
  return f"❌ Error during registration: {str(e)}", self.get_registered_workers_info()
229
 
230
- def register_worker_auto(self, face_image: np.ndarray) -> Tuple[Optional[str], Optional[str]]:
231
  """Automatic worker registration for unrecognized faces"""
232
  try:
233
- worker_id = f"W{self.next_worker_id:04d}"
234
- worker_name = f"Unknown_Worker_{self.next_worker_id}"
 
 
235
 
236
  embedding = DeepFace.represent(img_path=face_image, model_name='Facenet')[0]['embedding']
237
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  face_pil = Image.fromarray(cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB))
239
  caption = self.get_image_caption(face_pil)
240
 
@@ -326,6 +367,10 @@ class AttendanceSystem:
326
  face_area = face_obj['facial_area']
327
  x, y, w, h = face_area['x'], face_area['y'], face_area['w'], face_area['h']
328
 
 
 
 
 
329
  face_image = frame[y:y+h, x:x+w]
330
 
331
  try:
@@ -353,13 +398,14 @@ class AttendanceSystem:
353
  self.last_recognition_time[worker_id] = current_time
354
  else:
355
  if face_image.size > 0:
356
- new_id, new_name = self.register_worker_auto(face_image)
357
  if new_id:
358
  worker_id = new_id
359
  worker_name = new_name
360
  color = (255, 165, 0)
361
  logger.info(f"New worker registered: {new_name} ({new_id})")
362
- self.mark_attendance(worker_id, worker_name)
 
363
 
364
  cv2.rectangle(frame, (x, y), (x+w, y+h), color, 2)
365
  cv2.rectangle(frame, (x, y+h - 35), (x+w, y+h), color, cv2.FILLED)
@@ -481,7 +527,7 @@ class AttendanceSystem:
481
 
482
  def get_registered_workers_info(self) -> str:
483
  if not self.sf:
484
- return "❌ Salesforce connection not established."
485
 
486
  try:
487
  workers = self.sf.query_all("SELECT Name, Worker_ID__c, Image_Caption__c, Image_URL__c FROM Worker__c")['records']
@@ -509,7 +555,7 @@ class AttendanceSystem:
509
 
510
  def get_today_attendance(self) -> str:
511
  if not self.sf:
512
- return "❌ Salesforce connection not established."
513
 
514
  today = date.today().isoformat()
515
  try:
@@ -553,7 +599,7 @@ class AttendanceSystem:
553
  return "Invalid date format. Please use YYYY-MM-DD."
554
 
555
  if not self.sf:
556
- return "❌ Salesforce connection not established."
557
 
558
  try:
559
  records = self.sf.query_all(
@@ -659,7 +705,7 @@ def create_interface():
659
  ## πŸš€ **Key Features:**
660
  - **πŸŽ₯ Live Camera Recognition** - Real-time face detection from camera/CCTV
661
  - **πŸ“Ή Video File Processing** - Process pre-recorded videos for attendance
662
- - **πŸ€– Automatic Worker Registration** - Auto-register unknown faces with unique IDs
663
  - **πŸ‘€ Manual Registration** - Register workers manually with photos and AI-generated captions
664
  - **πŸ“… 24-Hour Attendance Rule** - One attendance mark per worker per day
665
  - **πŸ“Š Advanced Analytics** - Detailed reports and data export
 
46
  @retry(stop_max_attempt_number=3, wait_fixed=2000)
47
  def connect_to_salesforce():
48
  try:
49
+ if SF_CREDENTIALS["instance"]:
50
+ sf = Salesforce(
51
+ username=SF_CREDENTIALS["username"],
52
+ password=SF_CREDENTIALS["password"],
53
+ security_token=SF_CREDENTIALS["security_token"],
54
+ instance=SF_CREDENTIALS["instance"]
55
+ )
56
+ else:
57
+ sf = Salesforce(
58
+ username=SF_CREDENTIALS["username"],
59
+ password=SF_CREDENTIALS["password"],
60
+ security_token=SF_CREDENTIALS["security_token"],
61
+ domain=SF_CREDENTIALS["domain"]
62
+ )
63
+ logger.info("Connected to Salesforce successfully")
64
  sf.describe()
65
  return sf
66
  except Exception as e:
67
+ logger.error(f"Salesforce connection failed: {e}. Check SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN, and SF_DOMAIN in .env file.")
68
  raise
69
 
70
  class AttendanceSystem:
 
82
  self.recognition_cooldown = 5 # seconds
83
  self.video_file_path = None
84
  self.video_processing = False
85
+ self.min_face_size = (100, 100) # Minimum face size for registration/recognition
86
 
87
  # Initialize Salesforce
88
  try:
89
  self.sf = connect_to_salesforce()
90
  except Exception as e:
91
+ logger.error(f"Failed to initialize Salesforce connection: {e}")
92
  self.sf = None
93
 
94
  # Create directories
 
192
  image_array = np.array(image)
193
 
194
  try:
195
+ # Verify face and size
196
  face_analysis = DeepFace.analyze(img_path=image_array, actions=['emotion'], enforce_detection=True, detector_backend='opencv')
197
+ faces = DeepFace.extract_faces(img_path=image_array, target_size=(160, 160), enforce_detection=False, detector_backend='opencv')
198
+ if not faces or faces[0]['facial_area']['w'] < self.min_face_size[0] or faces[0]['facial_area']['h'] < self.min_face_size[1]:
199
+ return "❌ Face too small or not clear enough (must be at least 100x100 pixels)!", self.get_registered_workers_info()
200
 
201
  embedding = DeepFace.represent(img_path=image_array, model_name='Facenet')[0]['embedding']
202
 
203
+ # Check for duplicate face
204
+ if len(self.known_face_embeddings) > 0:
205
+ distances = [np.linalg.norm(np.array(embedding) - np.array(known_embedding))
206
+ for known_embedding in self.known_face_embeddings]
207
+ if min(distances) < 10:
208
+ best_match_index = distances.index(min(distances))
209
+ return f"❌ Face already registered as {self.known_face_names[best_match_index]} (ID: {self.known_face_ids[best_match_index]})!", self.get_registered_workers_info()
210
+
211
  name = name.strip().title()
212
  if name in self.known_face_names:
213
  return f"❌ {name} is already registered!", self.get_registered_workers_info()
 
241
  logger.warning("Image URL not set due to upload failure")
242
  except Exception as e:
243
  logger.error(f"Error saving to Salesforce: {e}")
244
+ return f"❌ Error saving to Salesforce: {e}. Check connection and permissions.", self.get_registered_workers_info()
245
 
246
  self.save_data()
247
 
 
254
  except Exception as e:
255
  return f"❌ Error during registration: {str(e)}", self.get_registered_workers_info()
256
 
257
+ def register_worker_auto(self, face_image: np.ndarray, face_area: dict) -> Tuple[Optional[str], Optional[str]]:
258
  """Automatic worker registration for unrecognized faces"""
259
  try:
260
+ # Verify face size
261
+ if face_area['w'] < self.min_face_size[0] or face_area['h'] < self.min_face_size[1]:
262
+ logger.info("Face too small for registration (must be at least 100x100 pixels)")
263
+ return None, None
264
 
265
  embedding = DeepFace.represent(img_path=face_image, model_name='Facenet')[0]['embedding']
266
 
267
+ # Check for duplicate face
268
+ if len(self.known_face_embeddings) > 0:
269
+ distances = [np.linalg.norm(np.array(embedding) - np.array(known_embedding))
270
+ for known_embedding in self.known_face_embeddings]
271
+ if min(distances) < 10:
272
+ best_match_index = distances.index(min(distances))
273
+ logger.info(f"Face already registered as {self.known_face_names[best_match_index]} (ID: {self.known_face_ids[best_match_index]})")
274
+ return self.known_face_ids[best_match_index], self.known_face_names[best_match_index]
275
+
276
+ worker_id = f"W{self.next_worker_id:04d}"
277
+ worker_name = f"Unknown_Worker_{self.next_worker_id}"
278
+
279
  face_pil = Image.fromarray(cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB))
280
  caption = self.get_image_caption(face_pil)
281
 
 
367
  face_area = face_obj['facial_area']
368
  x, y, w, h = face_area['x'], face_area['y'], face_area['w'], face_area['h']
369
 
370
+ # Check face size
371
+ if w < self.min_face_size[0] or h < self.min_face_size[1]:
372
+ continue
373
+
374
  face_image = frame[y:y+h, x:x+w]
375
 
376
  try:
 
398
  self.last_recognition_time[worker_id] = current_time
399
  else:
400
  if face_image.size > 0:
401
+ new_id, new_name = self.register_worker_auto(face_image, face_area)
402
  if new_id:
403
  worker_id = new_id
404
  worker_name = new_name
405
  color = (255, 165, 0)
406
  logger.info(f"New worker registered: {new_name} ({new_id})")
407
+ if self.mark_attendance(worker_id, worker_name):
408
+ logger.info(f"Attendance marked for new worker {worker_name} ({worker_id})")
409
 
410
  cv2.rectangle(frame, (x, y), (x+w, y+h), color, 2)
411
  cv2.rectangle(frame, (x, y+h - 35), (x+w, y+h), color, cv2.FILLED)
 
527
 
528
  def get_registered_workers_info(self) -> str:
529
  if not self.sf:
530
+ return "❌ Salesforce connection not established. Check credentials in .env file and ensure user has access to Worker__c and ContentVersion objects."
531
 
532
  try:
533
  workers = self.sf.query_all("SELECT Name, Worker_ID__c, Image_Caption__c, Image_URL__c FROM Worker__c")['records']
 
555
 
556
  def get_today_attendance(self) -> str:
557
  if not self.sf:
558
+ return "❌ Salesforce connection not established. Check credentials in .env file and ensure user has access to Attendance__c object."
559
 
560
  today = date.today().isoformat()
561
  try:
 
599
  return "Invalid date format. Please use YYYY-MM-DD."
600
 
601
  if not self.sf:
602
+ return "❌ Salesforce connection not established. Check credentials in .env file and ensure user has access to Attendance__c object."
603
 
604
  try:
605
  records = self.sf.query_all(
 
705
  ## πŸš€ **Key Features:**
706
  - **πŸŽ₯ Live Camera Recognition** - Real-time face detection from camera/CCTV
707
  - **πŸ“Ή Video File Processing** - Process pre-recorded videos for attendance
708
+ - **πŸ€– Automatic Worker Registration** - Auto-register unknown faces with unique IDs in Salesforce
709
  - **πŸ‘€ Manual Registration** - Register workers manually with photos and AI-generated captions
710
  - **πŸ“… 24-Hour Attendance Rule** - One attendance mark per worker per day
711
  - **πŸ“Š Advanced Analytics** - Detailed reports and data export