cmbai13 commited on
Commit
8aa8fe9
·
verified ·
1 Parent(s): 2ab9773

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +6 -4
  2. index.html +361 -19
  3. prompts.txt +0 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Scale Ai
3
- emoji: 😻
4
- colorFrom: blue
5
  colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: scale-ai
3
+ emoji: 🐳
4
+ colorFrom: purple
5
  colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,361 @@
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>Scale AI - Human Detection</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.18.0/dist/tf.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/hand-pose-detection@1.0.0/dist/hand-pose-detection.min.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd@2.2.2/dist/coco-ssd.min.js"></script>
11
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
12
+ <style>
13
+ .toggle-checkbox:checked {
14
+ right: 0;
15
+ background-color: #10B981;
16
+ }
17
+ .toggle-checkbox:checked + .toggle-label {
18
+ background-color: #A7F3D0;
19
+ }
20
+ .detection-box {
21
+ position: absolute;
22
+ border: 3px solid;
23
+ border-radius: 4px;
24
+ z-index: 10;
25
+ }
26
+ .person-box {
27
+ border-color: #EF4444;
28
+ }
29
+ .hand-box {
30
+ border-color: #10B981;
31
+ }
32
+ .pinch-indicator {
33
+ position: absolute;
34
+ width: 20px;
35
+ height: 20px;
36
+ background-color: rgba(16, 185, 129, 0.7);
37
+ border-radius: 50%;
38
+ z-index: 20;
39
+ }
40
+ </style>
41
+ </head>
42
+ <body class="bg-gray-900 text-white min-h-screen flex flex-col">
43
+ <!-- Header -->
44
+ <header class="bg-gray-800 py-4 px-6 flex justify-between items-center shadow-lg">
45
+ <div class="flex items-center space-x-2">
46
+ <div class="w-10 h-10 bg-emerald-500 rounded-full flex items-center justify-center">
47
+ <i class="fas fa-robot text-xl"></i>
48
+ </div>
49
+ <h1 class="text-2xl font-bold">Scale AI</h1>
50
+ </div>
51
+
52
+ <!-- Toggle Switch -->
53
+ <div class="flex items-center space-x-3">
54
+ <span id="status-text" class="text-sm font-medium">Detection: Off</span>
55
+ <div class="relative inline-block w-12 mr-2 align-middle select-none">
56
+ <input type="checkbox" id="toggle" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
57
+ <label for="toggle" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label>
58
+ </div>
59
+ </div>
60
+ </header>
61
+
62
+ <!-- Main Content -->
63
+ <main class="flex-grow flex flex-col items-center justify-center p-6">
64
+ <div class="relative w-full max-w-3xl h-96 md:h-[32rem] bg-gray-800 rounded-xl overflow-hidden shadow-2xl">
65
+ <video id="video" class="w-full h-full object-cover" playsinline autoplay muted></video>
66
+ <canvas id="canvas" class="absolute top-0 left-0 w-full h-full"></canvas>
67
+
68
+ <!-- Loading Indicator -->
69
+ <div id="loading" class="absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-70">
70
+ <div class="text-center">
71
+ <div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-emerald-500 mx-auto mb-4"></div>
72
+ <p class="text-lg font-medium">Loading AI models...</p>
73
+ </div>
74
+ </div>
75
+
76
+ <!-- Instructions -->
77
+ <div id="instructions" class="absolute bottom-4 left-4 right-4 bg-gray-800 bg-opacity-80 p-3 rounded-lg text-sm hidden">
78
+ <p>👆 Pinch fingers together to toggle detection</p>
79
+ <p class="mt-1">👤 Person detection (red box)</p>
80
+ <p class="mt-1">✋ Hand detection (green box)</p>
81
+ </div>
82
+ </div>
83
+
84
+ <div class="mt-6 text-center max-w-2xl">
85
+ <h2 class="text-xl font-bold mb-2">Human Detection System</h2>
86
+ <p class="text-gray-300">Scale AI's advanced computer vision detects humans and hand gestures in real-time. Toggle detection with the switch or by pinching your fingers together.</p>
87
+ </div>
88
+ </main>
89
+
90
+ <!-- Footer -->
91
+ <footer class="bg-gray-800 py-4 px-6 text-center text-sm text-gray-400">
92
+ <p>© 2023 Scale AI Technologies. All rights reserved.</p>
93
+ </footer>
94
+
95
+ <script>
96
+ // DOM Elements
97
+ const video = document.getElementById('video');
98
+ const canvas = document.getElementById('canvas');
99
+ const ctx = canvas.getContext('2d');
100
+ const toggleSwitch = document.getElementById('toggle');
101
+ const statusText = document.getElementById('status-text');
102
+ const loadingIndicator = document.getElementById('loading');
103
+ const instructions = document.getElementById('instructions');
104
+
105
+ // State
106
+ let isDetectionActive = false;
107
+ let personDetector = null;
108
+ let handDetector = null;
109
+ let lastPinchTime = 0;
110
+ let animationId = null;
111
+
112
+ // Initialize the app
113
+ async function init() {
114
+ try {
115
+ // Load models
116
+ await Promise.all([
117
+ loadPersonDetectionModel(),
118
+ loadHandDetectionModel()
119
+ ]);
120
+
121
+ // Start camera
122
+ await startCamera();
123
+
124
+ // Hide loading indicator
125
+ loadingIndicator.classList.add('hidden');
126
+ instructions.classList.remove('hidden');
127
+
128
+ // Start detection loop
129
+ detect();
130
+ } catch (error) {
131
+ console.error('Initialization error:', error);
132
+ loadingIndicator.innerHTML = `
133
+ <div class="text-center">
134
+ <i class="fas fa-exclamation-triangle text-red-500 text-4xl mb-3"></i>
135
+ <p class="text-lg font-medium">Failed to initialize</p>
136
+ <p class="text-sm mt-2">${error.message}</p>
137
+ <button onclick="window.location.reload()" class="mt-4 px-4 py-2 bg-emerald-500 rounded-md hover:bg-emerald-600 transition">
138
+ Try Again
139
+ </button>
140
+ </div>
141
+ `;
142
+ }
143
+ }
144
+
145
+ // Load person detection model
146
+ async function loadPersonDetectionModel() {
147
+ personDetector = await cocoSsd.load();
148
+ console.log('Person detection model loaded');
149
+ }
150
+
151
+ // Load hand detection model
152
+ async function loadHandDetectionModel() {
153
+ handDetector = await handPoseDetection.createDetector(
154
+ handPoseDetection.SupportedModels.MediaPipeHands, {
155
+ runtime: 'tfjs',
156
+ modelType: 'full',
157
+ maxHands: 2
158
+ }
159
+ );
160
+ console.log('Hand detection model loaded');
161
+ }
162
+
163
+ // Start camera
164
+ async function startCamera() {
165
+ const stream = await navigator.mediaDevices.getUserMedia({
166
+ video: {
167
+ width: { ideal: 1280 },
168
+ height: { ideal: 720 },
169
+ facingMode: 'user'
170
+ },
171
+ audio: false
172
+ });
173
+
174
+ video.srcObject = stream;
175
+
176
+ return new Promise((resolve) => {
177
+ video.onloadedmetadata = () => {
178
+ // Set canvas dimensions to match video
179
+ canvas.width = video.videoWidth;
180
+ canvas.height = video.videoHeight;
181
+ resolve();
182
+ };
183
+ });
184
+ }
185
+
186
+ // Main detection loop
187
+ async function detect() {
188
+ if (!isDetectionActive) {
189
+ // Clear canvas if detection is off
190
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
191
+ animationId = requestAnimationFrame(detect);
192
+ return;
193
+ }
194
+
195
+ // Clear previous drawings
196
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
197
+
198
+ // Detect persons
199
+ if (personDetector) {
200
+ const persons = await personDetector.detect(video);
201
+ drawPersonBoxes(persons);
202
+ }
203
+
204
+ // Detect hands
205
+ if (handDetector) {
206
+ const hands = await handDetector.estimateHands(video);
207
+ drawHandBoxes(hands);
208
+ checkForPinchGesture(hands);
209
+ }
210
+
211
+ // Continue the loop
212
+ animationId = requestAnimationFrame(detect);
213
+ }
214
+
215
+ // Draw bounding boxes around detected persons
216
+ function drawPersonBoxes(persons) {
217
+ persons.forEach(person => {
218
+ if (person.class === 'person') {
219
+ const [x, y, width, height] = person.bbox;
220
+
221
+ // Draw box
222
+ const box = document.createElement('div');
223
+ box.className = 'detection-box person-box';
224
+ box.style.left = `${x}px`;
225
+ box.style.top = `${y}px`;
226
+ box.style.width = `${width}px`;
227
+ box.style.height = `${height}px`;
228
+
229
+ // Clear previous boxes and add new one
230
+ document.querySelectorAll('.person-box').forEach(el => el.remove());
231
+ canvas.parentNode.appendChild(box);
232
+
233
+ // Draw label
234
+ ctx.fillStyle = '#EF4444';
235
+ ctx.font = '16px Arial';
236
+ ctx.fillText(
237
+ `Person (${Math.round(person.score * 100)}%)`,
238
+ x,
239
+ y > 20 ? y - 5 : y + 20
240
+ );
241
+ }
242
+ });
243
+ }
244
+
245
+ // Draw bounding boxes around detected hands
246
+ function drawHandBoxes(hands) {
247
+ // Clear previous hand boxes and pinch indicators
248
+ document.querySelectorAll('.hand-box, .pinch-indicator').forEach(el => el.remove());
249
+
250
+ hands.forEach(hand => {
251
+ const keypoints = hand.keypoints;
252
+
253
+ // Calculate bounding box
254
+ let minX = Infinity, minY = Infinity, maxX = 0, maxY = 0;
255
+
256
+ keypoints.forEach(point => {
257
+ minX = Math.min(minX, point.x);
258
+ minY = Math.min(minY, point.y);
259
+ maxX = Math.max(maxX, point.x);
260
+ maxY = Math.max(maxY, point.y);
261
+ });
262
+
263
+ const width = maxX - minX;
264
+ const height = maxY - minY;
265
+
266
+ // Draw box
267
+ const box = document.createElement('div');
268
+ box.className = 'detection-box hand-box';
269
+ box.style.left = `${minX}px`;
270
+ box.style.top = `${minY}px`;
271
+ box.style.width = `${width}px`;
272
+ box.style.height = `${height}px`;
273
+ canvas.parentNode.appendChild(box);
274
+
275
+ // Draw pinch indicator if hand is pinching
276
+ if (isHandPinching(hand)) {
277
+ const indexTip = keypoints.find(p => p.name === 'index_finger_tip');
278
+ const thumbTip = keypoints.find(p => p.name === 'thumb_tip');
279
+
280
+ if (indexTip && thumbTip) {
281
+ const pinchX = (indexTip.x + thumbTip.x) / 2;
282
+ const pinchY = (indexTip.y + thumbTip.y) / 2;
283
+
284
+ const indicator = document.createElement('div');
285
+ indicator.className = 'pinch-indicator';
286
+ indicator.style.left = `${pinchX - 10}px`;
287
+ indicator.style.top = `${pinchY - 10}px`;
288
+ canvas.parentNode.appendChild(indicator);
289
+ }
290
+ }
291
+ });
292
+ }
293
+
294
+ // Check if hand is making a pinch gesture
295
+ function isHandPinching(hand) {
296
+ const keypoints = hand.keypoints;
297
+ const indexTip = keypoints.find(p => p.name === 'index_finger_tip');
298
+ const thumbTip = keypoints.find(p => p.name === 'thumb_tip');
299
+
300
+ if (!indexTip || !thumbTip) return false;
301
+
302
+ // Calculate distance between index and thumb tips
303
+ const dx = indexTip.x - thumbTip.x;
304
+ const dy = indexTip.y - thumbTip.y;
305
+ const distance = Math.sqrt(dx * dx + dy * dy);
306
+
307
+ // Consider it a pinch if distance is small
308
+ return distance < 30;
309
+ }
310
+
311
+ // Check for pinch gesture to toggle detection
312
+ function checkForPinchGesture(hands) {
313
+ const now = Date.now();
314
+
315
+ // Only allow toggle every 1 second to prevent rapid toggling
316
+ if (now - lastPinchTime < 1000) return;
317
+
318
+ // Check if any hand is pinching
319
+ const isPinching = hands.some(hand => isHandPinching(hand));
320
+
321
+ if (isPinching) {
322
+ lastPinchTime = now;
323
+ toggleDetection();
324
+ }
325
+ }
326
+
327
+ // Toggle detection state
328
+ function toggleDetection() {
329
+ isDetectionActive = !isDetectionActive;
330
+ toggleSwitch.checked = isDetectionActive;
331
+ statusText.textContent = `Detection: ${isDetectionActive ? 'On' : 'Off'}`;
332
+
333
+ // Visual feedback
334
+ const statusColor = isDetectionActive ? 'text-emerald-400' : 'text-red-400';
335
+ statusText.className = `text-sm font-medium ${statusColor}`;
336
+
337
+ // If turning on, start detection immediately
338
+ if (isDetectionActive && !animationId) {
339
+ detect();
340
+ }
341
+ }
342
+
343
+ // Event Listeners
344
+ toggleSwitch.addEventListener('change', toggleDetection);
345
+
346
+ // Initialize the app
347
+ window.addEventListener('DOMContentLoaded', init);
348
+
349
+ // Clean up on page unload
350
+ window.addEventListener('beforeunload', () => {
351
+ if (animationId) {
352
+ cancelAnimationFrame(animationId);
353
+ }
354
+
355
+ if (video.srcObject) {
356
+ video.srcObject.getTracks().forEach(track => track.stop());
357
+ }
358
+ });
359
+ </script>
360
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=cmbai13/scale-ai" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
361
+ </html>
prompts.txt ADDED
File without changes