FeilongTang commited on
Commit
1476ac5
·
1 Parent(s): 34df0c5

Decouple cumulative chart baseline from preview resize

Browse files
Files changed (1) hide show
  1. app.py +22 -13
app.py CHANGED
@@ -623,6 +623,7 @@ def make_charts(
623
  codec_frame_ids: List[int],
624
  uniform_frame_ids: List[int],
625
  uniform_requested_frames: int,
 
626
  fps: float,
627
  total_duration_sec: float,
628
  total_patches_budget: int,
@@ -637,7 +638,7 @@ def make_charts(
637
  Y = cumulative count of selected patches
638
  The codec curve rises in bursts where saliency is high; the uniform
639
  baseline rises in equal steps because every sampled full frame
640
- contributes one complete patch grid."""
641
  fig, ax = plt.subplots(figsize=(9.2, 3.6), constrained_layout=True)
642
 
643
  fps_safe = float(fps) if fps and fps > 0 else 25.0
@@ -672,11 +673,12 @@ def make_charts(
672
 
673
  # Uniform baseline: evenly sample COMPLETE frames from the same time
674
  # window, no codec saliency involved. Each sampled frame contributes a
675
- # whole patch grid.
676
  budget_int = int(total_patches_budget)
677
  requested_uniform = max(0, int(uniform_requested_frames))
 
678
  n_uniform = len(uniform_frame_ids)
679
- uni_per_step = [grid_size for _ in uniform_frame_ids]
680
  uni_cum = list(np.cumsum(uni_per_step)) if uni_per_step else []
681
  uni_total = int(uni_cum[-1]) if uni_cum else 0
682
  uni_times = [fid / fps_safe for fid in uniform_frame_ids]
@@ -700,7 +702,7 @@ def make_charts(
700
  if requested_uniform != n_uniform else f"{n_uniform} frames"
701
  )
702
  uni_lbl = (
703
- f"Uniform full frames ({frame_part} · {grid_size}/frame · "
704
  f"{uni_total:,} total"
705
  + (f" · {unused:,} budget unused" if unused else "")
706
  + ")"
@@ -708,7 +710,7 @@ def make_charts(
708
  else:
709
  uni_lbl = (
710
  f"Uniform full frames (0/{requested_uniform} frames fit budget "
711
- f"{budget_int:,}; need {grid_size} patches/frame)"
712
  )
713
 
714
  ax.fill_between(xx_c, yy_c, step=None, alpha=0.12, color="#4f46e5")
@@ -887,16 +889,17 @@ def process(
887
 
888
  hb, wb = grids[0].shape
889
  grid_size = int(grids[0].shape[0] * grids[0].shape[1]) if grids else 0
 
890
  # Uniform full-frame sampling baseline: evenly sample complete frames
891
  # from the same time window, independent of codec saliency.
892
  requested_budget = int(total_patches)
893
  uniform_requested_frames = len(fids)
894
  uniform_frame_count = min(
895
  uniform_requested_frames,
896
- requested_budget // max(1, grid_size),
897
  )
898
  uniform_frame_ids = sample_window_frame_ids(f_start, f_end, uniform_frame_count)
899
- uniform_total = int(len(uniform_frame_ids) * grid_size)
900
  info = {
901
  "input": meta,
902
  "params": {
@@ -933,7 +936,7 @@ def process(
933
  "mode": "uniform_full_frame_sampling",
934
  "requested_frames": int(uniform_requested_frames),
935
  "frames": int(len(uniform_frame_ids)),
936
- "patches_per_frame": int(grid_size),
937
  "frame_ids": [int(x) for x in uniform_frame_ids],
938
  "requested_budget": requested_budget,
939
  "unused_budget": int(max(0, requested_budget - uniform_total)),
@@ -942,12 +945,14 @@ def process(
942
  "Uniformly sample complete frames from the same time window. "
943
  f"The baseline targets the same sampled-frame count as codec "
944
  f"({uniform_requested_frames}), but each full frame costs "
945
- f"{grid_size} patches, so only {len(uniform_frame_ids)} full "
 
946
  "frames may fit inside the requested budget."
947
  ),
948
  },
949
  "resized_frame_size": f"{tw}x{th}",
950
  "patch_grid_per_frame": f"{hb}x{wb} = {hb * wb} patches",
 
951
  "actual_selected_total": int(actual_selected),
952
  "total_selected_patches_incl_i_frames": int(n_selected),
953
  "canvases": [
@@ -973,6 +978,7 @@ def process(
973
  duration_sec = (total / fps) if fps > 0 else 0.0
974
  chart_fig = make_charts(
975
  grids, masks, fids, uniform_frame_ids, uniform_requested_frames,
 
976
  fps, duration_sec,
977
  int(total_patches), saliency_signal,
978
  groups=groups, gop_label=gop_resolved,
@@ -1398,8 +1404,9 @@ with gr.Blocks(**_BLOCK_KW) as demo:
1398
  label="Total patches budget (whole video)",
1399
  info="The single budget shared across the whole video. "
1400
  "The uniform full-frame baseline will fit as many "
1401
- "complete frames as this budget allows; the codec path "
1402
- "spends the same budget on saliency-selected patches.",
 
1403
  )
1404
  patch_size = gr.Radio(
1405
  PATCH_CHOICES, value=14, label="Patch size (px)",
@@ -1484,8 +1491,10 @@ with gr.Blocks(**_BLOCK_KW) as demo:
1484
  "in bursts. <b>Cyan (dashed)</b>: uniform full-frame "
1485
  "sampling — evenly samples complete frames from the same "
1486
  "time window, targeting the same sampled-frame count as "
1487
- "codec when the budget allows. Each step is one full "
1488
- "patch grid. The dotted line marks the requested budget.</small>"
 
 
1489
  )
1490
  chart_out = gr.Plot(label="", show_label=False)
1491
 
 
623
  codec_frame_ids: List[int],
624
  uniform_frame_ids: List[int],
625
  uniform_requested_frames: int,
626
+ uniform_full_frame_patches: int,
627
  fps: float,
628
  total_duration_sec: float,
629
  total_patches_budget: int,
 
638
  Y = cumulative count of selected patches
639
  The codec curve rises in bursts where saliency is high; the uniform
640
  baseline rises in equal steps because every sampled full frame
641
+ contributes `patch_size^2` patches."""
642
  fig, ax = plt.subplots(figsize=(9.2, 3.6), constrained_layout=True)
643
 
644
  fps_safe = float(fps) if fps and fps > 0 else 25.0
 
673
 
674
  # Uniform baseline: evenly sample COMPLETE frames from the same time
675
  # window, no codec saliency involved. Each sampled frame contributes a
676
+ # fixed `patch_size^2` patch cost, independent of visualization resize.
677
  budget_int = int(total_patches_budget)
678
  requested_uniform = max(0, int(uniform_requested_frames))
679
+ full_frame_patches = max(1, int(uniform_full_frame_patches))
680
  n_uniform = len(uniform_frame_ids)
681
+ uni_per_step = [full_frame_patches for _ in uniform_frame_ids]
682
  uni_cum = list(np.cumsum(uni_per_step)) if uni_per_step else []
683
  uni_total = int(uni_cum[-1]) if uni_cum else 0
684
  uni_times = [fid / fps_safe for fid in uniform_frame_ids]
 
702
  if requested_uniform != n_uniform else f"{n_uniform} frames"
703
  )
704
  uni_lbl = (
705
+ f"Uniform full frames ({frame_part} · {full_frame_patches}/frame · "
706
  f"{uni_total:,} total"
707
  + (f" · {unused:,} budget unused" if unused else "")
708
  + ")"
 
710
  else:
711
  uni_lbl = (
712
  f"Uniform full frames (0/{requested_uniform} frames fit budget "
713
+ f"{budget_int:,}; need {full_frame_patches} patches/frame)"
714
  )
715
 
716
  ax.fill_between(xx_c, yy_c, step=None, alpha=0.12, color="#4f46e5")
 
889
 
890
  hb, wb = grids[0].shape
891
  grid_size = int(grids[0].shape[0] * grids[0].shape[1]) if grids else 0
892
+ uniform_full_frame_patches = int(patch_size) * int(patch_size)
893
  # Uniform full-frame sampling baseline: evenly sample complete frames
894
  # from the same time window, independent of codec saliency.
895
  requested_budget = int(total_patches)
896
  uniform_requested_frames = len(fids)
897
  uniform_frame_count = min(
898
  uniform_requested_frames,
899
+ requested_budget // max(1, uniform_full_frame_patches),
900
  )
901
  uniform_frame_ids = sample_window_frame_ids(f_start, f_end, uniform_frame_count)
902
+ uniform_total = int(len(uniform_frame_ids) * uniform_full_frame_patches)
903
  info = {
904
  "input": meta,
905
  "params": {
 
936
  "mode": "uniform_full_frame_sampling",
937
  "requested_frames": int(uniform_requested_frames),
938
  "frames": int(len(uniform_frame_ids)),
939
+ "patches_per_frame": int(uniform_full_frame_patches),
940
  "frame_ids": [int(x) for x in uniform_frame_ids],
941
  "requested_budget": requested_budget,
942
  "unused_budget": int(max(0, requested_budget - uniform_total)),
 
945
  "Uniformly sample complete frames from the same time window. "
946
  f"The baseline targets the same sampled-frame count as codec "
947
  f"({uniform_requested_frames}), but each full frame costs "
948
+ f"{uniform_full_frame_patches} patches (= patch_size^2), so "
949
+ f"only {len(uniform_frame_ids)} full "
950
  "frames may fit inside the requested budget."
951
  ),
952
  },
953
  "resized_frame_size": f"{tw}x{th}",
954
  "patch_grid_per_frame": f"{hb}x{wb} = {hb * wb} patches",
955
+ "uniform_full_frame_patch_cost": int(uniform_full_frame_patches),
956
  "actual_selected_total": int(actual_selected),
957
  "total_selected_patches_incl_i_frames": int(n_selected),
958
  "canvases": [
 
978
  duration_sec = (total / fps) if fps > 0 else 0.0
979
  chart_fig = make_charts(
980
  grids, masks, fids, uniform_frame_ids, uniform_requested_frames,
981
+ uniform_full_frame_patches,
982
  fps, duration_sec,
983
  int(total_patches), saliency_signal,
984
  groups=groups, gop_label=gop_resolved,
 
1404
  label="Total patches budget (whole video)",
1405
  info="The single budget shared across the whole video. "
1406
  "The uniform full-frame baseline will fit as many "
1407
+ "complete frames as this budget allows, where one full "
1408
+ "frame costs patch_size^2 patches; the codec path spends "
1409
+ "the same budget on saliency-selected patches.",
1410
  )
1411
  patch_size = gr.Radio(
1412
  PATCH_CHOICES, value=14, label="Patch size (px)",
 
1491
  "in bursts. <b>Cyan (dashed)</b>: uniform full-frame "
1492
  "sampling — evenly samples complete frames from the same "
1493
  "time window, targeting the same sampled-frame count as "
1494
+ "codec when the budget allows. Each step costs "
1495
+ "<b>patch_size^2</b> patches, regardless of the preview "
1496
+ "frame resolution. The dotted line marks the requested "
1497
+ "budget.</small>"
1498
  )
1499
  chart_out = gr.Plot(label="", show_label=False)
1500