awacke1 commited on
Commit
a111a9f
·
verified ·
1 Parent(s): 33a90a5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -55
app.py CHANGED
@@ -7,9 +7,8 @@ import time
7
  from dataclasses import dataclass
8
  import zipfile
9
  import logging
10
- import cv2
11
- from PIL import Image
12
- import numpy as np
13
 
14
  # Logging setup
15
  logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
@@ -190,6 +189,30 @@ def zip_files(files, zip_name):
190
  zipf.write(file, os.path.basename(file))
191
  return zip_name
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  # Main App
194
  st.title("SFT Tiny Titans 🚀 (Dual Cam Action!)")
195
 
@@ -204,6 +227,7 @@ def update_gallery():
204
  for idx, file in enumerate(media_files[:4]):
205
  with cols[idx % 2]:
206
  if file.endswith(".png"):
 
207
  st.image(Image.open(file), caption=file.split('/')[-1], use_container_width=True)
208
  elif file.endswith(".mp4"):
209
  st.video(file)
@@ -249,82 +273,77 @@ with tab1:
249
 
250
  with tab2:
251
  st.header("Camera Snap 📷 (Dual Live Feed!)")
252
- caps = {0: cv2.VideoCapture(0), 1: cv2.VideoCapture(1)}
253
  cols = st.columns(2)
 
254
  for i in range(2):
255
  with cols[i]:
256
  st.subheader(f"Camera {i}")
257
- if caps[i].isOpened():
258
- ret, frame = caps[i].read()
259
- if ret:
260
- frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
261
- st.image(frame_rgb, caption=f"Live Feed Cam {i}", use_container_width=True)
262
- else:
263
- st.warning(f"Camera {i} failed to read frame!")
264
- logger.error(f"Failed to read frame from Camera {i}")
265
- else:
266
- st.warning(f"Camera {i} not detected!")
267
- logger.error(f"Camera {i} not opened")
268
-
269
  if st.button(f"Capture Frame 📸 Cam {i}", key=f"snap_{i}"):
270
  logger.info(f"Capturing frame from Camera {i}")
271
  try:
272
- ret, frame = caps[i].read()
273
- if ret:
274
- frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
275
- img = Image.fromarray(frame_rgb)
276
  filename = generate_filename(i)
277
- img.save(filename)
278
- st.image(img, caption=filename, use_container_width=True)
279
  logger.info(f"Saved snapshot: {filename}")
280
  if 'captured_images' not in st.session_state:
281
  st.session_state['captured_images'] = []
282
  st.session_state['captured_images'].append(filename)
283
  update_gallery()
284
  else:
285
- st.error("Failed to capture frame!")
286
  logger.error(f"No frame captured from Camera {i}")
287
  except Exception as e:
288
  st.error(f"Frame capture failed: {str(e)}")
289
  logger.error(f"Error capturing frame: {str(e)}")
290
-
291
  if st.button(f"Capture Video 🎥 Cam {i}", key=f"rec_{i}"):
292
  logger.info(f"Capturing 10s video from Camera {i}")
293
  try:
294
- fourcc = cv2.VideoWriter_fourcc(*'mp4v')
295
- mp4_filename = generate_filename(i, "mp4")
296
- out = cv2.VideoWriter(mp4_filename, fourcc, 30.0, (int(caps[i].get(3)), int(caps[i].get(4))))
297
- frames = []
298
- start_time = time.time()
299
- while time.time() - start_time < 10:
300
- ret, frame = caps[i].read()
301
- if ret:
302
- frames.append(frame)
303
- out.write(frame)
304
- time.sleep(0.033) # ~30 FPS
305
- out.release()
306
- st.video(mp4_filename)
307
- logger.info(f"Saved video: {mp4_filename}")
308
- # Slice into 10 frames
309
- sliced_images = []
310
- step = max(1, len(frames) // 10)
311
- for j in range(0, len(frames), step):
312
- if len(sliced_images) < 10:
313
- frame_rgb = cv2.cvtColor(frames[j], cv2.COLOR_BGR2RGB)
314
- img = Image.fromarray(frame_rgb)
315
- img_filename = generate_filename(f"{i}_{len(sliced_images)}")
316
- img.save(img_filename)
317
- sliced_images.append(img_filename)
318
- st.image(img, caption=img_filename, use_container_width=True)
319
- st.session_state['captured_images'] = st.session_state.get('captured_images', []) + sliced_images
320
- logger.info(f"Sliced video into {len(sliced_images)} images")
321
- update_gallery()
 
 
 
 
 
 
322
  except Exception as e:
323
  st.error(f"Video capture failed: {str(e)}")
324
  logger.error(f"Error capturing video: {str(e)}")
325
- # Release cameras after use
326
- for cap in caps.values():
327
- cap.release()
328
 
329
  with tab3:
330
  st.header("Fine-Tune Titans 🔧 (Tune Fast!)")
@@ -351,6 +370,7 @@ with tab3:
351
  if st.button("Tune CV 🔄"):
352
  logger.info("Initiating CV fine-tune")
353
  try:
 
354
  images = [Image.open(img) for img in captured_images]
355
  st.session_state['builder'].fine_tune(images, texts)
356
  st.success("CV polished! 🎉")
@@ -381,6 +401,7 @@ with tab4:
381
  if st.button("Run CV Demo ▶️"):
382
  logger.info("Running CV image set demo")
383
  try:
 
384
  images = [Image.open(img) for img in captured_images[:10]]
385
  prompts = ["Neon " + os.path.basename(img).split('.')[0] for img in captured_images[:10]]
386
  generated_images = []
 
7
  from dataclasses import dataclass
8
  import zipfile
9
  import logging
10
+ import av
11
+ from streamlit_webrtc import webrtc_streamer, VideoProcessorBase, WebRtcMode
 
12
 
13
  # Logging setup
14
  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
+ # Video Processor for WebRTC
193
+ class CameraProcessor(VideoProcessorBase):
194
+ def __init__(self):
195
+ self.frame = None
196
+
197
+ def recv(self, frame):
198
+ from PIL import Image
199
+ img = frame.to_image()
200
+ self.frame = img
201
+ return av.VideoFrame.from_image(img)
202
+
203
+ def capture_frame(self):
204
+ from PIL import Image
205
+ return self.frame
206
+
207
+ def capture_video(self):
208
+ from PIL import Image
209
+ frames = []
210
+ start_time = time.time()
211
+ while time.time() - start_time < 10 and self.frame:
212
+ frames.append(np.array(self.frame))
213
+ time.sleep(0.033) # ~30 FPS
214
+ return frames
215
+
216
  # Main App
217
  st.title("SFT Tiny Titans 🚀 (Dual Cam Action!)")
218
 
 
227
  for idx, file in enumerate(media_files[:4]):
228
  with cols[idx % 2]:
229
  if file.endswith(".png"):
230
+ from PIL import Image
231
  st.image(Image.open(file), caption=file.split('/')[-1], use_container_width=True)
232
  elif file.endswith(".mp4"):
233
  st.video(file)
 
273
 
274
  with tab2:
275
  st.header("Camera Snap 📷 (Dual Live Feed!)")
 
276
  cols = st.columns(2)
277
+ processors = {}
278
  for i in range(2):
279
  with cols[i]:
280
  st.subheader(f"Camera {i}")
281
+ key = f"camera_{i}"
282
+ processors[key] = webrtc_streamer(
283
+ key=key,
284
+ mode=WebRtcMode.SENDRECV,
285
+ video_processor_factory=CameraProcessor,
286
+ frontend_rtc_configuration={"iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]}
287
+ )
 
 
 
 
 
288
  if st.button(f"Capture Frame 📸 Cam {i}", key=f"snap_{i}"):
289
  logger.info(f"Capturing frame from Camera {i}")
290
  try:
291
+ if processors[key].video_processor and processors[key].video_processor.frame:
292
+ snapshot = processors[key].video_processor.capture_frame()
 
 
293
  filename = generate_filename(i)
294
+ snapshot.save(filename)
295
+ st.image(snapshot, caption=filename, use_container_width=True)
296
  logger.info(f"Saved snapshot: {filename}")
297
  if 'captured_images' not in st.session_state:
298
  st.session_state['captured_images'] = []
299
  st.session_state['captured_images'].append(filename)
300
  update_gallery()
301
  else:
302
+ st.error("No frame available!")
303
  logger.error(f"No frame captured from Camera {i}")
304
  except Exception as e:
305
  st.error(f"Frame capture failed: {str(e)}")
306
  logger.error(f"Error capturing frame: {str(e)}")
 
307
  if st.button(f"Capture Video 🎥 Cam {i}", key=f"rec_{i}"):
308
  logger.info(f"Capturing 10s video from Camera {i}")
309
  try:
310
+ if processors[key].video_processor:
311
+ frames = processors[key].video_processor.capture_video()
312
+ if frames:
313
+ mp4_filename = generate_filename(i, "mp4")
314
+ with av.open(mp4_filename, "w") as container:
315
+ stream = container.add_stream("h264", rate=30)
316
+ stream.width = frames[0].shape[1]
317
+ stream.height = frames[0].shape[0]
318
+ for frame in frames:
319
+ av_frame = av.VideoFrame.from_ndarray(frame, format="rgb24")
320
+ for packet in stream.encode(av_frame):
321
+ container.mux(packet)
322
+ for packet in stream.encode():
323
+ container.mux(packet)
324
+ st.video(mp4_filename)
325
+ logger.info(f"Saved video: {mp4_filename}")
326
+ sliced_images = []
327
+ step = max(1, len(frames) // 10)
328
+ for j in range(0, len(frames), step):
329
+ if len(sliced_images) < 10:
330
+ img = Image.fromarray(frames[j])
331
+ img_filename = generate_filename(f"{i}_{len(sliced_images)}")
332
+ img.save(img_filename)
333
+ sliced_images.append(img_filename)
334
+ st.image(img, caption=img_filename, use_container_width=True)
335
+ st.session_state['captured_images'] = st.session_state.get('captured_images', []) + sliced_images
336
+ logger.info(f"Sliced video into {len(sliced_images)} images")
337
+ update_gallery()
338
+ else:
339
+ st.error("No frames recorded!")
340
+ logger.error("No frames captured during video recording")
341
+ else:
342
+ st.error("Camera processor not initialized!")
343
+ logger.error(f"Processor not ready for Camera {i}")
344
  except Exception as e:
345
  st.error(f"Video capture failed: {str(e)}")
346
  logger.error(f"Error capturing video: {str(e)}")
 
 
 
347
 
348
  with tab3:
349
  st.header("Fine-Tune Titans 🔧 (Tune Fast!)")
 
370
  if st.button("Tune CV 🔄"):
371
  logger.info("Initiating CV fine-tune")
372
  try:
373
+ from PIL import Image
374
  images = [Image.open(img) for img in captured_images]
375
  st.session_state['builder'].fine_tune(images, texts)
376
  st.success("CV polished! 🎉")
 
401
  if st.button("Run CV Demo ▶️"):
402
  logger.info("Running CV image set demo")
403
  try:
404
+ from PIL import Image
405
  images = [Image.open(img) for img in captured_images[:10]]
406
  prompts = ["Neon " + os.path.basename(img).split('.')[0] for img in captured_images[:10]]
407
  generated_images = []