Spaces:
Build error
Build error
File size: 6,807 Bytes
7735e32 8cc4a3a 7735e32 6907498 7735e32 8cc4a3a 7735e32 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
import streamlit as st
from PIL import Image
import numpy as np
import cv2
import face_recognition
import os
from typing import List, Tuple
import requests
from urllib.parse import quote
import logging
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class FaceRecognitionApp:
def __init__(self, image_directory: str = "facerecognition"):
"""Initialize the face recognition application."""
self.image_directory = image_directory
self.images: List[np.ndarray] = []
self.classnames: List[str] = []
self.encode_list_known = None
# Initialize Streamlit page
st.set_page_config(page_title="Face Recognition System", page_icon="👤")
st.title("Face Recognition System")
# Load and encode known faces
self._load_known_faces()
def _load_known_faces(self) -> None:
"""Load and encode all known faces from the directory and predefined images."""
try:
# Load predefined images
predefined_images = {
"sarwan.jpg": "Sarwan",
"rattantata.png": "RattanTata",
"Ravinder.jpg": "RavinderKaur"
}
for img_path, name in predefined_images.items():
if os.path.exists(img_path):
img = cv2.imread(img_path)
if img is not None:
self.images.append(img)
self.classnames.append(name)
else:
logger.warning(f"Failed to load image: {img_path}")
# Load images from directory
if os.path.exists(self.image_directory):
for filename in os.listdir(self.image_directory):
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
img_path = os.path.join(self.image_directory, filename)
img = cv2.imread(img_path)
if img is not None:
self.images.append(img)
self.classnames.append(os.path.splitext(filename)[0])
else:
logger.warning(f"Failed to load image: {img_path}")
# Encode faces
if self.images:
self.encode_list_known = []
for img in self.images:
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
encodings = face_recognition.face_encodings(rgb_img)
if encodings:
self.encode_list_known.append(encodings[0])
else:
logger.warning("No face detected in one of the reference images")
logger.info(f"Loaded {len(self.images)} images for face recognition")
except Exception as e:
logger.error(f"Error loading known faces: {str(e)}")
st.error("Error loading reference images. Please check the image files.")
def _process_face(self, image: np.ndarray, scale: float = 0.25) -> Tuple[np.ndarray, bool]:
"""Process image and detect faces."""
img_small = cv2.resize(image, (0, 0), None, scale, scale)
img_rgb = cv2.cvtColor(img_small, cv2.COLOR_BGR2RGB)
face_locations = face_recognition.face_locations(img_rgb)
face_encodings = face_recognition.face_encodings(img_rgb, face_locations)
face_matched = False
for encoding, (top, right, bottom, left) in zip(face_encodings, face_locations):
if self.encode_list_known:
matches = face_recognition.compare_faces(self.encode_list_known, encoding)
face_distances = face_recognition.face_distance(self.encode_list_known, encoding)
if any(matches):
best_match_idx = np.argmin(face_distances)
if matches[best_match_idx]:
name = self.classnames[best_match_idx].upper()
face_matched = True
# Scale back the coordinates
top, right, bottom, left = [coord * int(1/scale) for coord in (top, right, bottom, left)]
# Draw rectangle and name
cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 2)
cv2.rectangle(image, (left, bottom - 35), (right, bottom), (0, 255, 0), cv2.FILLED)
cv2.putText(image, name, (left + 6, bottom - 6),
cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
# Update external service
self._update_external_service(name)
return image, face_matched
def _update_external_service(self, name: str) -> None:
"""Update external service with recognition results."""
try:
base_url = "https://fc11.glitch.me/submit"
params = {
"email": "pm",
"message": "faceReco",
"name": quote(name)
}
response = requests.get(base_url, params=params, timeout=5)
response.raise_for_status()
st.success(f"Successfully updated recognition for {name}")
logger.info(f"External service updated for {name}")
except requests.exceptions.RequestException as e:
logger.error(f"Failed to update external service: {str(e)}")
st.warning("Failed to update external service, but recognition completed successfully")
def run(self) -> None:
"""Run the face recognition application."""
if not self.encode_list_known:
st.error("No reference faces loaded. Please check the image directory.")
return
img_file_buffer = st.camera_input("Take Your Picture")
if img_file_buffer is not None:
try:
image = np.array(Image.open(img_file_buffer))
processed_image, face_matched = self._process_face(image.copy())
st.image(processed_image, use_column_width=True, channels="BGR")
if not face_matched:
st.warning("No matching faces found in the image.")
except Exception as e:
logger.error(f"Error processing image: {str(e)}")
st.error("Error processing the image. Please try again.")
if __name__ == "__main__":
app = FaceRecognitionApp()
app.run() |