Kanompung commited on
Commit
256e92e
·
verified ·
1 Parent(s): 2c5b936

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -138
app.py CHANGED
@@ -11,9 +11,6 @@ import uuid
11
  from openai import OpenAI
12
  import os
13
  from dotenv import load_dotenv
14
- import requests
15
- import queue
16
- import threading
17
 
18
  load_dotenv()
19
 
@@ -139,8 +136,6 @@ ACTION_COLS = [
139
  'Decreasing Pressure', 'Acceleration', 'Decelerating'
140
  ]
141
 
142
- api_results_queue = queue.Queue()
143
-
144
  recording = False
145
  recording_thread = None
146
 
@@ -155,60 +150,14 @@ def parse_time_str(tstr):
155
  return m * 60 + s
156
 
157
  def send_to_api(file_path, start_sec, end_sec, actions):
158
- """Send video file to API for prediction"""
159
  print(f"📤 Sending {file_path} to API...")
160
  print(f"⏱ Clip time: {start_sec}-{end_sec} sec")
161
- #print(f"📝 Actions in this clip: {actions}")
162
-
163
- # Fix URL format - add http:// protocol
164
- url = "http://172.16.30.129:8000/predict"
165
-
166
- try:
167
- # Prepare the file and timestamp
168
- with open(file_path, 'rb') as file:
169
- files = {'file': file}
170
-
171
- # Convert start_sec to timestamp format expected by server
172
- # Assuming timestamp should be in "MM:SS" format or seconds
173
- timestamp = str(int(start_sec)) # or format_time(start_sec) if MM:SS format needed
174
-
175
- data = {'timestamp': timestamp}
176
-
177
- # Make the POST request
178
- response = requests.post(url, files=files, data=data, timeout=30)
179
-
180
- if response.status_code == 200:
181
- result = response.json()
182
- print("✅ API Response:")
183
- print(f" Timestamp: {result['timestamp']}")
184
- print(f" Predicted Actions: {result['actions']}")
185
- # print(f" Probabilities: {result['probabilities']}")
186
- return result
187
- else:
188
- print(f"❌ API Error: {response.status_code}")
189
- print(f" Error message: {response.text}")
190
- return None
191
-
192
- except requests.exceptions.ConnectionError:
193
- print("❌ Connection Error: Could not connect to the API server")
194
- return None
195
- except requests.exceptions.Timeout:
196
- print("❌ Timeout Error: Request took too long")
197
- return None
198
- except requests.exceptions.RequestException as e:
199
- print(f"❌ Request Error: {e}")
200
- return None
201
- except FileNotFoundError:
202
- print(f"❌ File Error: Could not find file {file_path}")
203
- return None
204
- except Exception as e:
205
- print(f"❌ Unexpected Error: {e}")
206
- return None
207
 
208
- def record_video(actions_state_snapshot, is_recording, recording_start_time):
209
- global recording, api_results_queue
210
  cap = cv2.VideoCapture(0)
211
- fps = 30
212
  width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
213
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
214
 
@@ -231,62 +180,17 @@ def record_video(actions_state_snapshot, is_recording, recording_start_time):
231
  clip_idx += 1
232
 
233
  actions_in_clip = []
234
- for item in actions_state_snapshot:
235
  t_sec = parse_time_str(item["timestamp"])
236
  if elapsed_start <= t_sec < elapsed_end:
237
  actions_in_clip.extend(item["actions"])
238
  actions_in_clip = list(set(actions_in_clip))
239
 
240
  if recording:
241
- result = send_to_api(filename, elapsed_start, elapsed_end, actions_in_clip)
242
- # Put result in queue instead of directly modifying state
243
- new_item = {
244
- "id": str(uuid.uuid4()),
245
- "timestamp": format_time(elapsed_start),
246
- "actions": actions_in_clip,
247
- "result": result
248
- }
249
- api_results_queue.put(new_item)
250
 
251
  cap.release()
252
 
253
- def extract_actions_from_api_result(api_result):
254
- """Extract action names from API result based on the PredictionResponse structure"""
255
- if not api_result or 'actions' not in api_result:
256
- return []
257
-
258
- # api_result['actions'] is a Dict[str, int] where 1 means the action is detected
259
- detected_actions = []
260
- for action_name, is_detected in api_result['actions'].items():
261
- if is_detected == 1:
262
- detected_actions.append(action_name)
263
-
264
- return detected_actions
265
-
266
- def check_api_results(actions_state):
267
- """Check for new API results and update the state"""
268
- global api_results_queue
269
- updated = False
270
-
271
- while not api_results_queue.empty():
272
- try:
273
- new_item = api_results_queue.get_nowait()
274
- # Extract the actual detected actions from the API result
275
- if new_item.get('result'):
276
- detected_actions = extract_actions_from_api_result(new_item['result'])
277
- new_item['actions'] = detected_actions
278
-
279
- actions_state.append(new_item)
280
- updated = True
281
- print(f"✅ Added API result to table: {new_item['timestamp']} - Actions: {new_item['actions']}")
282
- except queue.Empty:
283
- break
284
-
285
- if updated:
286
- return actions_state, render_table(actions_state, None)
287
- else:
288
- return actions_state, gr.update()
289
-
290
  def toggle_recording(state, is_recording, recording_start_time, actions_state, accept_visible):
291
  global recording, recording_thread
292
  if state == "Start":
@@ -331,23 +235,19 @@ def render_table(actions_state, edit_index):
331
  wrap=True
332
  )
333
 
334
- def start_edit(idx, actions_state):
335
  try:
336
  idx = int(idx)
337
  if 0 <= idx < len(actions_state):
338
- return idx, actions_state[idx]["actions"]
 
 
 
339
  else:
340
- return None, []
341
  except Exception:
342
- return None, []
343
-
344
- def save_edit(idx, new_actions, actions_state):
345
- if idx is not None and 0 <= idx < len(actions_state):
346
- actions_state[idx]["actions"] = new_actions
347
- return None, None, actions_state
348
 
349
- def cancel_edit():
350
- return None, None
351
 
352
  def clean_markdown_response(response_text):
353
  """Clean markdown code block markers from LLM response"""
@@ -393,7 +293,7 @@ def LLM_Summarize(actions_state):
393
 
394
 
395
  response = client.chat.completions.create(
396
- model="gpt-4o-mini", # Updated to use GPT-4o mini
397
  messages=[
398
  {"role": "system", "content": SYSTEM_PROMPT},
399
  {"role": "user", "content": f"Here is the CSV data to analyze:\n\n{csv_data}"}
@@ -633,40 +533,25 @@ def main():
633
 
634
  # Edit functionality
635
  with gr.Row():
636
- edit_row = gr.Number(label="📝 Edit Row (0-based)", precision=0)
637
- edit_multiselect = gr.CheckboxGroup(choices=ACTION_COLS, label="แก้ไข Actions")
638
- save_btn = gr.Button("💾 Save Edit")
639
- cancel_btn = gr.Button("❌ Cancel Edit")
640
 
641
  edit_row.change(
642
- start_edit,
643
  inputs=[edit_row, actions_state],
644
- outputs=[edit_index, edit_multiselect]
645
  )
646
 
647
- save_btn.click(
648
- save_edit,
649
- inputs=[edit_index, edit_multiselect, actions_state],
 
650
  outputs=[edit_index, edit_multiselect, actions_state]
651
  ).then(
652
  render_table,
653
  inputs=[actions_state, edit_index],
654
  outputs=actions_table
655
- )
656
-
657
- cancel_btn.click(
658
- cancel_edit,
659
- outputs=[edit_index, edit_multiselect]
660
- )
661
-
662
- api_check_timer = gr.Timer(value=0.5) # Check every 0.5 seconds
663
-
664
- api_check_timer.tick(
665
- check_api_results,
666
- inputs=[actions_state],
667
- outputs=[actions_state, actions_table]
668
- )
669
-
670
  demo.launch()
671
 
672
  if __name__ == "__main__":
 
11
  from openai import OpenAI
12
  import os
13
  from dotenv import load_dotenv
 
 
 
14
 
15
  load_dotenv()
16
 
 
136
  'Decreasing Pressure', 'Acceleration', 'Decelerating'
137
  ]
138
 
 
 
139
  recording = False
140
  recording_thread = None
141
 
 
150
  return m * 60 + s
151
 
152
  def send_to_api(file_path, start_sec, end_sec, actions):
 
153
  print(f"📤 Sending {file_path} to API...")
154
  print(f"⏱ Clip time: {start_sec}-{end_sec} sec")
155
+ print(f"📝 Actions in this clip: {actions}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
+ def record_video(actions_state, is_recording, recording_start_time):
158
+ global recording
159
  cap = cv2.VideoCapture(0)
160
+ fps = int(cap.get(cv2.CAP_PROP_FPS) or 24)
161
  width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
162
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
163
 
 
180
  clip_idx += 1
181
 
182
  actions_in_clip = []
183
+ for item in actions_state:
184
  t_sec = parse_time_str(item["timestamp"])
185
  if elapsed_start <= t_sec < elapsed_end:
186
  actions_in_clip.extend(item["actions"])
187
  actions_in_clip = list(set(actions_in_clip))
188
 
189
  if recording:
190
+ send_to_api(filename, elapsed_start, elapsed_end, actions_in_clip)
 
 
 
 
 
 
 
 
191
 
192
  cap.release()
193
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  def toggle_recording(state, is_recording, recording_start_time, actions_state, accept_visible):
195
  global recording, recording_thread
196
  if state == "Start":
 
235
  wrap=True
236
  )
237
 
238
+ def start_edit(idx, actions_state, new_actions=None):
239
  try:
240
  idx = int(idx)
241
  if 0 <= idx < len(actions_state):
242
+ # ถ้ามี new_actions ให้บันทึกเลย
243
+ if new_actions is not None:
244
+ actions_state[idx]["actions"] = new_actions
245
+ return idx, actions_state[idx]["actions"], actions_state
246
  else:
247
+ return None, [], actions_state
248
  except Exception:
249
+ return None, [], actions_state
 
 
 
 
 
250
 
 
 
251
 
252
  def clean_markdown_response(response_text):
253
  """Clean markdown code block markers from LLM response"""
 
293
 
294
 
295
  response = client.chat.completions.create(
296
+ model="typhoon-v2.1-12b-instruct", # Updated to use Typhoon model
297
  messages=[
298
  {"role": "system", "content": SYSTEM_PROMPT},
299
  {"role": "user", "content": f"Here is the CSV data to analyze:\n\n{csv_data}"}
 
533
 
534
  # Edit functionality
535
  with gr.Row():
536
+ edit_row = gr.Number(label="📝 Edit Row (0-based)", precision=0)
537
+ edit_multiselect = gr.CheckboxGroup(choices=ACTION_COLS, label="แก้ไข Actions")
 
 
538
 
539
  edit_row.change(
540
+ lambda idx, actions_state: start_edit(idx, actions_state),
541
  inputs=[edit_row, actions_state],
542
+ outputs=[edit_index, edit_multiselect, actions_state]
543
  )
544
 
545
+ # เมื่อแก้ไข multiselect ให้บันทึกอัตโนมัติ
546
+ edit_multiselect.change(
547
+ lambda new_actions, edit_index, actions_state: start_edit(edit_index, actions_state, new_actions),
548
+ inputs=[edit_multiselect, edit_index, actions_state],
549
  outputs=[edit_index, edit_multiselect, actions_state]
550
  ).then(
551
  render_table,
552
  inputs=[actions_state, edit_index],
553
  outputs=actions_table
554
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  demo.launch()
556
 
557
  if __name__ == "__main__":