Spaces:
Running
Running
Update index.html
Browse files- index.html +106 -56
index.html
CHANGED
@@ -39,6 +39,25 @@
|
|
39 |
left: 0;
|
40 |
transform: scaleX(-1);
|
41 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
.detection-info {
|
43 |
margin-top: 20px;
|
44 |
padding: 10px;
|
@@ -54,6 +73,9 @@
|
|
54 |
margin-top: 10px;
|
55 |
font-size: 14px;
|
56 |
}
|
|
|
|
|
|
|
57 |
.detection-box {
|
58 |
position: absolute;
|
59 |
border: 2px solid #0f0;
|
@@ -78,6 +100,9 @@
|
|
78 |
<canvas id="canvas"></canvas>
|
79 |
</div>
|
80 |
|
|
|
|
|
|
|
81 |
<div class="detection-info">
|
82 |
<div id="detections"></div>
|
83 |
<div class="stats">
|
@@ -92,9 +117,10 @@
|
|
92 |
let canvas = document.getElementById('canvas');
|
93 |
let ctx = canvas.getContext('2d');
|
94 |
let model;
|
|
|
|
|
95 |
let lastTime = performance.now();
|
96 |
let frameCount = 0;
|
97 |
-
|
98 |
// Initialize camera and AI model
|
99 |
async function init() {
|
100 |
// Load COCO-SSD model
|
@@ -119,68 +145,92 @@
|
|
119 |
// Start detection loop
|
120 |
requestAnimationFrame(detect);
|
121 |
}
|
122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
async function detect() {
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
}
|
132 |
-
|
133 |
-
// Detect objects
|
134 |
-
const predictions = await model.detect(video);
|
135 |
-
|
136 |
-
// Clear previous detections
|
137 |
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
138 |
-
|
139 |
-
// Draw new detections
|
140 |
-
predictions.forEach(prediction => {
|
141 |
-
// Draw bounding box
|
142 |
-
ctx.strokeStyle = '#00ff00';
|
143 |
-
ctx.lineWidth = 2;
|
144 |
-
ctx.strokeRect(
|
145 |
-
prediction.bbox[0],
|
146 |
-
prediction.bbox[1],
|
147 |
-
prediction.bbox[2],
|
148 |
-
prediction.bbox[3]
|
149 |
-
);
|
150 |
-
// Draw label background
|
151 |
-
ctx.fillStyle = '#00ff00';
|
152 |
-
ctx.fillRect(
|
153 |
-
prediction.bbox[0],
|
154 |
-
prediction.bbox[1] - 20,
|
155 |
-
prediction.bbox[2],
|
156 |
-
20
|
157 |
-
);
|
158 |
-
// Draw label text
|
159 |
-
ctx.fillStyle = '#000000';
|
160 |
-
ctx.font = '16px monospace';
|
161 |
-
ctx.fillText(
|
162 |
-
`${prediction.class} ${Math.round(prediction.score * 100)}%`,
|
163 |
-
prediction.bbox[0] + 5,
|
164 |
-
prediction.bbox[1] - 5
|
165 |
-
);
|
166 |
-
});
|
167 |
-
|
168 |
-
// Update detection info
|
169 |
-
document.getElementById('objects').textContent =
|
170 |
-
`Objects detected: ${predictions.length}`;
|
171 |
-
|
172 |
-
document.getElementById('detections').innerHTML =
|
173 |
-
predictions.map(p =>
|
174 |
-
`Detected ${p.class} (${Math.round(p.score * 100)}% confidence)`
|
175 |
-
).join('<br>');
|
176 |
-
|
177 |
requestAnimationFrame(detect);
|
178 |
}
|
179 |
-
|
180 |
// Start application
|
181 |
init().catch(err => {
|
182 |
console.error('Error initializing camera:', err);
|
183 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
</script>
|
185 |
</body>
|
186 |
-
</html>
|
|
|
39 |
left: 0;
|
40 |
transform: scaleX(-1);
|
41 |
}
|
42 |
+
.controls {
|
43 |
+
margin-top: 20px;
|
44 |
+
display: flex;
|
45 |
+
gap: 10px;
|
46 |
+
}
|
47 |
+
button {
|
48 |
+
background: #0f0;
|
49 |
+
color: #000;
|
50 |
+
border: none;
|
51 |
+
padding: 10px 20px;
|
52 |
+
border-radius: 4px;
|
53 |
+
cursor: pointer;
|
54 |
+
font-weight: bold;
|
55 |
+
transition: all 0.3s;
|
56 |
+
}
|
57 |
+
button:hover {
|
58 |
+
background: #0f0;
|
59 |
+
box-shadow: 0 0 10px #0f0;
|
60 |
+
}
|
61 |
.detection-info {
|
62 |
margin-top: 20px;
|
63 |
padding: 10px;
|
|
|
73 |
margin-top: 10px;
|
74 |
font-size: 14px;
|
75 |
}
|
76 |
+
.night-vision {
|
77 |
+
filter: brightness(2) contrast(1.2) hue-rotate(120deg) grayscale(0.5);
|
78 |
+
}
|
79 |
.detection-box {
|
80 |
position: absolute;
|
81 |
border: 2px solid #0f0;
|
|
|
100 |
<canvas id="canvas"></canvas>
|
101 |
</div>
|
102 |
|
103 |
+
|
104 |
+
</div>
|
105 |
+
|
106 |
<div class="detection-info">
|
107 |
<div id="detections"></div>
|
108 |
<div class="stats">
|
|
|
117 |
let canvas = document.getElementById('canvas');
|
118 |
let ctx = canvas.getContext('2d');
|
119 |
let model;
|
120 |
+
let isNightVision = false;
|
121 |
+
let isDetecting = false;
|
122 |
let lastTime = performance.now();
|
123 |
let frameCount = 0;
|
|
|
124 |
// Initialize camera and AI model
|
125 |
async function init() {
|
126 |
// Load COCO-SSD model
|
|
|
145 |
// Start detection loop
|
146 |
requestAnimationFrame(detect);
|
147 |
}
|
148 |
+
function toggleNightVision() {
|
149 |
+
isNightVision = !isNightVision;
|
150 |
+
video.className = isNightVision ? 'night-vision' : '';
|
151 |
+
}
|
152 |
+
function toggleDetection() {
|
153 |
+
isDetecting = !isDetecting;
|
154 |
+
}
|
155 |
async function detect() {
|
156 |
+
if (isDetecting) {
|
157 |
+
// Calculate FPS
|
158 |
+
const now = performance.now();
|
159 |
+
frameCount++;
|
160 |
+
if (now - lastTime >= 1000) {
|
161 |
+
document.getElementById('fps').textContent = `FPS: ${frameCount}`;
|
162 |
+
frameCount = 0;
|
163 |
+
lastTime = now;
|
164 |
+
}
|
165 |
+
// Detect objects
|
166 |
+
const predictions = await model.detect(video);
|
167 |
+
|
168 |
+
// Clear previous detections
|
169 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
170 |
+
// Draw new detections
|
171 |
+
predictions.forEach(prediction => {
|
172 |
+
// Draw bounding box
|
173 |
+
ctx.strokeStyle = '#00ff00';
|
174 |
+
ctx.lineWidth = 2;
|
175 |
+
ctx.strokeRect(
|
176 |
+
prediction.bbox[0],
|
177 |
+
prediction.bbox[1],
|
178 |
+
prediction.bbox[2],
|
179 |
+
prediction.bbox[3]
|
180 |
+
);
|
181 |
+
// Draw label background
|
182 |
+
ctx.fillStyle = '#00ff00';
|
183 |
+
ctx.fillRect(
|
184 |
+
prediction.bbox[0],
|
185 |
+
prediction.bbox[1] - 20,
|
186 |
+
prediction.bbox[2],
|
187 |
+
20
|
188 |
+
);
|
189 |
+
// Draw label text
|
190 |
+
ctx.fillStyle = '#000000';
|
191 |
+
ctx.font = '16px monospace';
|
192 |
+
ctx.fillText(
|
193 |
+
`${prediction.class} ${Math.round(prediction.score * 100)}%`,
|
194 |
+
prediction.bbox[0] + 5,
|
195 |
+
prediction.bbox[1] - 5
|
196 |
+
);
|
197 |
+
});
|
198 |
+
// Update detection info
|
199 |
+
document.getElementById('objects').textContent =
|
200 |
+
`Objects detected: ${predictions.length}`;
|
201 |
+
|
202 |
+
document.getElementById('detections').innerHTML =
|
203 |
+
predictions.map(p =>
|
204 |
+
`Detected ${p.class} (${Math.round(p.score * 100)}% confidence)`
|
205 |
+
).join('<br>');
|
206 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
requestAnimationFrame(detect);
|
208 |
}
|
|
|
209 |
// Start application
|
210 |
init().catch(err => {
|
211 |
console.error('Error initializing camera:', err);
|
212 |
});
|
213 |
+
// Add image processing for better night vision
|
214 |
+
const imageProcessor = new ImageCapture(video.srcObject.getVideoTracks()[0]);
|
215 |
+
|
216 |
+
async function enhanceNightVision() {
|
217 |
+
if (isNightVision) {
|
218 |
+
try {
|
219 |
+
const photoCapabilities = await imageProcessor.getPhotoCapabilities();
|
220 |
+
await imageProcessor.setOptions({
|
221 |
+
brightness: photoCapabilities.brightness.max,
|
222 |
+
contrast: photoCapabilities.contrast.max,
|
223 |
+
saturation: 0,
|
224 |
+
sharpness: photoCapabilities.sharpness.max,
|
225 |
+
exposureMode: 'manual',
|
226 |
+
exposureCompensation: 2,
|
227 |
+
whiteBalanceMode: 'manual'
|
228 |
+
});
|
229 |
+
} catch (err) {
|
230 |
+
console.log('Night vision enhancement not supported');
|
231 |
+
}
|
232 |
+
}
|
233 |
+
}
|
234 |
</script>
|
235 |
</body>
|
236 |
+
</html>
|