RP-Azul commited on
Commit
d8e3daf
·
verified ·
1 Parent(s): ccc2b4d

Upload 2 files

Browse files
Files changed (3) hide show
  1. .gitattributes +1 -0
  2. gesture_recognizer.task +3 -0
  3. main.py +348 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ gesture_recognizer.task filter=lfs diff=lfs merge=lfs -text
gesture_recognizer.task ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:13aa0bd33974391c1b8d31e5cf77e29df346f3633781c49d7d307bdf8f2de85b
3
+ size 8764485
main.py ADDED
@@ -0,0 +1,348 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # without hand landmarking
2
+ # import streamlit as st
3
+ # import mediapipe as mp
4
+ # import cv2
5
+ # import os
6
+ # import time
7
+ # from queue import Queue
8
+
9
+ # # Import necessary components from MediaPipe
10
+ # BaseOptions = mp.tasks.BaseOptions
11
+ # GestureRecognizer = mp.tasks.vision.GestureRecognizer
12
+ # GestureRecognizerOptions = mp.tasks.vision.GestureRecognizerOptions
13
+ # GestureRecognizerResult = mp.tasks.vision.GestureRecognizerResult
14
+ # VisionRunningMode = mp.tasks.vision.RunningMode
15
+
16
+ # # Correct path to the Gesture Recognizer model file
17
+ # model_path = './model/model/gesture_recognizer.task'
18
+
19
+ # # Check if file exists
20
+ # if not os.path.exists(model_path):
21
+ # raise FileNotFoundError(f"Model file not found at {model_path}")
22
+
23
+ # # Queue to share results between the callback and main thread
24
+ # gesture_queue = Queue()
25
+
26
+ # # Callback function to process results and add them to the queue
27
+ # def print_result(result: GestureRecognizerResult, output_image: mp.Image, timestamp_ms: int):
28
+ # results = [] # Collect gesture results
29
+ # if result.gestures:
30
+ # for hand_gestures in result.gestures:
31
+ # for gesture in hand_gestures:
32
+ # results.append(f"Gesture: **{gesture.category_name}**, Confidence: **{gesture.score:.2f}**")
33
+ # else:
34
+ # results.append("No gestures detected.")
35
+ # gesture_queue.put(results)
36
+
37
+ # # Configure the Gesture Recognizer
38
+ # options = GestureRecognizerOptions(
39
+ # base_options=BaseOptions(model_asset_path=model_path),
40
+ # running_mode=VisionRunningMode.LIVE_STREAM,
41
+ # result_callback=print_result
42
+ # )
43
+
44
+ # # Custom App Header
45
+ # st.markdown("<h1 style='text-align: center; color: #4CAF50;'>Gesture Recognition App 🚀</h1>", unsafe_allow_html=True)
46
+ # st.markdown("<p style='text-align: center; color: grey;'>Recognize hand gestures in real time with MediaPipe and Streamlit</p>", unsafe_allow_html=True)
47
+
48
+ # # Sidebar for User Controls
49
+ # st.sidebar.title("Control Panel")
50
+ # run_app = st.sidebar.button("Start Gesture Recognition")
51
+ # st.sidebar.write("Toggle the button above to start the app.")
52
+
53
+ # # Placeholder for video feed and results
54
+ # video_placeholder = st.empty() # Placeholder for the video feed
55
+ # result_placeholder = st.empty() # Placeholder for gesture results
56
+
57
+ # # Footer with branding
58
+ # st.sidebar.markdown(
59
+ # "<hr><p style='text-align: center;'>Made with ❤️ using Streamlit</p>", unsafe_allow_html=True
60
+ # )
61
+
62
+ # if run_app:
63
+ # st.markdown("<h2 style='text-align: center;'>Processing Video Feed...</h2>", unsafe_allow_html=True)
64
+ # cap = cv2.VideoCapture(0)
65
+
66
+ # # Initialize a monotonically increasing timestamp
67
+ # start_time = time.time()
68
+
69
+ # with GestureRecognizer.create_from_options(options) as recognizer:
70
+ # while cap.isOpened():
71
+ # success, frame = cap.read()
72
+ # if not success:
73
+ # st.warning("No frames available from the video feed.")
74
+ # break
75
+
76
+ # # Compute the current timestamp in milliseconds
77
+ # current_time_ms = int((time.time() - start_time) * 1000)
78
+
79
+ # # Convert frame to a MediaPipe Image
80
+ # mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame)
81
+
82
+ # # Perform gesture recognition asynchronously
83
+ # recognizer.recognize_async(mp_image, current_time_ms)
84
+
85
+ # # Display the frame in Streamlit
86
+ # frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
87
+ # video_placeholder.image(frame_rgb, channels="RGB", caption="Gesture Recognition", use_column_width=True)
88
+
89
+ # # Retrieve and display gesture results from the queue
90
+ # while not gesture_queue.empty():
91
+ # results = gesture_queue.get()
92
+ # result_placeholder.markdown(
93
+ # "<h3 style='text-align: center; color: #FF5722;'>Detected Gestures</h3>",
94
+ # unsafe_allow_html=True,
95
+ # )
96
+ # result_placeholder.markdown(
97
+ # "<ul>" + "".join([f"<li>{result}</li>" for result in results]) + "</ul>",
98
+ # unsafe_allow_html=True,
99
+ # )
100
+
101
+ # cap.release()
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+ # with hand landmark
131
+ import streamlit as st
132
+ import mediapipe as mp
133
+ import cv2
134
+ import os
135
+ import time
136
+ from queue import Queue
137
+
138
+ # Initialize MediaPipe Hands for hand landmark detection
139
+ mp_hands = mp.solutions.hands
140
+ mp_drawing = mp.solutions.drawing_utils
141
+ mp_drawing_styles = mp.solutions.drawing_styles
142
+
143
+ # Import necessary components from MediaPipe Gesture Recognizer
144
+ BaseOptions = mp.tasks.BaseOptions
145
+ GestureRecognizer = mp.tasks.vision.GestureRecognizer
146
+ GestureRecognizerOptions = mp.tasks.vision.GestureRecognizerOptions
147
+ GestureRecognizerResult = mp.tasks.vision.GestureRecognizerResult
148
+ VisionRunningMode = mp.tasks.vision.RunningMode
149
+
150
+ # Correct path to the Gesture Recognizer model file
151
+ model_path = './model/model/gesture_recognizer.task'
152
+
153
+ # Check if file exists
154
+ if not os.path.exists(model_path):
155
+ raise FileNotFoundError(f"Model file not found at {model_path}")
156
+
157
+ # Queue to share results between the callback and main thread
158
+ gesture_queue = Queue()
159
+
160
+ # Callback function to process gesture results and add them to the queue
161
+ def print_result(result: GestureRecognizerResult, output_image: mp.Image, timestamp_ms: int):
162
+ results = [] # Collect gesture results
163
+ if result.gestures:
164
+ for hand_gestures in result.gestures:
165
+ for gesture in hand_gestures:
166
+ results.append(f"{gesture.category_name} (Confidence: {gesture.score:.2f})") # Include confidence
167
+ else:
168
+ results.append("No gestures detected.")
169
+ gesture_queue.put(results)
170
+
171
+ # Configure the Gesture Recognizer
172
+ options = GestureRecognizerOptions(
173
+ base_options=BaseOptions(model_asset_path=model_path),
174
+ running_mode=VisionRunningMode.LIVE_STREAM,
175
+ result_callback=print_result
176
+ )
177
+
178
+ # Initialize session state for saving gestures
179
+ if "recognized_gestures" not in st.session_state:
180
+ st.session_state.recognized_gestures = []
181
+
182
+ # Custom App Header
183
+ st.markdown(
184
+ """
185
+ <style>
186
+ .header {text-align: center; color: #4CAF50; margin-top: -50px;}
187
+ .description {text-align: center; color: grey; font-size: 16px;}
188
+ </style>
189
+ <h1 class="header">Gesture & Hand Landmark Detection 🚀</h1>
190
+ <p class="description">Recognize and save hand gestures in real time with MediaPipe.</p>
191
+ """,
192
+ unsafe_allow_html=True,
193
+ )
194
+
195
+ # Sidebar for User Controls
196
+ st.sidebar.title("Control Panel")
197
+ st.sidebar.markdown("<hr>", unsafe_allow_html=True)
198
+
199
+ max_num_hands = st.sidebar.slider("Max Number of Hands", 1, 2, 1)
200
+ skip_frames = st.sidebar.slider("Process Every Nth Frame", 1, 10, 5)
201
+ resolution = st.sidebar.selectbox("Frame Resolution", ["320x240", "640x480"], index=0)
202
+
203
+ st.sidebar.markdown("<hr>", unsafe_allow_html=True)
204
+
205
+ # Start and Stop buttons
206
+ if "run_app" not in st.session_state:
207
+ st.session_state.run_app = False
208
+
209
+ col1, col2 = st.sidebar.columns(2)
210
+ if col1.button("▶ Start"):
211
+ st.session_state.run_app = True
212
+
213
+ if col2.button("⏹ Stop"):
214
+ st.session_state.run_app = False
215
+
216
+ # Clear history button
217
+ if st.sidebar.button("🗑️ Clear History"):
218
+ st.session_state.recognized_gestures = []
219
+
220
+ # Layout with columns: Live camera feed on the left, gesture log box on the right
221
+ col_feed, col_log = st.columns([3, 2])
222
+
223
+ with col_feed:
224
+ st.markdown("### Live Camera Feed")
225
+ video_placeholder = st.empty() # Placeholder for the video feed
226
+
227
+ with col_log:
228
+ st.markdown("### Gesture Log")
229
+ current_gesture_box = st.empty() # Box to display the most recent gesture dynamically
230
+ st.markdown("### Gesture History")
231
+ gesture_history_box = st.empty() # Box to display all recognized gestures dynamically
232
+
233
+ # Footer with branding
234
+ st.sidebar.markdown(
235
+ """
236
+ <style>
237
+ .footer {text-align: center; font-size: 12px; color: grey; margin-top: 20px;}
238
+ </style>
239
+ <p class="footer">Made by Marco Chen, William Taka, Rigoberto Ponce using Streamlit, MediaPipe & OpenCV</p>
240
+ """,
241
+ unsafe_allow_html=True,
242
+ )
243
+
244
+ if st.session_state.run_app:
245
+ cap = cv2.VideoCapture(0)
246
+
247
+ # Parse resolution
248
+ res_width, res_height = map(int, resolution.split("x"))
249
+
250
+ # Initialize a monotonically increasing timestamp
251
+ start_time = time.time()
252
+
253
+ with GestureRecognizer.create_from_options(options) as recognizer, mp_hands.Hands(
254
+ max_num_hands=max_num_hands,
255
+ model_complexity=0, # Simplified model for performance
256
+ min_detection_confidence=0.3,
257
+ min_tracking_confidence=0.3
258
+ ) as hands:
259
+ frame_count = 0
260
+ while st.session_state.run_app and cap.isOpened():
261
+ success, frame = cap.read()
262
+ if not success:
263
+ st.warning("No frames available from the video feed.")
264
+ break
265
+
266
+ frame_count += 1
267
+ if frame_count % skip_frames != 0:
268
+ continue
269
+
270
+ # Flip and resize frame
271
+ frame = cv2.flip(frame, 1)
272
+ frame = cv2.resize(frame, (res_width, res_height))
273
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
274
+
275
+ # Perform hand landmark detection
276
+ hand_results = hands.process(frame_rgb)
277
+
278
+ # Perform gesture recognition
279
+ mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame)
280
+ current_time_ms = int((time.time() - start_time) * 1000)
281
+ recognizer.recognize_async(mp_image, current_time_ms)
282
+
283
+ # Draw hand landmarks on the frame
284
+ if hand_results.multi_hand_landmarks:
285
+ for hand_landmarks in hand_results.multi_hand_landmarks:
286
+ mp_drawing.draw_landmarks(
287
+ frame,
288
+ hand_landmarks,
289
+ mp_hands.HAND_CONNECTIONS,
290
+ mp_drawing_styles.get_default_hand_landmarks_style(),
291
+ mp_drawing_styles.get_default_hand_connections_style(),
292
+ )
293
+
294
+ # Retrieve and display gesture results from the queue
295
+ while not gesture_queue.empty():
296
+ results = gesture_queue.get()
297
+ if results:
298
+ new_gesture = results[-1]
299
+
300
+ # Extract label and confidence safely
301
+ if " (Confidence: " in new_gesture:
302
+ label, confidence = new_gesture.split(" (Confidence: ")
303
+ confidence = confidence.rstrip(")") # Remove the trailing parenthesis
304
+ else:
305
+ label = new_gesture
306
+ confidence = "N/A"
307
+
308
+ # Add new gesture to history only if it's not already logged
309
+ if label.isalpha() and new_gesture not in st.session_state.recognized_gestures:
310
+ st.session_state.recognized_gestures.append(new_gesture)
311
+
312
+ # Update current gesture display
313
+ current_gesture_box.markdown(
314
+ f"<h4 style='text-align: center; color: #4CAF50;'>Gesture: {label}<br>Confidence: {confidence}</h4>",
315
+ unsafe_allow_html=True,
316
+ )
317
+
318
+ # Update gesture history display
319
+ gesture_history_box.text_area(
320
+ "Gesture History:",
321
+ value="\n".join(reversed(st.session_state.recognized_gestures)),
322
+ height=300,
323
+ disabled=True,
324
+ )
325
+
326
+ # Display the frame with hand landmarks and gesture results
327
+ video_placeholder.image(frame, channels="BGR", caption="Gesture & Hand Landmark Detection", use_column_width=True)
328
+
329
+ cap.release()
330
+
331
+
332
+
333
+
334
+
335
+
336
+
337
+
338
+
339
+
340
+
341
+
342
+
343
+
344
+
345
+
346
+
347
+
348
+