awacke1 commited on
Commit
9f49a9f
·
verified ·
1 Parent(s): 2148864

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -157
app.py CHANGED
@@ -7,8 +7,9 @@ import time
7
  from dataclasses import dataclass
8
  import zipfile
9
  import logging
10
- from streamlit.components.v1 import html
11
  from PIL import Image
 
 
12
 
13
  # Logging setup
14
  logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
@@ -188,157 +189,20 @@ def zip_files(files, zip_name):
188
  zipf.write(file, os.path.basename(file))
189
  return zip_name
190
 
191
- # JavaScript/HTML Dual Camera Component
192
- dual_camera_html = """
193
- <div style="width: 100%;">
194
- <h3>Dual Camera Capture</h3>
195
- <div>
196
- <label>Camera 0 Video: </label>
197
- <select id="videoSource0"></select>
198
- <label>Audio: </label>
199
- <select id="audioSource0"></select>
200
- <video id="video0" autoplay playsinline style="width: 45%; margin: 5px;"></video>
201
- </div>
202
- <div>
203
- <label>Camera 1 Video: </label>
204
- <select id="videoSource1"></select>
205
- <label>Audio: </label>
206
- <select id="audioSource1"></select>
207
- <video id="video1" autoplay playsinline style="width: 45%; margin: 5px;"></video>
208
- </div>
209
- <button onclick="startStreams()">Start Streams</button>
210
- <button onclick="captureFrame(0)">Capture Frame 📸 Cam 0</button>
211
- <button onclick="captureFrame(1)">Capture Frame 📸 Cam 1</button>
212
- <button onclick="captureVideo(0)">Capture Video 🎥 Cam 0</button>
213
- <button onclick="captureVideo(1)">Capture Video 🎥 Cam 1</button>
214
- <canvas id="canvas" style="display: none;"></canvas>
215
- </div>
216
- <script>
217
- const videoSource0 = document.getElementById('videoSource0');
218
- const audioSource0 = document.getElementById('audioSource0');
219
- const videoSource1 = document.getElementById('videoSource1');
220
- const audioSource1 = document.getElementById('audioSource1');
221
- const video0 = document.getElementById('video0');
222
- const video1 = document.getElementById('video1');
223
- const canvas = document.getElementById('canvas');
224
- let streams = [null, null];
225
- let recorders = [null, null];
226
-
227
- navigator.mediaDevices.enumerateDevices().then(devices => {
228
- let videoCount = 0;
229
- devices.forEach(device => {
230
- const option = document.createElement('option');
231
- option.value = device.deviceId;
232
- option.text = device.label || `${device.kind} ${device.deviceId}`;
233
- if (device.kind === 'videoinput') {
234
- videoSource0.appendChild(option.cloneNode(true));
235
- videoSource1.appendChild(option.cloneNode(true));
236
- videoCount++;
237
- } else if (device.kind === 'audioinput') {
238
- audioSource0.appendChild(option.cloneNode(true));
239
- audioSource1.appendChild(option.cloneNode(true));
240
- }
241
- });
242
- if (videoCount > 1) {
243
- videoSource1.selectedIndex = 1; // Default to second camera
244
- }
245
- }).catch(err => console.error('Error enumerating devices:', err));
246
-
247
- function startStreams() {
248
- [0, 1].forEach(i => {
249
- if (streams[i]) {
250
- streams[i].getTracks().forEach(track => track.stop());
251
- }
252
- const constraints = {
253
- video: { deviceId: document.getElementById(`videoSource${i}`).value ? { exact: document.getElementById(`videoSource${i}`).value } : undefined },
254
- audio: { deviceId: document.getElementById(`audioSource${i}`).value ? { exact: document.getElementById(`audioSource${i}`).value } : undefined }
255
- };
256
- navigator.mediaDevices.getUserMedia(constraints)
257
- .then(mediaStream => {
258
- streams[i] = mediaStream;
259
- document.getElementById(`video${i}`).srcObject = streams[i];
260
- recorders[i] = new MediaRecorder(streams[i]);
261
- const chunks = [];
262
- recorders[i].ondataavailable = e => chunks.push(e.data);
263
- recorders[i].onstop = () => {
264
- const blob = new Blob(chunks, { type: 'video/mp4' });
265
- saveFile(blob, `${i}${new Date().toISOString().replace(/[^0-9]/g, '')}.mp4`);
266
- sliceVideo(blob, i);
267
- };
268
- console.log(`Camera ${i} stream started`);
269
- })
270
- .catch(err => console.error(`Error starting Camera ${i}:`, err));
271
- });
272
- }
273
-
274
- function captureFrame(id) {
275
- const video = document.getElementById(`video${id}`);
276
- canvas.width = video.videoWidth;
277
- canvas.height = video.videoHeight;
278
- const ctx = canvas.getContext('2d');
279
- ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
280
- const dataUrl = canvas.toDataURL('image/png');
281
- saveFile(dataUrl, `${id}${new Date().toISOString().replace(/[^0-9]/g, '')}.png`);
282
- console.log(`Captured frame from Camera ${id}`);
283
- }
284
-
285
- function captureVideo(id) {
286
- recorders[id].start();
287
- setTimeout(() => recorders[id].stop(), 10000); // 10 seconds
288
- console.log(`Recording started for Camera ${id}`);
289
- }
290
-
291
- function saveFile(data, filename) {
292
- const link = document.createElement('a');
293
- link.href = data instanceof Blob ? URL.createObjectURL(data) : data;
294
- link.download = filename;
295
- link.click();
296
- }
297
-
298
- function sliceVideo(blob, id) {
299
- const video = document.createElement('video');
300
- video.src = URL.createObjectURL(blob);
301
- video.onloadedmetadata = () => {
302
- const ctx = canvas.getContext('2d');
303
- canvas.width = video.videoWidth;
304
- canvas.height = video.videoHeight;
305
- let frameCount = 0;
306
- const interval = video.duration / 10;
307
- video.currentTime = 0;
308
- const captureFrame = () => {
309
- if (frameCount < 10) {
310
- ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
311
- const dataUrl = canvas.toDataURL('image/png');
312
- saveFile(dataUrl, `${id}${new Date().toISOString().replace(/[^0-9]/g, '')}_${frameCount}.png`);
313
- console.log(`Captured frame ${frameCount} from Camera ${id}`);
314
- frameCount++;
315
- video.currentTime += interval;
316
- setTimeout(captureFrame, 100);
317
- }
318
- };
319
- video.play().then(captureFrame);
320
- };
321
- }
322
- </script>
323
- """
324
-
325
  # Main App
326
- st.title("SFT Tiny Titans 🚀 (Web Cam Action!)")
327
 
328
  # Sidebar Galleries
329
  st.sidebar.header("Captured Media 🎨")
330
  gallery_container = st.sidebar.empty()
331
  def update_gallery():
332
- media_files = get_gallery_files(["png", "mp4"])
333
  with gallery_container:
334
  if media_files:
335
  cols = st.columns(2)
336
  for idx, file in enumerate(media_files[:4]):
337
  with cols[idx % 2]:
338
- if file.endswith(".png"):
339
- st.image(Image.open(file), caption=file.split('/')[-1], use_container_width=True)
340
- elif file.endswith(".mp4"):
341
- st.video(file)
342
 
343
  # Sidebar Model Management
344
  st.sidebar.subheader("Model Hub 🗂️")
@@ -380,21 +244,73 @@ with tab1:
380
  st.error(f"Download failed: {str(e)}")
381
 
382
  with tab2:
383
- st.header("Camera Snap 📷 (Dual Live Feed!)")
384
- html(dual_camera_html, height=600)
385
- st.subheader("Upload Captured Files")
386
- uploaded_files = st.file_uploader("Upload PNGs/MP4s from Downloads", type=["png", "mp4"], accept_multiple_files=True)
387
- if uploaded_files:
388
- for file in uploaded_files:
389
- filename = file.name
390
  with open(filename, "wb") as f:
391
- f.write(file.read())
392
- logger.info(f"Saved uploaded file: {filename}")
393
- if filename.endswith(".png"):
394
- st.image(Image.open(filename), caption=filename, use_container_width=True)
395
- elif filename.endswith(".mp4"):
396
- st.video(filename)
397
- update_gallery()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
 
399
  with tab3:
400
  st.header("Fine-Tune & Test 🔧🧪")
@@ -436,7 +352,7 @@ with tab3:
436
  except Exception as e:
437
  st.error(f"CV fine-tune failed: {str(e)}")
438
  else:
439
- st.warning("Upload at least 2 PNGs in Camera Snap first! ⚠️")
440
  st.subheader("CV Test 🎨 (Image Set Demo)")
441
  if len(captured_images) >= 2:
442
  if st.button("Run CV Demo ▶️"):
@@ -465,7 +381,7 @@ with tab3:
465
  st.error(f"CV demo failed: {str(e)}")
466
  logger.error(f"Error in CV demo: {str(e)}")
467
  else:
468
- st.warning("Upload at least 2 PNGs in Camera Snap first! ⚠️")
469
 
470
  # Display Logs
471
  st.sidebar.subheader("Action Logs 📜")
 
7
  from dataclasses import dataclass
8
  import zipfile
9
  import logging
 
10
  from PIL import Image
11
+ import numpy as np
12
+ import cv2
13
 
14
  # Logging setup
15
  logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
 
189
  zipf.write(file, os.path.basename(file))
190
  return zip_name
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  # Main App
193
+ st.title("SFT Tiny Titans 🚀 (Camera Input Action!)")
194
 
195
  # Sidebar Galleries
196
  st.sidebar.header("Captured Media 🎨")
197
  gallery_container = st.sidebar.empty()
198
  def update_gallery():
199
+ media_files = get_gallery_files(["png"])
200
  with gallery_container:
201
  if media_files:
202
  cols = st.columns(2)
203
  for idx, file in enumerate(media_files[:4]):
204
  with cols[idx % 2]:
205
+ st.image(Image.open(file), caption=file.split('/')[-1], use_container_width=True)
 
 
 
206
 
207
  # Sidebar Model Management
208
  st.sidebar.subheader("Model Hub 🗂️")
 
244
  st.error(f"Download failed: {str(e)}")
245
 
246
  with tab2:
247
+ st.header("Camera Snap 📷 (Dual Capture!)")
248
+ cols = st.columns(2)
249
+ with cols[0]:
250
+ st.subheader("Camera 0")
251
+ cam0_img = st.camera_input("Take a picture - Cam 0", key="cam0")
252
+ if cam0_img:
253
+ filename = generate_filename(0)
254
  with open(filename, "wb") as f:
255
+ f.write(cam0_img.getvalue())
256
+ st.image(Image.open(filename), caption=filename, use_container_width=True)
257
+ logger.info(f"Saved snapshot from Camera 0: {filename}")
258
+ if 'captured_images' not in st.session_state:
259
+ st.session_state['captured_images'] = []
260
+ st.session_state['captured_images'].append(filename)
261
+ update_gallery()
262
+ with cols[1]:
263
+ st.subheader("Camera 1")
264
+ cam1_img = st.camera_input("Take a picture - Cam 1", key="cam1")
265
+ if cam1_img:
266
+ filename = generate_filename(1)
267
+ with open(filename, "wb") as f:
268
+ f.write(cam1_img.getvalue())
269
+ st.image(Image.open(filename), caption=filename, use_container_width=True)
270
+ logger.info(f"Saved snapshot from Camera 1: {filename}")
271
+ if 'captured_images' not in st.session_state:
272
+ st.session_state['captured_images'] = []
273
+ st.session_state['captured_images'].append(filename)
274
+ update_gallery()
275
+
276
+ st.subheader("Capture 10 Frames (Video Simulation)")
277
+ cols = st.columns(2)
278
+ with cols[0]:
279
+ if st.button("Capture 10 Frames - Cam 0 📸"):
280
+ st.session_state['cam0_frames'] = []
281
+ for i in range(10):
282
+ img = st.camera_input(f"Frame {i} - Cam 0", key=f"cam0_frame_{i}")
283
+ if img:
284
+ filename = generate_filename(f"0_{i}")
285
+ with open(filename, "wb") as f:
286
+ f.write(img.getvalue())
287
+ st.session_state['cam0_frames'].append(filename)
288
+ logger.info(f"Saved frame {i} from Camera 0: {filename}")
289
+ time.sleep(0.5) # Simulate video frame rate
290
+ if 'captured_images' not in st.session_state:
291
+ st.session_state['captured_images'] = []
292
+ st.session_state['captured_images'].extend(st.session_state['cam0_frames'])
293
+ update_gallery()
294
+ for frame in st.session_state['cam0_frames']:
295
+ st.image(Image.open(frame), caption=frame, use_container_width=True)
296
+ with cols[1]:
297
+ if st.button("Capture 10 Frames - Cam 1 📸"):
298
+ st.session_state['cam1_frames'] = []
299
+ for i in range(10):
300
+ img = st.camera_input(f"Frame {i} - Cam 1", key=f"cam1_frame_{i}")
301
+ if img:
302
+ filename = generate_filename(f"1_{i}")
303
+ with open(filename, "wb") as f:
304
+ f.write(img.getvalue())
305
+ st.session_state['cam1_frames'].append(filename)
306
+ logger.info(f"Saved frame {i} from Camera 1: {filename}")
307
+ time.sleep(0.5) # Simulate video frame rate
308
+ if 'captured_images' not in st.session_state:
309
+ st.session_state['captured_images'] = []
310
+ st.session_state['captured_images'].extend(st.session_state['cam1_frames'])
311
+ update_gallery()
312
+ for frame in st.session_state['cam1_frames']:
313
+ st.image(Image.open(frame), caption=frame, use_container_width=True)
314
 
315
  with tab3:
316
  st.header("Fine-Tune & Test 🔧🧪")
 
352
  except Exception as e:
353
  st.error(f"CV fine-tune failed: {str(e)}")
354
  else:
355
+ st.warning("Capture at least 2 images in Camera Snap first! ⚠️")
356
  st.subheader("CV Test 🎨 (Image Set Demo)")
357
  if len(captured_images) >= 2:
358
  if st.button("Run CV Demo ▶️"):
 
381
  st.error(f"CV demo failed: {str(e)}")
382
  logger.error(f"Error in CV demo: {str(e)}")
383
  else:
384
+ st.warning("Capture at least 2 images in Camera Snap first! ⚠️")
385
 
386
  # Display Logs
387
  st.sidebar.subheader("Action Logs 📜")