vertalius commited on
Commit
0684bfb
·
verified ·
1 Parent(s): aca8878

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -61
app.py CHANGED
@@ -5,7 +5,17 @@ import tempfile
5
  from typing import Optional, Tuple
6
  from datetime import datetime
7
  from PIL import Image
8
- from streamlit_drawable_canvas import st_canvas
 
 
 
 
 
 
 
 
 
 
9
 
10
  from pose_detector import PoseDetector
11
  from skeleton_generator import SkeletonGenerator
@@ -76,7 +86,7 @@ def init_page():
76
  st.session_state.manual_correction = st.sidebar.checkbox("Enable Manual Corrections", value=st.session_state.manual_correction)
77
 
78
  if st.session_state.manual_correction:
79
- st.sidebar.info("Click on the preview canvas to select a joint")
80
 
81
  st.title("Pose Detection & Animation Generator")
82
  return confidence_threshold
@@ -141,7 +151,7 @@ def main():
141
  db.close()
142
 
143
  def process_image_upload(uploaded_file, components, processed_file, db, col1, col2):
144
- """Handle image file upload processing with persistent state and interactive joint selection."""
145
  pose_detector, skeleton_generator, animation_exporter = components
146
 
147
  # Сохраняем исходное изображение в session_state
@@ -174,66 +184,68 @@ def process_image_upload(uploaded_file, components, processed_file, db, col1, co
174
  processed_rgb = cv2.cvtColor(processed_image, cv2.COLOR_BGR2RGB)
175
  pil_image = Image.fromarray(processed_rgb)
176
 
177
- # Отображаем изображение через st_canvas, чтобы можно было кликать по нему.
178
- canvas_result = st_canvas(
179
- fill_color="rgba(0, 0, 0, 0)", # прозрачный фон для рисования
180
- stroke_width=5,
181
- stroke_color="#FF0000",
182
- background_image=pil_image,
183
- update_streamlit=True,
184
- height=height,
185
- width=width,
186
- drawing_mode="point", # режим для регистрации кликов
187
- key="canvas"
188
- )
189
-
190
- # Если пользователь сделал клик, в canvas_result.json_data появятся объекты.
191
- if st.session_state.get('manual_correction', False) and canvas_result.json_data is not None:
192
- objects = canvas_result.json_data.get("objects", [])
193
- if objects:
194
- # Берём последний добавленный объект как клик.
195
- last_obj = objects[-1]
196
- click_x = last_obj.get("left")
197
- click_y = last_obj.get("top")
198
-
199
- # Находим ближайший joint (учитывая, что координаты суставов нормализованы)
200
- min_dist = float("inf")
201
- selected_joint = None
202
- for joint_name, data in skeleton_data.items():
203
- joint_px = data['position'][0] * width
204
- joint_py = data['position'][1] * height
205
- dist = ((joint_px - click_x)**2 + (joint_py - click_y)**2)**0.5
206
- if dist < min_dist:
207
- min_dist = dist
208
- selected_joint = joint_name
209
- threshold = 20 # порог в пикселях для выбора сустава
210
- if min_dist < threshold:
211
- st.session_state.active_joint = selected_joint
212
- st.write(f"Selected joint: **{selected_joint}**")
213
- else:
214
- st.write("Click closer to a joint to select it.")
215
-
216
- # Если активный joint выбран, показываем слайдеры для его корректировки.
217
- if st.session_state.get("active_joint"):
218
- active_joint = st.session_state.active_joint
219
- joints = st.session_state.get("current_landmarks", skeleton_data.copy())
220
- st.write(f"Active joint for adjustment: **{active_joint}**")
221
- x_pos = st.slider("Adjust X", 0.0, 1.0, float(joints[active_joint]['position'][0]), 0.01, key=f"adj_x_{active_joint}")
222
- y_pos = st.slider("Adjust Y", 0.0, 1.0, float(joints[active_joint]['position'][1]), 0.01, key=f"adj_y_{active_joint}")
223
- if st.button("Apply Adjustment", key=f"apply_adj_{active_joint}"):
224
- joints[active_joint]['position'] = [x_pos, y_pos]
225
- st.session_state.current_landmarks = joints
226
- corrected_image = pose_detector.draw_corrected_pose(image, joints)
227
- st.session_state.processed_image = corrected_image
228
- corrected_rgb = cv2.cvtColor(corrected_image, cv2.COLOR_BGR2RGB)
229
- st.image(corrected_rgb, use_column_width=True)
230
- st.write(f"Updated {active_joint}: {joints[active_joint]['position']}")
231
- if st.button("Save Corrections", key=f"save_adj_{active_joint}"):
232
- save_corrected_pose(db, processed_file.id, joints)
233
- st.success("Corrections saved successfully!")
 
 
234
 
235
  def process_video_upload(uploaded_file, components, processed_file, db, is_gif, col1, col2):
236
- """Handle video/GIF file upload processing."""
237
  pose_detector, skeleton_generator, animation_exporter = components
238
  progress_bar = st.progress(0)
239
 
 
5
  from typing import Optional, Tuple
6
  from datetime import datetime
7
  from PIL import Image
8
+
9
+ # Попытка импортировать st_canvas; если не установлен, интерактивный режим будет отключён.
10
+ try:
11
+ from streamlit_drawable_canvas import st_canvas
12
+ canvas_available = True
13
+ except ImportError:
14
+ canvas_available = False
15
+ st.warning(
16
+ "Интерактивное редактирование отключено, так как модуль streamlit-drawable-canvas не установлен. "
17
+ "Для его использования добавьте 'streamlit-drawable-canvas' в зависимости."
18
+ )
19
 
20
  from pose_detector import PoseDetector
21
  from skeleton_generator import SkeletonGenerator
 
86
  st.session_state.manual_correction = st.sidebar.checkbox("Enable Manual Corrections", value=st.session_state.manual_correction)
87
 
88
  if st.session_state.manual_correction:
89
+ st.sidebar.info("Интерактивное редактирование доступно" + (" (с использованием canvas)" if canvas_available else " (canvas не доступен)"))
90
 
91
  st.title("Pose Detection & Animation Generator")
92
  return confidence_threshold
 
151
  db.close()
152
 
153
  def process_image_upload(uploaded_file, components, processed_file, db, col1, col2):
154
+ """Обработка изображения с сохранением состояния и интерактивным выбором сустава (если canvas доступен)."""
155
  pose_detector, skeleton_generator, animation_exporter = components
156
 
157
  # Сохраняем исходное изображение в session_state
 
184
  processed_rgb = cv2.cvtColor(processed_image, cv2.COLOR_BGR2RGB)
185
  pil_image = Image.fromarray(processed_rgb)
186
 
187
+ if canvas_available and st.session_state.get('manual_correction', False):
188
+ # Используем st_canvas для интерактивного редактирования
189
+ canvas_result = st_canvas(
190
+ fill_color="rgba(0, 0, 0, 0)", # прозрачный фон для рисования
191
+ stroke_width=5,
192
+ stroke_color="#FF0000",
193
+ background_image=pil_image,
194
+ update_streamlit=True,
195
+ height=height,
196
+ width=width,
197
+ drawing_mode="point", # режим для регистрации кликов
198
+ key="canvas"
199
+ )
200
+
201
+ if canvas_result.json_data is not None:
202
+ objects = canvas_result.json_data.get("objects", [])
203
+ if objects:
204
+ last_obj = objects[-1]
205
+ click_x = last_obj.get("left")
206
+ click_y = last_obj.get("top")
207
+
208
+ # Находим ближайший joint (координаты нормализованы)
209
+ min_dist = float("inf")
210
+ selected_joint = None
211
+ for joint_name, data in skeleton_data.items():
212
+ joint_px = data['position'][0] * width
213
+ joint_py = data['position'][1] * height
214
+ dist = ((joint_px - click_x)**2 + (joint_py - click_y)**2)**0.5
215
+ if dist < min_dist:
216
+ min_dist = dist
217
+ selected_joint = joint_name
218
+ threshold = 20 # порог в пикселях для выбора сустава
219
+ if min_dist < threshold:
220
+ st.session_state.active_joint = selected_joint
221
+ st.write(f"Selected joint: **{selected_joint}**")
222
+ else:
223
+ st.write("Click closer to a joint to select it.")
224
+
225
+ if st.session_state.get("active_joint"):
226
+ active_joint = st.session_state.active_joint
227
+ joints = st.session_state.get("current_landmarks", skeleton_data.copy())
228
+ st.write(f"Active joint for adjustment: **{active_joint}**")
229
+ x_pos = st.slider("Adjust X", 0.0, 1.0, float(joints[active_joint]['position'][0]), 0.01, key=f"adj_x_{active_joint}")
230
+ y_pos = st.slider("Adjust Y", 0.0, 1.0, float(joints[active_joint]['position'][1]), 0.01, key=f"adj_y_{active_joint}")
231
+ if st.button("Apply Adjustment", key=f"apply_adj_{active_joint}"):
232
+ joints[active_joint]['position'] = [x_pos, y_pos]
233
+ st.session_state.current_landmarks = joints
234
+ corrected_image = pose_detector.draw_corrected_pose(image, joints)
235
+ st.session_state.processed_image = corrected_image
236
+ corrected_rgb = cv2.cvtColor(corrected_image, cv2.COLOR_BGR2RGB)
237
+ st.image(corrected_rgb, use_column_width=True)
238
+ st.write(f"Updated {active_joint}: {joints[active_joint]['position']}")
239
+ if st.button("Save Corrections", key=f"save_adj_{active_joint}"):
240
+ save_corrected_pose(db, processed_file.id, joints)
241
+ st.success("Corrections saved successfully!")
242
+ else:
243
+ # Если canvas недоступен, выводим просто изображение и сообщение
244
+ st.image(processed_rgb, use_column_width=True)
245
+ st.info("Интерактивное редактирование недоступно, так как streamlit-drawable-canvas не установлен.")
246
 
247
  def process_video_upload(uploaded_file, components, processed_file, db, is_gif, col1, col2):
248
+ """Обработка видео/GIF файлов."""
249
  pose_detector, skeleton_generator, animation_exporter = components
250
  progress_bar = st.progress(0)
251