Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Smart Home Security - Face Recognition</title> | |
| <script src="https://cdn.jsdelivr.net/npm/face-api.js"></script> | |
| <style> | |
| :root { | |
| --primary: #2962ff; | |
| --dark: #1a237e; | |
| --light: #f5f5f5; | |
| --success: #00c853; | |
| --danger: #d50000; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| font-family: 'Segoe UI', sans-serif; | |
| } | |
| body { | |
| background: var(--light); | |
| min-height: 100vh; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| .header { | |
| background: var(--dark); | |
| color: white; | |
| padding: 1rem; | |
| border-radius: 10px; | |
| margin-bottom: 2rem; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .main-content { | |
| display: grid; | |
| grid-template-columns: 2fr 1fr; | |
| gap: 2rem; | |
| } | |
| .video-container { | |
| background: white; | |
| padding: 20px; | |
| border-radius: 10px; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.1); | |
| } | |
| #video { | |
| width: 100%; | |
| border-radius: 5px; | |
| } | |
| .controls { | |
| background: white; | |
| padding: 20px; | |
| border-radius: 10px; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.1); | |
| } | |
| .status { | |
| text-align: center; | |
| padding: 1rem; | |
| margin: 1rem 0; | |
| border-radius: 5px; | |
| font-weight: bold; | |
| } | |
| .status.authorized { | |
| background: var(--success); | |
| color: white; | |
| } | |
| .status.unauthorized { | |
| background: var(--danger); | |
| color: white; | |
| } | |
| .btn { | |
| background: var(--primary); | |
| color: white; | |
| border: none; | |
| padding: 10px 20px; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| transition: 0.3s; | |
| width: 100%; | |
| margin: 5px 0; | |
| } | |
| .btn:hover { | |
| background: var(--dark); | |
| } | |
| .registered-faces { | |
| margin-top: 2rem; | |
| } | |
| .face-item { | |
| display: flex; | |
| align-items: center; | |
| padding: 10px; | |
| background: #f8f9fa; | |
| margin: 5px 0; | |
| border-radius: 5px; | |
| } | |
| .face-item img { | |
| width: 50px; | |
| height: 50px; | |
| border-radius: 50%; | |
| margin-right: 10px; | |
| } | |
| .loading { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: rgba(0,0,0,0.8); | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| color: white; | |
| font-size: 1.2rem; | |
| } | |
| @keyframes spin { | |
| to { transform: rotate(360deg); } | |
| } | |
| .spinner { | |
| width: 40px; | |
| height: 40px; | |
| border: 4px solid #f3f3f3; | |
| border-top: 4px solid var(--primary); | |
| border-radius: 50%; | |
| animation: spin 1s linear infinite; | |
| margin-right: 10px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="header"> | |
| <h1>🏠 Smart Home Security</h1> | |
| <div>System Status: <span id="system-status">Active</span></div> | |
| </div> | |
| <div class="main-content"> | |
| <div class="video-container"> | |
| <video id="video" autoplay muted></video> | |
| <div class="status" id="access-status">Waiting for face detection...</div> | |
| </div> | |
| <div class="controls"> | |
| <h2>Control Panel</h2> | |
| <button class="btn" id="add-face">Add New Face</button> | |
| <button class="btn" id="test-detection">Test Detection</button> | |
| <div class="registered-faces"> | |
| <h3>Registered Users</h3> | |
| <div id="faces-list"> | |
| <!-- Registered faces will be listed here --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="loading" id="loading" style="display: none;"> | |
| <div class="spinner"></div> | |
| Loading face detection models... | |
| </div> | |
| <script> | |
| // Mock database of registered faces | |
| const registeredFaces = [ | |
| { id: 1, name: 'John Doe', image: 'data:image/jpeg;base64,/9j/4AAQSkZJRg==' }, | |
| { id: 2, name: 'Jane Smith', image: 'data:image/jpeg;base64,/9j/4AAQSkZJRg==' } | |
| ]; | |
| // Initialize face detection | |
| async function initFaceDetection() { | |
| try { | |
| document.getElementById('loading').style.display = 'flex'; | |
| // Load face-api models (in real implementation) | |
| // await faceapi.nets.tinyFaceDetector.loadFromUri('/models'); | |
| // await faceapi.nets.faceLandmark68Net.loadFromUri('/models'); | |
| // await faceapi.nets.faceRecognitionNet.loadFromUri('/models'); | |
| // Access webcam | |
| const video = document.getElementById('video'); | |
| const stream = await navigator.mediaDevices.getUserMedia({ video: true }); | |
| video.srcObject = stream; | |
| document.getElementById('loading').style.display = 'none'; | |
| } catch (error) { | |
| console.error('Error initializing face detection:', error); | |
| document.getElementById('loading').style.display = 'none'; | |
| } | |
| } | |
| // Simulate face detection | |
| function detectFace() { | |
| const accessStatus = document.getElementById('access-status'); | |
| const isAuthorized = Math.random() > 0.5; // Simulate detection | |
| if (isAuthorized) { | |
| accessStatus.textContent = 'Access Granted ✅'; | |
| accessStatus.className = 'status authorized'; | |
| } else { | |
| accessStatus.textContent = 'Access Denied ❌'; | |
| accessStatus.className = 'status unauthorized'; | |
| } | |
| } | |
| // Display registered faces | |
| function displayRegisteredFaces() { | |
| const facesList = document.getElementById('faces-list'); | |
| facesList.innerHTML = registeredFaces.map(face => ` | |
| <div class="face-item"> | |
| <img src="${face.image}" alt="${face.name}"> | |
| <div> | |
| <h4>${face.name}</h4> | |
| <small>ID: ${face.id}</small> | |
| </div> | |
| </div> | |
| `).join(''); | |
| } | |
| // Event listeners | |
| document.getElementById('add-face').addEventListener('click', () => { | |
| const name = prompt('Enter name for new face:'); | |
| if (name) { | |
| registeredFaces.push({ | |
| id: registeredFaces.length + 1, | |
| name, | |
| image: 'data:image/jpeg;base64,/9j/4AAQSkZJRg==' | |
| }); | |
| displayRegisteredFaces(); | |
| } | |
| }); | |
| document.getElementById('test-detection').addEventListener('click', detectFace); | |
| // Initialize application | |
| window.addEventListener('load', () => { | |
| initFaceDetection(); | |
| displayRegisteredFaces(); | |
| }); | |
| </script> | |
| </body> | |
| </html> |