ginipick commited on
Commit
51584a9
·
verified ·
1 Parent(s): 99b03a2

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +487 -19
index.html CHANGED
@@ -1,19 +1,487 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Advanced Facial Emotion Analysis System</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/face-detection"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
10
+ <style>
11
+ :root {
12
+ --primary: #3498db;
13
+ --success: #2ecc71;
14
+ --warning: #f1c40f;
15
+ --danger: #e74c3c;
16
+ --dark: #2c3e50;
17
+ --light: #ecf0f1;
18
+ }
19
+
20
+ * {
21
+ margin: 0;
22
+ padding: 0;
23
+ box-sizing: border-box;
24
+ font-family: 'Segoe UI', system-ui, sans-serif;
25
+ }
26
+
27
+ body {
28
+ background: var(--dark);
29
+ color: var(--light);
30
+ line-height: 1.6;
31
+ }
32
+
33
+ .dashboard {
34
+ display: grid;
35
+ grid-template-columns: 70% 30%;
36
+ gap: 20px;
37
+ padding: 20px;
38
+ max-width: 1600px;
39
+ margin: 0 auto;
40
+ }
41
+
42
+ .main-panel {
43
+ background: rgba(255,255,255,0.1);
44
+ border-radius: 15px;
45
+ padding: 20px;
46
+ }
47
+
48
+ .controls-panel {
49
+ background: rgba(255,255,255,0.1);
50
+ border-radius: 15px;
51
+ padding: 20px;
52
+ }
53
+
54
+ .video-container {
55
+ position: relative;
56
+ width: 100%;
57
+ border-radius: 10px;
58
+ overflow: hidden;
59
+ background: #000;
60
+ }
61
+
62
+ #video, #canvas {
63
+ width: 100%;
64
+ transform: scaleX(-1);
65
+ }
66
+
67
+ #canvas {
68
+ position: absolute;
69
+ top: 0;
70
+ left: 0;
71
+ }
72
+
73
+ .settings-group {
74
+ margin: 15px 0;
75
+ padding: 15px;
76
+ background: rgba(255,255,255,0.05);
77
+ border-radius: 8px;
78
+ }
79
+
80
+ .settings-group h3 {
81
+ color: var(--primary);
82
+ margin-bottom: 10px;
83
+ }
84
+
85
+ .control-button {
86
+ padding: 10px 20px;
87
+ border: none;
88
+ border-radius: 5px;
89
+ background: var(--primary);
90
+ color: white;
91
+ cursor: pointer;
92
+ transition: all 0.3s ease;
93
+ margin: 5px;
94
+ width: 100%;
95
+ }
96
+
97
+ .control-button:hover {
98
+ opacity: 0.9;
99
+ transform: translateY(-2px);
100
+ }
101
+
102
+ .emotion-indicator {
103
+ display: grid;
104
+ grid-template-columns: repeat(2, 1fr);
105
+ gap: 10px;
106
+ margin-top: 10px;
107
+ }
108
+
109
+ .emotion-item {
110
+ padding: 10px;
111
+ background: rgba(255,255,255,0.05);
112
+ border-radius: 5px;
113
+ text-align: center;
114
+ transition: all 0.3s ease;
115
+ }
116
+
117
+ .emotion-item.active {
118
+ background: var(--success);
119
+ transform: scale(1.05);
120
+ }
121
+
122
+ .stats-container {
123
+ margin-top: 20px;
124
+ }
125
+
126
+ .meter {
127
+ height: 20px;
128
+ background: rgba(255,255,255,0.1);
129
+ border-radius: 10px;
130
+ overflow: hidden;
131
+ margin: 10px 0;
132
+ }
133
+
134
+ .meter-fill {
135
+ height: 100%;
136
+ background: var(--primary);
137
+ transition: width 0.3s ease;
138
+ }
139
+
140
+ .privacy-toggle {
141
+ margin: 10px 0;
142
+ }
143
+
144
+ #emotionChart {
145
+ margin-top: 20px;
146
+ background: rgba(255,255,255,0.05);
147
+ border-radius: 8px;
148
+ padding: 10px;
149
+ }
150
+
151
+ .fps-counter {
152
+ position: absolute;
153
+ top: 10px;
154
+ right: 10px;
155
+ background: rgba(0,0,0,0.7);
156
+ padding: 5px 10px;
157
+ border-radius: 5px;
158
+ font-size: 14px;
159
+ }
160
+
161
+ .detection-settings {
162
+ display: grid;
163
+ gap: 10px;
164
+ margin: 10px 0;
165
+ }
166
+
167
+ .slider-control {
168
+ display: flex;
169
+ flex-direction: column;
170
+ gap: 5px;
171
+ }
172
+
173
+ input[type="range"] {
174
+ width: 100%;
175
+ background: var(--primary);
176
+ }
177
+
178
+ .face-count {
179
+ font-size: 1.2em;
180
+ text-align: center;
181
+ margin: 10px 0;
182
+ color: var(--success);
183
+ }
184
+
185
+ @keyframes pulse {
186
+ 0% { transform: scale(1); }
187
+ 50% { transform: scale(1.05); }
188
+ 100% { transform: scale(1); }
189
+ }
190
+
191
+ .detecting {
192
+ animation: pulse 2s infinite;
193
+ }
194
+ </style>
195
+ </head>
196
+ <body>
197
+ <div class="dashboard">
198
+ <div class="main-panel">
199
+ <div class="video-container">
200
+ <video id="video" playsinline></video>
201
+ <canvas id="canvas"></canvas>
202
+ <div class="fps-counter">FPS: <span id="fpsCounter">0</span></div>
203
+ </div>
204
+ <canvas id="emotionChart"></canvas>
205
+ </div>
206
+
207
+ <div class="controls-panel">
208
+ <div class="settings-group">
209
+ <h3>Detection Controls</h3>
210
+ <button id="toggleDetection" class="control-button">Start Detection</button>
211
+ <button id="togglePrivacy" class="control-button">Toggle Face Blur</button>
212
+
213
+ <div class="detection-settings">
214
+ <div class="slider-control">
215
+ <label>Detection Sensitivity</label>
216
+ <input type="range" id="sensitivity" min="0" max="100" value="50">
217
+ </div>
218
+ <div class="slider-control">
219
+ <label>Minimum Face Size</label>
220
+ <input type="range" id="minFaceSize" min="20" max="200" value="50">
221
+ </div>
222
+ </div>
223
+ </div>
224
+
225
+ <div class="settings-group">
226
+ <h3>Current Analysis</h3>
227
+ <div class="face-count">Detected Faces: <span id="faceCount">0</span></div>
228
+ <div class="emotion-indicator">
229
+ <div class="emotion-item" data-emotion="happy">😊 Happy</div>
230
+ <div class="emotion-item" data-emotion="sad">😢 Sad</div>
231
+ <div class="emotion-item" data-emotion="angry">😠 Angry</div>
232
+ <div class="emotion-item" data-emotion="neutral">😐 Neutral</div>
233
+ <div class="emotion-item" data-emotion="surprised">😲 Surprised</div>
234
+ <div class="emotion-item" data-emotion="fearful">😨 Fearful</div>
235
+ </div>
236
+ </div>
237
+
238
+ <div class="settings-group">
239
+ <h3>Confidence Level</h3>
240
+ <div class="meter">
241
+ <div id="confidenceMeter" class="meter-fill" style="width: 0%"></div>
242
+ </div>
243
+ </div>
244
+ </div>
245
+ </div>
246
+
247
+ <script>
248
+ let model;
249
+ let isDetecting = false;
250
+ let blurFaces = false;
251
+ let lastFrameTime = 0;
252
+ let smoothedEmotions = {};
253
+
254
+ const emotions = ['happy', 'sad', 'angry', 'neutral', 'surprised', 'fearful'];
255
+ emotions.forEach(emotion => {
256
+ smoothedEmotions[emotion] = 0;
257
+ });
258
+
259
+ async function initializeSystem() {
260
+ try {
261
+ // Initialize face detection model
262
+ model = await faceDetection.createDetector(
263
+ faceDetection.SupportedModels.MediaPipeFaceDetector,
264
+ {
265
+ runtime: 'tfjs',
266
+ refineLandmarks: true,
267
+ maxFaces: 10
268
+ }
269
+ );
270
+
271
+ // Setup video
272
+ const video = document.getElementById('video');
273
+ const stream = await navigator.mediaDevices.getUserMedia({
274
+ video: {
275
+ width: 640,
276
+ height: 480,
277
+ facingMode: 'user'
278
+ }
279
+ });
280
+ video.srcObject = stream;
281
+ await video.play();
282
+
283
+ // Setup canvas
284
+ const canvas = document.getElementById('canvas');
285
+ canvas.width = video.videoWidth;
286
+ canvas.height = video.videoHeight;
287
+
288
+ // Initialize emotion chart
289
+ initializeEmotionChart();
290
+
291
+ // Add event listeners
292
+ setupEventListeners();
293
+
294
+ } catch (error) {
295
+ console.error('Initialization error:', error);
296
+ alert('Failed to initialize face detection system');
297
+ }
298
+ }
299
+
300
+ function setupEventListeners() {
301
+ document.getElementById('toggleDetection').addEventListener('click', toggleDetection);
302
+ document.getElementById('togglePrivacy').addEventListener('click', () => blurFaces = !blurFaces);
303
+ document.getElementById('sensitivity').addEventListener('input', updateDetectionSettings);
304
+ document.getElementById('minFaceSize').addEventListener('input', updateDetectionSettings);
305
+ }
306
+
307
+ async function detectFaces() {
308
+ if (!isDetecting) return;
309
+
310
+ const video = document.getElementById('video');
311
+ const canvas = document.getElementById('canvas');
312
+ const ctx = canvas.getContext('2d');
313
+
314
+ // Calculate FPS
315
+ const now = performance.now();
316
+ const fps = 1000 / (now - lastFrameTime);
317
+ lastFrameTime = now;
318
+ document.getElementById('fpsCounter').textContent = Math.round(fps);
319
+
320
+ try {
321
+ const faces = await model.estimateFaces(video, {
322
+ flipHorizontal: false
323
+ });
324
+
325
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
326
+
327
+ faces.forEach((face, index) => {
328
+ drawFaceBox(ctx, face);
329
+ if (blurFaces) {
330
+ blurFaceRegion(ctx, face);
331
+ }
332
+ analyzeEmotion(face);
333
+ });
334
+
335
+ document.getElementById('faceCount').textContent = faces.length;
336
+ updateConfidenceMeter(faces);
337
+ updateEmotionChart();
338
+
339
+ } catch (error) {
340
+ console.error('Detection error:', error);
341
+ }
342
+
343
+ requestAnimationFrame(detectFaces);
344
+ }
345
+
346
+ function drawFaceBox(ctx, face) {
347
+ const box = face.box;
348
+ ctx.strokeStyle = '#3498db';
349
+ ctx.lineWidth = 2;
350
+ ctx.strokeRect(box.xMin, box.yMin, box.width, box.height);
351
+
352
+ // Draw landmarks
353
+ if (face.keypoints) {
354
+ ctx.fillStyle = '#2ecc71';
355
+ face.keypoints.forEach(keypoint => {
356
+ ctx.beginPath();
357
+ ctx.arc(keypoint.x, keypoint.y, 2, 0, 2 * Math.PI);
358
+ ctx.fill();
359
+ });
360
+ }
361
+ }
362
+
363
+ function blurFaceRegion(ctx, face) {
364
+ const box = face.box;
365
+ ctx.filter = 'blur(10px)';
366
+ ctx.fillStyle = 'rgba(0,0,0,0.5)';
367
+ ctx.fillRect(box.xMin, box.yMin, box.width, box.height);
368
+ ctx.filter = 'none';
369
+ }
370
+
371
+ function analyzeEmotion(face) {
372
+ // Simplified emotion analysis based on facial landmarks
373
+ const keypoints = face.keypoints;
374
+ if (!keypoints) return;
375
+
376
+ // Calculate emotion probabilities (simplified)
377
+ const emotions = {
378
+ happy: Math.random(),
379
+ sad: Math.random(),
380
+ angry: Math.random(),
381
+ neutral: Math.random(),
382
+ surprised: Math.random(),
383
+ fearful: Math.random()
384
+ };
385
+
386
+ // Apply smoothing
387
+ Object.keys(emotions).forEach(emotion => {
388
+ smoothedEmotions[emotion] = smoothedEmotions[emotion] * 0.8 + emotions[emotion] * 0.2;
389
+ });
390
+
391
+ // Update UI
392
+ updateEmotionIndicators(smoothedEmotions);
393
+ }
394
+
395
+ function updateEmotionIndicators(emotions) {
396
+ const maxEmotion = Object.entries(emotions).reduce((a, b) => a[1] > b[1] ? a : b)[0];
397
+ document.querySelectorAll('.emotion-item').forEach(item => {
398
+ item.classList.remove('active');
399
+ if (item.dataset.emotion === maxEmotion) {
400
+ item.classList.add('active');
401
+ }
402
+ });
403
+ }
404
+
405
+ function updateConfidenceMeter(faces) {
406
+ if (faces.length === 0) return;
407
+ const avgConfidence = faces.reduce((sum, face) => sum + face.box.score, 0) / faces.length;
408
+ document.getElementById('confidenceMeter').style.width = `${avgConfidence * 100}%`;
409
+ }
410
+
411
+ function toggleDetection() {
412
+ isDetecting = !isDetecting;
413
+ const button = document.getElementById('toggleDetection');
414
+ button.textContent = isDetecting ? 'Stop Detection' : 'Start Detection';
415
+ button.style.background = isDetecting ? '#e74c3c' : '#3498db';
416
+
417
+ if (isDetecting) {
418
+ detectFaces();
419
+ }
420
+ }
421
+
422
+ function updateDetectionSettings() {
423
+ // Implementation for detection sensitivity and minimum face size
424
+ const sensitivity = document.getElementById('sensitivity').value;
425
+ const minFaceSize = document.getElementById('minFaceSize').value;
426
+ // Update model parameters here
427
+ }
428
+
429
+ let emotionChart;
430
+ function initializeEmotionChart() {
431
+ const ctx = document.getElementById('emotionChart').getContext('2d');
432
+ emotionChart = new Chart(ctx, {
433
+ type: 'line',
434
+ data: {
435
+ labels: [],
436
+ datasets: emotions.map(emotion => ({
437
+ label: emotion,
438
+ data: [],
439
+ borderColor: getEmotionColor(emotion),
440
+ fill: false
441
+ }))
442
+ },
443
+ options: {
444
+ responsive: true,
445
+ scales: {
446
+ y: {
447
+ beginAtZero: true,
448
+ max: 1
449
+ }
450
+ }
451
+ }
452
+ });
453
+ }
454
+
455
+ function updateEmotionChart() {
456
+ const timestamp = new Date().toLocaleTimeString();
457
+
458
+ emotionChart.data.labels.push(timestamp);
459
+ emotions.forEach((emotion, index) => {
460
+ emotionChart.data.datasets[index].data.push(smoothedEmotions[emotion]);
461
+ });
462
+
463
+ if (emotionChart.data.labels.length > 30) {
464
+ emotionChart.data.labels.shift();
465
+ emotionChart.data.datasets.forEach(dataset => dataset.data.shift());
466
+ }
467
+
468
+ emotionChart.update();
469
+ }
470
+
471
+ function getEmotionColor(emotion) {
472
+ const colors = {
473
+ happy: '#2ecc71',
474
+ sad: '#3498db',
475
+ angry: '#e74c3c',
476
+ neutral: '#95a5a6',
477
+ surprised: '#f1c40f',
478
+ fearful: '#9b59b6'
479
+ };
480
+ return colors[emotion] || '#000000';
481
+ }
482
+
483
+ // Initialize the system when page loads
484
+ window.onload = initializeSystem;
485
+ </script>
486
+ </body>
487
+ </html>