Wenjiawang0312 commited on
Commit
4060232
·
1 Parent(s): 05f2d77
Files changed (1) hide show
  1. app.py +89 -187
app.py CHANGED
@@ -166,208 +166,110 @@ def create_video_survey_app():
166
  - **静态一致性** / Static Consistency: 视频中静态物体的稳定性和一致性
167
  - **整体质量** / Overall Quality: 视频的整体观感
168
  - 评分范围:1-5分(5分最好)/ Rating scale: 1-5 (5 = Best)
 
169
  """)
170
 
171
- # 状态变量
172
- current_question_idx = gr.State(0)
173
- current_method_mapping = gr.State({})
174
- all_ratings = gr.State({}) # 存储所有场景的评分
175
 
176
- # 进度显示
177
- with gr.Row():
178
- prev_btn = gr.Button("⬅️ 上一题 / Previous", size="sm")
179
- question_text = gr.Markdown(f"**场景 1 / {len(question_folders)}**")
180
- next_btn = gr.Button("下一题 / Next ➡️", size="sm", variant="primary")
181
-
182
- status_text = gr.Textbox(label="状态 / Status", interactive=False, visible=False)
183
-
184
- # 视频显示区域(4个视频)
185
- video_components = []
186
- rating_components = []
187
-
188
- for i in range(4):
189
- method_name = f"Method {chr(65+i)}"
190
 
191
  with gr.Group():
192
- gr.Markdown(f"### 🎥 {method_name}")
193
-
194
- video = gr.Video(label="", height=300)
195
- video_components.append(video)
196
 
 
197
  with gr.Row():
198
- dynamic = gr.Slider(
199
- minimum=1, maximum=5, step=1, value=3,
200
- label="动态质量 / Dynamic Quality",
201
- info="1=差 / Poor, 5=优秀 / Excellent"
202
- )
203
- static = gr.Slider(
204
- minimum=1, maximum=5, step=1, value=3,
205
- label="静态一致性 / Static Consistency",
206
- info="1=差 / Poor, 5=优秀 / Excellent"
207
- )
208
- overall = gr.Slider(
209
- minimum=1, maximum=5, step=1, value=3,
210
- label="整体质量 / Overall Quality",
211
- info="1=差 / Poor, 5=优秀 / Excellent"
212
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
- rating_components.append({
215
- "dynamic": dynamic,
216
- "static": static,
217
- "overall": overall
218
  })
219
 
220
- # 更新问题显示
221
- def update_question(question_idx, all_ratings_dict, save_previous=False, prev_ratings=None, prev_mapping=None):
222
- if question_idx < 0:
223
- question_idx = 0
224
- if question_idx >= len(question_folders):
225
- question_idx = len(question_folders) - 1
226
-
227
- # 如果需要,保存上一题的评分到字典
228
- save_msg = ""
229
- if save_previous and prev_ratings and prev_mapping:
230
- prev_idx = question_idx - 1 if question_idx > 0 else question_idx
231
- prev_scene = question_folders[prev_idx]
232
- all_ratings_dict[prev_scene] = {
233
- 'ratings': prev_ratings,
234
- 'mapping': prev_mapping
235
- }
236
-
237
- scene_name = question_folders[question_idx]
238
- videos, method_mapping = get_videos_for_question(scene_name)
239
-
240
- # 更新视频显示
241
- video_updates = []
242
- for i in range(4):
243
- method_name = f"Method {chr(65+i)}"
244
- if method_name in videos:
245
- video_updates.append(gr.update(value=videos[method_name]))
246
- else:
247
- video_updates.append(gr.update(value=None))
248
-
249
- # 检查是否有已保存的评分
250
- rating_updates = []
251
- if scene_name in all_ratings_dict:
252
- # 恢复之前的评分
253
- saved_ratings = all_ratings_dict[scene_name]['ratings']
254
- for i in range(4):
255
- method_name = f"Method {chr(65+i)}"
256
- if method_name in saved_ratings:
257
- rating_updates.append(gr.update(value=saved_ratings[method_name]['dynamic_quality']))
258
- rating_updates.append(gr.update(value=saved_ratings[method_name]['static_consistency']))
259
- rating_updates.append(gr.update(value=saved_ratings[method_name]['overall_quality']))
260
- else:
261
- rating_updates.extend([gr.update(value=3), gr.update(value=3), gr.update(value=3)])
262
- else:
263
- # 重置为默认评分
264
- rating_updates = [gr.update(value=3) for _ in range(12)] # 4个视频 x 3个评分,每个默认值为3
265
-
266
- question_markdown = f"**场景 {question_idx + 1} / {len(question_folders)}**: `{scene_name}`"
267
-
268
- return (
269
- [question_idx, method_mapping, all_ratings_dict, question_markdown, save_msg] +
270
- video_updates +
271
- rating_updates
272
- )
273
-
274
- # 收集当前评分
275
- def collect_ratings(*rating_values):
276
- ratings = {}
277
- for i in range(4):
278
- method_name = f"Method {chr(65+i)}"
279
- base_idx = i * 3
280
- ratings[method_name] = {
281
- "dynamic_quality": rating_values[base_idx],
282
- "static_consistency": rating_values[base_idx + 1],
283
- "overall_quality": rating_values[base_idx + 2]
284
- }
285
- return ratings
286
 
287
- # 下一题按钮
288
- def on_next(question_idx, method_mapping, all_ratings_dict, *rating_values):
289
- # 收集当前评分
290
- current_ratings = collect_ratings(*rating_values)
291
-
292
- # 保存当前评分到字典
293
- scene_name = question_folders[question_idx]
294
- all_ratings_dict[scene_name] = {
295
- 'ratings': current_ratings,
296
- 'mapping': method_mapping
297
- }
298
-
299
- # 移动到下一题
300
- new_idx = question_idx + 1
301
- if new_idx >= len(question_folders):
302
- # 所有题目完成,保存到文件
303
- for scene, data in all_ratings_dict.items():
304
- save_ratings(scene, data['ratings'], data['mapping'])
 
 
 
305
 
306
- return [
307
- question_idx,
308
- method_mapping,
309
- all_ratings_dict,
310
- f"**✅ 所有场景已完成!/ All scenes completed!**",
311
- "🎉 感谢参与!所有评分已保存 / Thank you! All ratings saved"
312
- ] + [gr.update(value=None)] * 4 + [gr.update(value=3)] * 12
313
-
314
- return update_question(new_idx, all_ratings_dict)
315
-
316
- # 上一题按钮
317
- def on_prev(question_idx, method_mapping, all_ratings_dict, *rating_values):
318
- # 收集当前评分并保存
319
- current_ratings = collect_ratings(*rating_values)
320
- scene_name = question_folders[question_idx]
321
- all_ratings_dict[scene_name] = {
322
- 'ratings': current_ratings,
323
- 'mapping': method_mapping
324
- }
325
-
326
- new_idx = question_idx - 1
327
- if new_idx < 0:
328
- new_idx = 0
329
- return update_question(new_idx, all_ratings_dict)
330
 
331
- # 收集所有评分组件
332
  all_rating_inputs = []
333
- for comp in rating_components:
334
- all_rating_inputs.extend([comp["dynamic"], comp["static"], comp["overall"]])
335
-
336
- # 绑定事件
337
- next_btn.click(
338
- on_next,
339
- inputs=[current_question_idx, current_method_mapping, all_ratings] + all_rating_inputs,
340
- outputs=[
341
- current_question_idx,
342
- current_method_mapping,
343
- all_ratings,
344
- question_text,
345
- status_text
346
- ] + video_components + all_rating_inputs
347
- )
348
-
349
- prev_btn.click(
350
- on_prev,
351
- inputs=[current_question_idx, current_method_mapping, all_ratings] + all_rating_inputs,
352
- outputs=[
353
- current_question_idx,
354
- current_method_mapping,
355
- all_ratings,
356
- question_text,
357
- status_text
358
- ] + video_components + all_rating_inputs
359
- )
360
 
361
- # 初始化第一个问题
362
- demo.load(
363
- lambda: update_question(0, {}),
364
- outputs=[
365
- current_question_idx,
366
- current_method_mapping,
367
- all_ratings,
368
- question_text,
369
- status_text
370
- ] + video_components + all_rating_inputs
371
  )
372
 
373
  return demo
 
166
  - **静态一致性** / Static Consistency: 视频中静态物体的稳定性和一致性
167
  - **整体质量** / Overall Quality: 视频的整体观感
168
  - 评分范围:1-5分(5分最好)/ Rating scale: 1-5 (5 = Best)
169
+ - 完成所有评分后,点击底部的"提交所有评分"按钮 / After rating all videos, click "Submit All Ratings" at the bottom
170
  """)
171
 
172
+ # 存储所有评分组件
173
+ all_scene_components = []
 
 
174
 
175
+ # 为每个场景创建界面
176
+ for scene_idx, scene_name in enumerate(question_folders):
177
+ videos, method_mapping = get_videos_for_question(scene_name)
 
 
 
 
 
 
 
 
 
 
 
178
 
179
  with gr.Group():
180
+ gr.Markdown(f"## 场景 {scene_idx + 1} / Scene {scene_idx + 1}: `{scene_name}`")
 
 
 
181
 
182
+ # 4个视频横向排列
183
  with gr.Row():
184
+ scene_ratings = []
185
+ for i in range(4):
186
+ method_name = f"Method {chr(65+i)}"
187
+
188
+ with gr.Column():
189
+ gr.Markdown(f"### 🎥 {method_name}")
190
+
191
+ # 视频
192
+ if method_name in videos:
193
+ video = gr.Video(value=videos[method_name], label="", height=300)
194
+ else:
195
+ video = gr.Video(value=None, label="", height=300, visible=False)
196
+
197
+ # 三个评分滑块(垂直排列)
198
+ dynamic = gr.Slider(
199
+ minimum=1, maximum=5, step=1, value=3,
200
+ label="动态质量 / Dynamic",
201
+ info="1=差, 5=优秀"
202
+ )
203
+ static = gr.Slider(
204
+ minimum=1, maximum=5, step=1, value=3,
205
+ label="静态一致性 / Static",
206
+ info="1=差, 5=优秀"
207
+ )
208
+ overall = gr.Slider(
209
+ minimum=1, maximum=5, step=1, value=3,
210
+ label="整体质量 / Overall",
211
+ info="1=差, 5=优秀"
212
+ )
213
+
214
+ scene_ratings.append({
215
+ "method": method_name,
216
+ "dynamic": dynamic,
217
+ "static": static,
218
+ "overall": overall
219
+ })
220
 
221
+ all_scene_components.append({
222
+ "scene_name": scene_name,
223
+ "method_mapping": method_mapping,
224
+ "ratings": scene_ratings
225
  })
226
 
227
+ # 提交按钮
228
+ gr.Markdown("---")
229
+ submit_btn = gr.Button("📤 提交所有评分 / Submit All Ratings", variant="primary", size="lg")
230
+ status_output = gr.Markdown("")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
 
232
+ # 提交函数
233
+ def submit_all_ratings(*all_rating_values):
234
+ try:
235
+ # 解析所有评分
236
+ value_idx = 0
237
+ for scene_data in all_scene_components:
238
+ scene_name = scene_data["scene_name"]
239
+ method_mapping = scene_data["method_mapping"]
240
+
241
+ ratings = {}
242
+ for rating_comp in scene_data["ratings"]:
243
+ method_name = rating_comp["method"]
244
+ ratings[method_name] = {
245
+ "dynamic_quality": all_rating_values[value_idx],
246
+ "static_consistency": all_rating_values[value_idx + 1],
247
+ "overall_quality": all_rating_values[value_idx + 2]
248
+ }
249
+ value_idx += 3
250
+
251
+ # 保存评分
252
+ save_ratings(scene_name, ratings, method_mapping)
253
 
254
+ return "✅ **所有评分已成功保存!感谢参与!** / All ratings saved successfully! Thank you for participating!"
255
+ except Exception as e:
256
+ return f"❌ **保存失败** / Save failed: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
 
258
+ # 收集所有评分输入
259
  all_rating_inputs = []
260
+ for scene_data in all_scene_components:
261
+ for rating_comp in scene_data["ratings"]:
262
+ all_rating_inputs.extend([
263
+ rating_comp["dynamic"],
264
+ rating_comp["static"],
265
+ rating_comp["overall"]
266
+ ])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
+ # 绑定提交按钮
269
+ submit_btn.click(
270
+ submit_all_ratings,
271
+ inputs=all_rating_inputs,
272
+ outputs=status_output
 
 
 
 
 
273
  )
274
 
275
  return demo