From Pi
From Pi
import os
import numpy as np
import threading
import time
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from deepface import DeepFace
from queue import Queue, Empty
import datetime
import logging
# Configuration
DATABASE_FOLDER = "database"
MODEL_NAME = "ArcFace"
DETECTOR_BACKEND = "ssd" # Faster than retinaface
FRAME_SKIP = 4 # Process every Nth frame
MAX_QUEUE_SIZE = 2
SIMILARITY_THRESHOLD = 0.65
# Email Configuration
EMAIL_ENABLED = True
EMAIL_FROM = "[email protected]" # Your email address
EMAIL_PASSWORD = "uvfbgvkicjtzzpvp" # Use app password for Gmail
EMAIL_TO = "[email protected] , [email protected]" # Recipient email
EMAIL_SMTP_SERVER = "smtp.gmail.com"
EMAIL_SMTP_PORT = 587
EMAIL_COOLDOWN = 60 # Seconds between emails
# RFID Configuration
RFID_ENABLED = True
RFID_PORT = "COM3" # Change to your RFID reader's serial port
RFID_BAUDRATE = 9600
RFID_EMERGENCY_CODES = [
"1234567890", # Add your RFID tag IDs here
"0987654321"
]
# Set up logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='face_recognition.log'
)
logger = logging.getLogger(__name__)
# Global variables
face_database = []
processing_queue = Queue(maxsize=MAX_QUEUE_SIZE)
current_results = []
is_running = True
frame_count = 0
fps = 0
last_fps_update = time.time()
fps_counter = 0
last_email_time = 0
unknown_faces_detected = False
# Initialize database
def init_database():
if not os.path.exists(DATABASE_FOLDER):
os.makedirs(DATABASE_FOLDER)
result = DeepFace.represent(
img_path=img,
model_name=MODEL_NAME,
detector_backend=DETECTOR_BACKEND,
enforce_detection=True,
align=True
)
if result:
face_database.append({
"name": os.path.splitext(filename)[0],
"embedding": result[0]["embedding"]
})
loaded += 1
except Exception as e:
logger.error(f"Error loading {filename}: {str(e)}")
continue
while is_running:
try:
frame = processing_queue.get(timeout=0.5)
# Detect faces
faces = DeepFace.extract_faces(
img_path=frame,
detector_backend=DETECTOR_BACKEND,
enforce_detection=False,
align=True
)
results = []
unknown_detected = False
region = face["facial_area"]
x, y, w, h = region["x"], region["y"], region["w"], region["h"]
try:
# Get embedding
embedding = DeepFace.represent(
img_path=face_img,
model_name=MODEL_NAME,
detector_backend="skip",
enforce_detection=False,
align=False
)[0]["embedding"]
# Update results
current_results = results
unknown_faces_detected = unknown_detected
processing_queue.task_done()
except Empty:
pass
except Exception as e:
logger.error(f"Process frame error: {str(e)}")
print(f"Error: {str(e)}")
try:
processing_queue.task_done()
except:
pass
# Ensure bounds
x1 = max(0, x - margin_x)
y1 = max(0, y - margin_y)
x2 = min(frame.shape[1], x + w + margin_x)
y2 = min(frame.shape[0], y + h + margin_y)
# Save image
face_img = frame[y1:y2, x1:x2]
cv2.imwrite(path, face_img)
# Add to database
embedding = DeepFace.represent(
img_path=face_img,
model_name=MODEL_NAME,
detector_backend=DETECTOR_BACKEND,
enforce_detection=True
)[0]["embedding"]
face_database.append({
"name": name,
"embedding": embedding
})
except Exception as e:
logger.error(f"Enrollment failed: {str(e)}")
print(f"Enrollment failed: {str(e)}")
return False
if not EMAIL_ENABLED:
return
# Check cooldown
current_time = time.time()
if current_time - last_email_time < EMAIL_COOLDOWN:
return
last_email_time = current_time
def _send_email_worker():
try:
# Find first unknown face with image
unknown_face = None
for face in current_results:
if face[4] == "Unknown" and face[6] is not None:
unknown_face = face
break
if unknown_face is None:
logger.warning("No unknown face image found for email")
return
# Create a timestamp
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Prepare the email
msg = MIMEMultipart()
msg['From'] = EMAIL_FROM
msg['To'] = EMAIL_TO
msg['Subject'] = f"⚠️ SECURITY ALERT: Unknown Person Detected -
{timestamp}"
# Email body
body = f"""
<html>
<body>
<h2>Security Alert: Unknown Person Detected</h2>
<p><b>Time:</b> {timestamp}</p>
<p>An unknown person has been detected by the security system.</p>
<p>Please see the attached image for details.</p>
</body>
</html>
"""
msg.attach(MIMEText(body, 'html'))
# Attach image
img_attach = MIMEImage(img_bytes)
img_attach.add_header('Content-Disposition', 'attachment',
filename=f'unknown_person_{timestamp}.jpg')
msg.attach(img_attach)
# Send email
server = smtplib.SMTP(EMAIL_SMTP_SERVER, EMAIL_SMTP_PORT)
server.starttls()
server.login(EMAIL_FROM, EMAIL_PASSWORD)
server.send_message(msg)
server.quit()
except Exception as e:
logger.error(f"Email sending failed: {str(e)}")
print(f"Email sending failed: {str(e)}")
# Main function
def main():
global is_running, frame_count, fps, last_fps_update, fps_counter,
SIMILARITY_THRESHOLD
# Initialize
init_database()
# Initialize camera
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
try:
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
except:
pass
# Main loop
while True:
# Capture frame
ret, frame = cap.read()
if not ret:
break
# Update FPS
fps_counter += 1
now = time.time()
if now - last_fps_update >= 1.0:
fps = fps_counter
fps_counter = 0
last_fps_update = now
# Draw results
for x, y, w, h, label, conf, _ in current_results:
# Set color based on recognition
color = (0, 255, 0) if label != "Unknown" else (0, 0, 255)
# Draw rectangle
cv2.rectangle(frame, (x, y), (x+w, y+h), color, 2)
# Draw HUD
cv2.putText(frame, f"FPS: {fps}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7,
(0, 255, 0), 2)
cv2.putText(frame, f"Thresh: {SIMILARITY_THRESHOLD:.2f}", (10, 60),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
# Show frame
cv2.imshow('Face Recognition', frame)
# Cleanup
is_running = False
if process_thread.is_alive():
process_thread.join(timeout=1.0)
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()