Paradise151 commited on
Commit
aa29e91
·
verified ·
1 Parent(s): 22abd80

Create indexPhoto_v2

Browse files
Files changed (1) hide show
  1. indexPhoto_v2 +175 -0
indexPhoto_v2 ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ <!DOCTYPE html>
4
+ <html>
5
+ <head>
6
+ <meta charset="utf-8">
7
+ <title>GrechnikNet — Snapshot Detection</title>
8
+ <style>
9
+ body { background:#111; color:#eee; font-family:sans-serif; margin:0; text-align:center; }
10
+ header { padding:16px; }
11
+ video, img { width: min(100vw, 720px); height:auto; border:1px solid #333; border-radius:8px; margin:10px 0; }
12
+ .controls { display:flex; gap:16px; flex-wrap:wrap; justify-content:center; margin:16px 0; }
13
+ .control { background:#1b1b1b; padding:10px 12px; border-radius:8px; }
14
+ label { display:block; font-size:14px; margin-bottom:6px; }
15
+ input[type="range"] { width:200px; }
16
+ button { padding:10px 16px; border:none; border-radius:6px; background:#3a6df0; color:#fff; cursor:pointer; }
17
+ button:disabled { background:#555; cursor:not-allowed; }
18
+ pre { text-align:left; background:#0e0e0e; padding:12px; border-radius:8px; width:min(100vw,720px); margin:10px auto; }
19
+ </style>
20
+ </head>
21
+ <body>
22
+ <header>
23
+ <h2>GrechnikNet — Snapshot Detection</h2>
24
+ <p>Сверху поток с камеры, снизу результат последнего снимка</p>
25
+ </header>
26
+
27
+ <!-- Панель управления -->
28
+ <div class="controls">
29
+ <div class="control">
30
+ <label>Камера:</label>
31
+ <select id="cameraSelect"></select>
32
+ </div>
33
+ <div class="control">
34
+ <label>Степень уверенности (conf): <span id="confVal">0.25</span></label>
35
+ <input type="range" id="confSlider" min="0" max="1" step="0.05" value="0.25">
36
+ </div>
37
+ <div class="control">
38
+ <label>Степень пересечения (IoU): <span id="iouVal">0.45</span></label>
39
+ <input type="range" id="iouSlider" min="0" max="1" step="0.05" value="0.45">
40
+ </div>
41
+ <div class="control">
42
+ <label>Режим ответа:</label>
43
+ <select id="modeSelect">
44
+ <option value="image">Аннотированное изображение</option>
45
+ <option value="json">Только боксы (JSON)</option>
46
+ </select>
47
+ </div>
48
+ <div class="control">
49
+ <button id="startBtn">Старт</button>
50
+ <button id="stopBtn" disabled>Стоп</button>
51
+ </div>
52
+ </div>
53
+
54
+ <!-- Верхнее окно: поток -->
55
+ <video id="video" autoplay playsinline muted></video>
56
+
57
+ <!-- Кнопка между окнами -->
58
+ <button id="snapBtn">Сделать фото</button>
59
+
60
+ <!-- Нижнее окно: результат -->
61
+ <img id="resultImg" alt="Результат появится здесь">
62
+ <pre id="jsonOut" style="display:none;"></pre>
63
+
64
+ <script>
65
+ const video = document.getElementById('video');
66
+ const resultImg = document.getElementById('resultImg');
67
+ const jsonOut = document.getElementById('jsonOut');
68
+ const snapBtn = document.getElementById('snapBtn');
69
+ const cameraSelect = document.getElementById('cameraSelect');
70
+ const confSlider = document.getElementById('confSlider');
71
+ const iouSlider = document.getElementById('iouSlider');
72
+ const confVal = document.getElementById('confVal');
73
+ const iouVal = document.getElementById('iouVal');
74
+ const modeSelect = document.getElementById('modeSelect');
75
+ const startBtn = document.getElementById('startBtn');
76
+ const stopBtn = document.getElementById('stopBtn');
77
+
78
+ let stream = null;
79
+ let currentDeviceId = null;
80
+
81
+ confSlider.oninput = () => confVal.textContent = confSlider.value;
82
+ iouSlider.oninput = () => iouVal.textContent = iouSlider.value;
83
+
84
+ async function enumerateCameras() {
85
+ const devices = await navigator.mediaDevices.enumerateDevices();
86
+ cameraSelect.innerHTML = '';
87
+ const cams = devices.filter(d => d.kind === 'videoinput');
88
+ cams.forEach((cam, i) => {
89
+ const opt = document.createElement('option');
90
+ opt.value = cam.deviceId || i;
91
+ opt.textContent = cam.label || `Камера ${i+1}`;
92
+ cameraSelect.appendChild(opt);
93
+ });
94
+ if (cams.length > 0) currentDeviceId = cams[0].deviceId;
95
+ }
96
+
97
+ async function startCamera(deviceId) {
98
+ if (stream) stopCamera();
99
+ const constraints = {
100
+ video: {
101
+ deviceId: deviceId ? { exact: deviceId } : undefined,
102
+ facingMode: 'environment',
103
+ width: { ideal: 720 },
104
+ height: { ideal: 720 }
105
+ },
106
+ audio: false
107
+ };
108
+ stream = await navigator.mediaDevices.getUserMedia(constraints);
109
+ video.srcObject = stream;
110
+ await video.play();
111
+ }
112
+
113
+ function stopCamera() {
114
+ if (stream) {
115
+ stream.getTracks().forEach(t => t.stop());
116
+ stream = null;
117
+ }
118
+ }
119
+
120
+ cameraSelect.onchange = async () => {
121
+ currentDeviceId = cameraSelect.value;
122
+ await startCamera(currentDeviceId);
123
+ };
124
+
125
+ async function takePhoto() {
126
+ if (!video.srcObject) return;
127
+
128
+ const canvas = document.createElement('canvas');
129
+ const w = Math.min(720, video.videoWidth || 640);
130
+ const h = Math.floor(w * (video.videoHeight / video.videoWidth));
131
+ canvas.width = w;
132
+ canvas.height = h;
133
+ const ctx = canvas.getContext('2d');
134
+ ctx.drawImage(video, 0, 0, w, h);
135
+
136
+ const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/jpeg', 0.9));
137
+ const formData = new FormData();
138
+ formData.append('file', blob, 'frame.jpg');
139
+ formData.append('conf', confSlider.value);
140
+ formData.append('iou', iouSlider.value);
141
+ const returnImage = (modeSelect.value === 'image') ? 1 : 0;
142
+ formData.append('return_image', returnImage.toString());
143
+
144
+ const resp = await fetch('/predict', { method: 'POST', body: formData });
145
+ if (returnImage === 1) {
146
+ const arrBuf = await resp.arrayBuffer();
147
+ const blobRes = new Blob([arrBuf], { type: 'image/jpeg' });
148
+ resultImg.src = URL.createObjectURL(blobRes);
149
+ resultImg.style.display = 'block';
150
+ jsonOut.style.display = 'none';
151
+ } else {
152
+ const data = await resp.json();
153
+ jsonOut.textContent = JSON.stringify(data, null, 2);
154
+ jsonOut.style.display = 'block';
155
+ resultImg.style.display = 'none';
156
+ }
157
+ }
158
+
159
+ snapBtn.onclick = takePhoto;
160
+
161
+ startBtn.onclick = async () => {
162
+ await enumerateCameras();
163
+ await startCamera(currentDeviceId);
164
+ startBtn.disabled = true;
165
+ stopBtn.disabled = false;
166
+ };
167
+
168
+ stopBtn.onclick = () => {
169
+ stopCamera();
170
+ startBtn.disabled = false;
171
+ stopBtn.disabled = true;
172
+ };
173
+ </script>
174
+ </body>
175
+ </html>