File size: 4,242 Bytes
0930008
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MicroMind Vision Sentinel</title>
    <style>
        body { font-family: sans-serif; background: #111; color: white; text-align: center; }
        #container { position: relative; display: inline-block; margin-top: 20px; }
        video { border: 2px solid #333; border-radius: 8px; }
        canvas { position: absolute; top: 0; left: 0; pointer-events: none; }
        #status { margin: 10px; font-weight: bold; color: #0f0; }
        #config { color: #888; font-size: 0.9em; }
    </style>
</head>
<body>
    <h1>👁️ MicroMind Vision Sentinel</h1>
    <div id="status">System Status: CONNECTING...</div>
    <div id="config">Target: Unknown | Conf: 0.0</div>

    <div id="container">
        <video id="video" width="640" height="480" autoplay playsinline></video>
        <canvas id="canvas" width="640" height="480"></canvas>
    </div>

    <script>
        const video = document.getElementById('video');
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        const statusEl = document.getElementById('status');
        const configEl = document.getElementById('config');

        // 1. Start Webcam
        navigator.mediaDevices.getUserMedia({ video: true })
            .then(stream => { video.srcObject = stream; })
            .catch(err => { console.error("Camera Error:", err); statusEl.innerText = "CAMERA ERROR"; statusEl.style.color = "red"; });

        // 2. Processing Loop
        setInterval(() => {
            if (video.readyState === video.HAVE_ENOUGH_DATA) {
                // Draw video frame to hidden canvas to convert to blob
                const tempCanvas = document.createElement('canvas');
                tempCanvas.width = video.videoWidth;
                tempCanvas.height = video.videoHeight;
                tempCanvas.getContext('2d').drawImage(video, 0, 0);
                
                tempCanvas.toBlob(blob => {
                    const formData = new FormData();
                    formData.append('image', blob);

                    // Send to Python Backend
                    fetch('/process_frame', { method: 'POST', body: formData })
                        .then(res => res.json())
                        .then(data => {
                            // Update UI
                            statusEl.innerText = `STATUS: ${data.status}`;
                            statusEl.style.color = data.status === "ARMED" ? "#0f0" : "#fa0";
                            
                            if (data.target) {
                                configEl.innerText = `Target: ${data.target.toUpperCase()}`;
                            }

                            // Clear previous drawings
                            ctx.clearRect(0, 0, canvas.width, canvas.height);

                            // Draw detections
                            if (data.detections) {
                                data.detections.forEach(det => {
                                    const [x1, y1, x2, y2] = det.bbox;
                                    // Scale coordinates if video size differs from canvas
                                    const scaleX = canvas.width / video.videoWidth;
                                    const scaleY = canvas.height / video.videoHeight;

                                    ctx.strokeStyle = '#00FF00';
                                    ctx.lineWidth = 3;
                                    ctx.strokeRect(x1 * scaleX, y1 * scaleY, (x2-x1) * scaleX, (y2-y1) * scaleY);
                                    
                                    ctx.fillStyle = '#00FF00';
                                    ctx.font = '16px Arial';
                                    ctx.fillText(`${det.label} (${det.confidence})`, x1 * scaleX, (y1 * scaleY) - 5);
                                });
                            }
                        })
                        .catch(err => console.error("API Error", err));
                }, 'image/jpeg');
            }
        }, 500); // Process every 500ms (2 FPS)
    </script>
</body>
</html>