Paradise151 commited on
Commit
5acd887
·
verified ·
1 Parent(s): 333b7d2

Update index.html

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