curryporkchop commited on
Commit
bc7ab19
·
verified ·
1 Parent(s): b02530e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -148
app.py CHANGED
@@ -209,12 +209,13 @@
209
 
210
 
211
 
 
 
212
  import streamlit as st
213
  import mediapipe as mp
214
  import cv2
 
215
  import os
216
- import time
217
- from queue import Queue
218
  from utils import display_gesture_chart
219
 
220
  # Initialize MediaPipe Hands for hand landmark detection
@@ -236,27 +237,6 @@ model_path = 'gesture_recognizer.task'
236
  if not os.path.exists(model_path):
237
  raise FileNotFoundError(f"Model file not found at {model_path}")
238
 
239
- # Queue to share gesture results between the callback and the main thread
240
- gesture_queue = Queue()
241
-
242
- # Callback function to process gesture results and add them to the queue
243
- def print_result(result: GestureRecognizerResult, output_image: mp.Image, timestamp_ms: int):
244
- results = []
245
- if result.gestures:
246
- for hand_gestures in result.gestures:
247
- for gesture in hand_gestures:
248
- results.append(f"{gesture.category_name} (Confidence: {gesture.score:.2f})")
249
- else:
250
- results.append("No gestures detected.")
251
- gesture_queue.put(results)
252
-
253
- # Configure the Gesture Recognizer options
254
- options = GestureRecognizerOptions(
255
- base_options=BaseOptions(model_asset_path=model_path),
256
- running_mode=VisionRunningMode.LIVE_STREAM,
257
- result_callback=print_result
258
- )
259
-
260
  # Initialize session state for saving recognized gestures
261
  if "recognized_gestures" not in st.session_state:
262
  st.session_state.recognized_gestures = []
@@ -282,104 +262,40 @@ st.sidebar.markdown("<hr>", unsafe_allow_html=True)
282
  gesture_chart_path = "./gestureReference.png" # Update this with the actual path to the image
283
  display_gesture_chart(gesture_chart_path)
284
 
285
- # User-configurable options
286
- max_num_hands = st.sidebar.slider("Max Number of Hands", 1, 2, 1)
287
- skip_frames = st.sidebar.slider("Process Every Nth Frame", 1, 10, 5)
288
- resolution = st.sidebar.selectbox("Frame Resolution", ["320x240", "640x480"], index=0)
289
-
290
- st.sidebar.markdown("<hr>", unsafe_allow_html=True)
291
-
292
- # Start and Stop buttons
293
- if "run_app" not in st.session_state:
294
- st.session_state.run_app = False
295
-
296
- col1, col2 = st.sidebar.columns(2)
297
- if col1.button("▶ Start"):
298
- st.session_state.run_app = True
299
-
300
- if col2.button("⏹ Stop"):
301
- st.session_state.run_app = False
302
-
303
  # Clear gesture history button
304
  if st.sidebar.button("🚲 Clear History"):
305
  st.session_state.recognized_gestures = []
306
 
307
- # Layout with columns: Live camera feed on the left, gesture log box on the right
308
  col_feed, col_log = st.columns([5, 2])
309
 
310
  with col_feed:
311
- st.markdown("### Live Camera Feed")
312
- video_placeholder = st.empty() # Placeholder for displaying the video feed
313
-
314
- with col_log:
315
- st.markdown("### Gesture Log")
316
- current_gesture_box = st.empty() # Box for the most recent gesture
317
- st.markdown("### Gesture History")
318
- gesture_history_box = st.empty() # Box for gesture history
319
-
320
- # Footer with branding
321
- st.sidebar.markdown(
322
- """
323
- <style>
324
- .footer {text-align: center; font-size: 12px; color: grey; margin-top: 20px;}
325
- </style>
326
- <p class="footer">Made by Marco Chen, William Taka, Rigoberto Ponce using Streamlit, MediaPipe & OpenCV</p>
327
- """,
328
- unsafe_allow_html=True,
329
- )
330
-
331
- if st.session_state.run_app:
332
- # Open a video capture device (webcam)
333
- cap = cv2.VideoCapture(0)
334
-
335
- # Parse resolution to width and height
336
- res_width, res_height = map(int, resolution.split("x"))
337
-
338
- # Start a timestamp for gesture recognition
339
- start_time = time.time()
340
-
341
- # Initialize MediaPipe components
342
- with GestureRecognizer.create_from_options(options) as recognizer, mp_hands.Hands(
343
- max_num_hands=max_num_hands,
344
- model_complexity=1, # Use simplified model for better performance
345
- min_detection_confidence=0.5,
346
- min_tracking_confidence=0.5
347
- ) as hands:
348
- frame_count = 0 # Counter to track frames processed
349
-
350
- while st.session_state.run_app and cap.isOpened():
351
- success, frame = cap.read()
352
- if not success:
353
- st.error("Unable to access the camera. Please check your camera connection.")
354
- st.session_state.run_app = False
355
- break
356
-
357
- frame_count += 1
358
-
359
- # Skip frames based on the user-configured interval
360
- if frame_count % skip_frames != 0:
361
- continue
362
-
363
- # Flip the frame horizontally for a mirror-like view
364
- frame = cv2.flip(frame, 1)
365
-
366
- # Resize the frame to the selected resolution
367
- frame = cv2.resize(frame, (res_width, res_height))
368
-
369
- # Convert the frame to RGB for processing by MediaPipe
370
- frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
371
-
372
  # Perform hand landmark detection
373
  hand_results = hands.process(frame_rgb)
374
 
375
- # Prepare frame for gesture recognition
376
- mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame)
377
- current_time_ms = int((time.time() - start_time) * 1000)
378
-
379
- # Perform asynchronous gesture recognition
380
- recognizer.recognize_async(mp_image, current_time_ms)
381
-
382
- # Draw hand landmarks on the frame
383
  if hand_results.multi_hand_landmarks:
384
  for hand_landmarks in hand_results.multi_hand_landmarks:
385
  mp_drawing.draw_landmarks(
@@ -389,45 +305,41 @@ if st.session_state.run_app:
389
  mp_drawing_styles.get_default_hand_landmarks_style(),
390
  mp_drawing_styles.get_default_hand_connections_style(),
391
  )
 
 
 
 
 
 
 
 
 
 
 
392
 
393
- # Process gesture results from the queue
394
- while not gesture_queue.empty():
395
- results = gesture_queue.get()
396
- if results:
397
- new_gesture = results[-1]
398
-
399
- # Extract gesture label and confidence
400
- if " (Confidence: " in new_gesture:
401
- label, confidence = new_gesture.split(" (Confidence: ")
402
- confidence = confidence.rstrip(")")
403
- else:
404
- label = new_gesture
405
- confidence = "N/A"
406
-
407
- # Add gesture to history if not already logged
408
- if label.isalpha() and new_gesture not in st.session_state.recognized_gestures:
409
- st.session_state.recognized_gestures.append(new_gesture)
410
-
411
- # Update current gesture display
412
- current_gesture_box.markdown(
413
- f"<h4 style='text-align: center; color: #4CAF50;'>Gesture: {label}<br>Confidence: {confidence}</h4>",
414
- unsafe_allow_html=True,
415
- )
416
-
417
- # Update gesture history display
418
- gesture_history_box.text_area(
419
- "Gesture History:",
420
- value="\n".join(reversed(st.session_state.recognized_gestures)),
421
- height=300,
422
- disabled=True,
423
- )
424
-
425
- # Display the processed frame with landmarks and gesture details
426
- video_placeholder.image(frame, channels="BGR", caption="Gesture & Hand Landmark Detection", use_column_width=True)
427
-
428
- # Release the video capture resource
429
- cap.release()
430
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
 
432
 
433
 
 
209
 
210
 
211
 
212
+
213
+
214
  import streamlit as st
215
  import mediapipe as mp
216
  import cv2
217
+ import numpy as np
218
  import os
 
 
219
  from utils import display_gesture_chart
220
 
221
  # Initialize MediaPipe Hands for hand landmark detection
 
237
  if not os.path.exists(model_path):
238
  raise FileNotFoundError(f"Model file not found at {model_path}")
239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  # Initialize session state for saving recognized gestures
241
  if "recognized_gestures" not in st.session_state:
242
  st.session_state.recognized_gestures = []
 
262
  gesture_chart_path = "./gestureReference.png" # Update this with the actual path to the image
263
  display_gesture_chart(gesture_chart_path)
264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  # Clear gesture history button
266
  if st.sidebar.button("🚲 Clear History"):
267
  st.session_state.recognized_gestures = []
268
 
269
+ # Layout with columns: Webcam input on the left, gesture log box on the right
270
  col_feed, col_log = st.columns([5, 2])
271
 
272
  with col_feed:
273
+ st.markdown("### Webcam Input")
274
+ # Use st.camera_input() to capture an image from the browser-based webcam
275
+ image_data = st.camera_input("Take a picture using your webcam")
276
+
277
+ if image_data:
278
+ # Read the image as a numpy array
279
+ file_bytes = np.asarray(bytearray(image_data.read()), dtype=np.uint8)
280
+ frame = cv2.imdecode(file_bytes, 1)
281
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
282
+
283
+ # Configure Gesture Recognizer
284
+ options = GestureRecognizerOptions(
285
+ base_options=BaseOptions(model_asset_path=model_path),
286
+ running_mode=VisionRunningMode.IMAGE # Use IMAGE mode for single-frame processing
287
+ )
288
+
289
+ # Initialize MediaPipe Gesture Recognizer
290
+ with GestureRecognizer.create_from_options(options) as recognizer, mp_hands.Hands(
291
+ model_complexity=1,
292
+ min_detection_confidence=0.5,
293
+ min_tracking_confidence=0.5,
294
+ ) as hands:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  # Perform hand landmark detection
296
  hand_results = hands.process(frame_rgb)
297
 
298
+ # Recognize gestures if landmarks are detected
 
 
 
 
 
 
 
299
  if hand_results.multi_hand_landmarks:
300
  for hand_landmarks in hand_results.multi_hand_landmarks:
301
  mp_drawing.draw_landmarks(
 
305
  mp_drawing_styles.get_default_hand_landmarks_style(),
306
  mp_drawing_styles.get_default_hand_connections_style(),
307
  )
308
+ st.image(frame, channels="BGR", caption="Processed Image with Landmarks")
309
+
310
+ # Prepare frame for gesture recognition
311
+ mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame_rgb)
312
+ recognizer_result = recognizer.recognize(mp_image)
313
+
314
+ if recognizer_result.gestures:
315
+ for hand_gestures in recognizer_result.gestures:
316
+ for gesture in hand_gestures:
317
+ label = gesture.category_name
318
+ confidence = f"{gesture.score:.2f}"
319
 
320
+ # Add gesture to history
321
+ if label not in st.session_state.recognized_gestures:
322
+ st.session_state.recognized_gestures.append(f"{label} (Confidence: {confidence})")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
 
324
+ with col_log:
325
+ st.markdown("### Gesture History")
326
+ gesture_history_box = st.text_area(
327
+ "Recognized Gestures:",
328
+ value="\n".join(reversed(st.session_state.recognized_gestures)),
329
+ height=300,
330
+ disabled=True,
331
+ )
332
+
333
+ # Footer with branding
334
+ st.sidebar.markdown(
335
+ """
336
+ <style>
337
+ .footer {text-align: center; font-size: 12px; color: grey; margin-top: 20px;}
338
+ </style>
339
+ <p class="footer">Made by Marco Chen, William Taka, Rigoberto Ponce using Streamlit, MediaPipe & OpenCV</p>
340
+ """,
341
+ unsafe_allow_html=True,
342
+ )
343
 
344
 
345