shunk031 commited on
Commit
dd699d3
·
1 Parent(s): 1b569b1

deploy: 63a85616f5fc427cf1e1e7b425293131f2fce2b8

Browse files
Files changed (3) hide show
  1. README.md +143 -1
  2. layout-overlay.py +19 -2
  3. requirements.txt +134 -89
README.md CHANGED
@@ -9,4 +9,146 @@ app_file: app.py
9
  pinned: false
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  pinned: false
10
  ---
11
 
12
+ # Layout Overlay
13
+
14
+ ## Description
15
+
16
+ The Layout Overlay metric measures the average IoU (Intersection over Union) of all pairs of layout elements, specifically excluding "underlay" or decoration elements. This metric is designed for poster and presentation layouts where underlay elements serve as backgrounds and should not be counted in overlap calculations.
17
+
18
+ ## What It Measures
19
+
20
+ This metric computes:
21
+
22
+ - **Non-underlay overlap**: IoU between all pairs of foreground elements (text, images, logos)
23
+ - **Element collision**: How much non-decoration elements interfere with each other
24
+ - **Foreground placement quality**: Whether foreground elements are properly spaced
25
+
26
+ Underlay/decoration elements (like background shapes) are excluded from the calculation since they're intended to sit behind other elements.
27
+
28
+ ## Metric Details
29
+
30
+ - Filters out decoration/underlay elements (typically class index 3 in PosterLayout)
31
+ - Removes invalid elements (< 0.1% of canvas area)
32
+ - Computes pairwise IoU for all remaining element pairs
33
+ - Returns average IoU across all overlapping pairs
34
+ - From PosterLayout (Hsu et al., CVPR 2023) for poster design evaluation
35
+
36
+ ## Usage
37
+
38
+ ### Installation
39
+
40
+ ```bash
41
+ pip install evaluate
42
+ ```
43
+
44
+ ### Basic Example
45
+
46
+ ```python
47
+ import evaluate
48
+ import numpy as np
49
+
50
+ # Load the metric with canvas dimensions
51
+ metric = evaluate.load(
52
+ "creative-graphic-design/layout-overlay",
53
+ canvas_width=360,
54
+ canvas_height=504,
55
+ decoration_label_index=3 # underlay/decoration class
56
+ )
57
+
58
+ # Prepare data
59
+ predictions = np.random.rand(1, 25, 4) # normalized ltrb coordinates
60
+ gold_labels = np.random.randint(0, 4, size=(1, 25)) # class labels
61
+ score = metric.compute(predictions=predictions, gold_labels=gold_labels)
62
+ print(score)
63
+ ```
64
+
65
+ ### Batch Processing Example
66
+
67
+ ```python
68
+ import evaluate
69
+ import numpy as np
70
+
71
+ # Load the metric
72
+ metric = evaluate.load(
73
+ "creative-graphic-design/layout-overlay",
74
+ canvas_width=360,
75
+ canvas_height=504,
76
+ decoration_label_index=3
77
+ )
78
+
79
+ # Batch processing
80
+ batch_size = 128
81
+ predictions = np.random.rand(batch_size, 25, 4)
82
+ gold_labels = np.random.randint(0, 4, size=(batch_size, 25))
83
+ score = metric.compute(predictions=predictions, gold_labels=gold_labels)
84
+ print(score)
85
+ ```
86
+
87
+ ## Parameters
88
+
89
+ ### Initialization Parameters
90
+
91
+ - **canvas_width** (`int`, required): Width of the canvas in pixels
92
+ - **canvas_height** (`int`, required): Height of the canvas in pixels
93
+ - **decoration_label_index** (`int`, optional, default=3): Class index for underlay/decoration elements to exclude
94
+
95
+ ### Computation Parameters
96
+
97
+ - **predictions** (`list` of `lists` of `float`): Normalized bounding boxes in ltrb format (0.0 to 1.0)
98
+ - **gold_labels** (`list` of `lists` of `int`): Class labels for each element (0 = padding)
99
+
100
+ **Note**:
101
+
102
+ - Elements with label == 0 are treated as padding
103
+ - Elements with label == decoration_label_index are excluded (underlay)
104
+ - Very small elements (< 0.1% of canvas) are filtered out
105
+
106
+ ## Returns
107
+
108
+ Returns a `float` value representing the average IoU of overlapping element pairs (excluding underlay).
109
+
110
+ ## Interpretation
111
+
112
+ - **Lower is better** (range: 0.0 to 1.0)
113
+ - **Value of 0.0**: No overlap between foreground elements (ideal)
114
+ - **Value of 0.1-0.3**: Minor overlap, possibly acceptable in dense layouts
115
+ - **Value of 0.3-0.5**: Moderate overlap, may indicate placement issues
116
+ - **Value > 0.5**: Significant overlap, likely problematic
117
+
118
+ ### Use Cases
119
+
120
+ - **Poster/presentation layout evaluation**: Ensure foreground elements don't overlap excessively
121
+ - **Content-aware design**: Evaluate layouts with distinct foreground and background layers
122
+ - **Layered designs**: Assess foreground element placement independent of decoration layers
123
+ - **Multi-layer layouts**: Focus on collision detection for primary content
124
+
125
+ ### Key Insights
126
+
127
+ - **Underlay exclusion is important**: Decoration elements are meant to be behind others
128
+ - **Context-specific**: Appropriate for designs with clear foreground/background separation
129
+ - **Different from general overlap**: Focuses only on foreground element interactions
130
+ - **Use with related metrics**: Combine with underlay effectiveness for full picture
131
+
132
+ ## Citations
133
+
134
+ ```bibtex
135
+ @inproceedings{hsu2023posterlayout,
136
+ title={Posterlayout: A new benchmark and approach for content-aware visual-textual presentation layout},
137
+ author={Hsu, Hsiao Yuan and He, Xiangteng and Peng, Yuxin and Kong, Hao and Zhang, Qing},
138
+ booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
139
+ pages={6018--6026},
140
+ year={2023}
141
+ }
142
+ ```
143
+
144
+ ## References
145
+
146
+ - **Paper**: [PosterLayout (Hsu et al., CVPR 2023)](https://arxiv.org/abs/2303.15937)
147
+ - **Reference Implementation**: [PosterLayout eval.py](https://github.com/PKU-ICST-MIPL/PosterLayout-CVPR2023/blob/main/eval.py#L205-L222)
148
+
149
+ ## Related Metrics
150
+
151
+ - [Layout Overlap](../layout_overlap/): General overlap metric for all elements
152
+ - [Layout Underlay Effectiveness](../layout_underlay_effectiveness/): Evaluates underlay element placement
153
+ - [Layout Average IoU](../layout_average_iou/): IoU-based overlap for all elements
154
+ - [Layout Validity](../layout_validity/): Checks basic validity constraints
layout-overlay.py CHANGED
@@ -4,13 +4,22 @@ import datasets as ds
4
  import evaluate
5
  import numpy as np
6
  import numpy.typing as npt
 
7
 
8
  _DESCRIPTION = r"""\
9
  Computes the average IoU of all pairs of elements except for underlay.
10
  """
11
 
12
  _KWARGS_DESCRIPTION = """\
13
- FIXME
 
 
 
 
 
 
 
 
14
  """
15
 
16
  _CITATION = """\
@@ -24,16 +33,19 @@ _CITATION = """\
24
  """
25
 
26
 
 
27
  class LayoutOverlay(evaluate.Metric):
28
  def __init__(
29
  self,
30
  canvas_width: int,
31
  canvas_height: int,
 
32
  **kwargs,
33
  ) -> None:
34
  super().__init__(**kwargs)
35
  self.canvas_width = canvas_width
36
  self.canvas_height = canvas_height
 
37
 
38
  def _info(self) -> evaluate.EvaluationModuleInfo:
39
  return evaluate.MetricInfo(
@@ -114,8 +126,13 @@ class LayoutOverlay(evaluate.Metric):
114
 
115
  for gold_label, prediction in zip(gold_labels, predictions):
116
  ove = 0.0
117
- mask = (gold_label > 0).reshape(-1) & (gold_label != 3).reshape(-1)
 
 
 
 
118
  mask_box = prediction[mask]
 
119
  n = len(mask_box)
120
  for i in range(n):
121
  bb1 = mask_box[i]
 
4
  import evaluate
5
  import numpy as np
6
  import numpy.typing as npt
7
+ from evaluate.utils.file_utils import add_start_docstrings
8
 
9
  _DESCRIPTION = r"""\
10
  Computes the average IoU of all pairs of elements except for underlay.
11
  """
12
 
13
  _KWARGS_DESCRIPTION = """\
14
+ Args:
15
+ predictions (`list` of `lists` of `float`): A list of lists of floats representing normalized `ltrb`-format bounding boxes.
16
+ gold_labels (`list` of `lists` of `int`): A list of lists of integers representing class labels.
17
+
18
+ Ruturns:
19
+ float: Average IoU except decoration (i.e., underlay) elements (used in PosterLayout).
20
+
21
+ Examples::
22
+ FIXME
23
  """
24
 
25
  _CITATION = """\
 
33
  """
34
 
35
 
36
+ @add_start_docstrings(_DESCRIPTION, _KWARGS_DESCRIPTION)
37
  class LayoutOverlay(evaluate.Metric):
38
  def __init__(
39
  self,
40
  canvas_width: int,
41
  canvas_height: int,
42
+ decoration_label_index: int = 3,
43
  **kwargs,
44
  ) -> None:
45
  super().__init__(**kwargs)
46
  self.canvas_width = canvas_width
47
  self.canvas_height = canvas_height
48
+ self.decoration_label_index = decoration_label_index
49
 
50
  def _info(self) -> evaluate.EvaluationModuleInfo:
51
  return evaluate.MetricInfo(
 
126
 
127
  for gold_label, prediction in zip(gold_labels, predictions):
128
  ove = 0.0
129
+
130
+ cond1 = (gold_label > 0).reshape(-1)
131
+ cond2 = (gold_label != self.decoration_label_index).reshape(-1)
132
+
133
+ mask = cond1 & cond2
134
  mask_box = prediction[mask]
135
+
136
  n = len(mask_box)
137
  for i in range(n):
138
  bb1 = mask_box[i]
requirements.txt CHANGED
@@ -1,89 +1,134 @@
1
- aiofiles==23.2.1 ; python_version >= "3.9" and python_version < "4.0"
2
- aiohttp==3.9.3 ; python_version >= "3.9" and python_version < "4.0"
3
- aiosignal==1.3.1 ; python_version >= "3.9" and python_version < "4.0"
4
- altair==5.2.0 ; python_version >= "3.9" and python_version < "4.0"
5
- annotated-types==0.6.0 ; python_version >= "3.9" and python_version < "4.0"
6
- anyio==4.2.0 ; python_version >= "3.9" and python_version < "4.0"
7
- arrow==1.3.0 ; python_version >= "3.9" and python_version < "4.0"
8
- async-timeout==4.0.3 ; python_version >= "3.9" and python_version < "3.11"
9
- attrs==23.2.0 ; python_version >= "3.9" and python_version < "4.0"
10
- binaryornot==0.4.4 ; python_version >= "3.9" and python_version < "4.0"
11
- certifi==2024.2.2 ; python_version >= "3.9" and python_version < "4.0"
12
- chardet==5.2.0 ; python_version >= "3.9" and python_version < "4.0"
13
- charset-normalizer==3.3.2 ; python_version >= "3.9" and python_version < "4.0"
14
- click==8.1.7 ; python_version >= "3.9" and python_version < "4.0"
15
- colorama==0.4.6 ; python_version >= "3.9" and python_version < "4.0"
16
- contourpy==1.2.0 ; python_version >= "3.9" and python_version < "4.0"
17
- cookiecutter==2.5.0 ; python_version >= "3.9" and python_version < "4.0"
18
- cycler==0.12.1 ; python_version >= "3.9" and python_version < "4.0"
19
- datasets==2.17.0 ; python_version >= "3.9" and python_version < "4.0"
20
- dill==0.3.8 ; python_version >= "3.9" and python_version < "4.0"
21
- evaluate[template]==0.4.1 ; python_version >= "3.9" and python_version < "4.0"
22
- exceptiongroup==1.2.0 ; python_version >= "3.9" and python_version < "3.11"
23
- fastapi==0.109.2 ; python_version >= "3.9" and python_version < "4.0"
24
- ffmpy==0.3.1 ; python_version >= "3.9" and python_version < "4.0"
25
- filelock==3.13.1 ; python_version >= "3.9" and python_version < "4.0"
26
- fonttools==4.48.1 ; python_version >= "3.9" and python_version < "4.0"
27
- frozenlist==1.4.1 ; python_version >= "3.9" and python_version < "4.0"
28
- fsspec==2023.10.0 ; python_version >= "3.9" and python_version < "4.0"
29
- fsspec[http]==2023.10.0 ; python_version >= "3.9" and python_version < "4.0"
30
- gradio-client==0.10.0 ; python_version >= "3.9" and python_version < "4.0"
31
- gradio==4.18.0 ; python_version >= "3.9" and python_version < "4.0"
32
- h11==0.14.0 ; python_version >= "3.9" and python_version < "4.0"
33
- httpcore==1.0.2 ; python_version >= "3.9" and python_version < "4.0"
34
- httpx==0.26.0 ; python_version >= "3.9" and python_version < "4.0"
35
- huggingface-hub==0.20.3 ; python_version >= "3.9" and python_version < "4.0"
36
- idna==3.6 ; python_version >= "3.9" and python_version < "4.0"
37
- importlib-resources==6.1.1 ; python_version >= "3.9" and python_version < "4.0"
38
- jinja2==3.1.3 ; python_version >= "3.9" and python_version < "4.0"
39
- jsonschema-specifications==2023.12.1 ; python_version >= "3.9" and python_version < "4.0"
40
- jsonschema==4.21.1 ; python_version >= "3.9" and python_version < "4.0"
41
- kiwisolver==1.4.5 ; python_version >= "3.9" and python_version < "4.0"
42
- markdown-it-py==3.0.0 ; python_version >= "3.9" and python_version < "4.0"
43
- markupsafe==2.1.5 ; python_version >= "3.9" and python_version < "4.0"
44
- matplotlib==3.8.2 ; python_version >= "3.9" and python_version < "4.0"
45
- mdurl==0.1.2 ; python_version >= "3.9" and python_version < "4.0"
46
- multidict==6.0.5 ; python_version >= "3.9" and python_version < "4.0"
47
- multiprocess==0.70.16 ; python_version >= "3.9" and python_version < "4.0"
48
- numpy==1.26.4 ; python_version >= "3.9" and python_version < "4.0"
49
- orjson==3.9.13 ; python_version >= "3.9" and python_version < "4.0"
50
- packaging==23.2 ; python_version >= "3.9" and python_version < "4.0"
51
- pandas==2.2.0 ; python_version >= "3.9" and python_version < "4.0"
52
- pillow==10.2.0 ; python_version >= "3.9" and python_version < "4.0"
53
- pyarrow-hotfix==0.6 ; python_version >= "3.9" and python_version < "4.0"
54
- pyarrow==15.0.0 ; python_version >= "3.9" and python_version < "4.0"
55
- pydantic-core==2.16.2 ; python_version >= "3.9" and python_version < "4.0"
56
- pydantic==2.6.1 ; python_version >= "3.9" and python_version < "4.0"
57
- pydub==0.25.1 ; python_version >= "3.9" and python_version < "4.0"
58
- pygments==2.17.2 ; python_version >= "3.9" and python_version < "4.0"
59
- pyparsing==3.1.1 ; python_version >= "3.9" and python_version < "4.0"
60
- python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "4.0"
61
- python-multipart==0.0.9 ; python_version >= "3.9" and python_version < "4.0"
62
- python-slugify==8.0.4 ; python_version >= "3.9" and python_version < "4.0"
63
- pytz==2024.1 ; python_version >= "3.9" and python_version < "4.0"
64
- pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4.0"
65
- referencing==0.33.0 ; python_version >= "3.9" and python_version < "4.0"
66
- requests==2.31.0 ; python_version >= "3.9" and python_version < "4.0"
67
- responses==0.18.0 ; python_version >= "3.9" and python_version < "4.0"
68
- rich==13.7.0 ; python_version >= "3.9" and python_version < "4.0"
69
- rpds-py==0.17.1 ; python_version >= "3.9" and python_version < "4.0"
70
- ruff==0.2.1 ; python_version >= "3.9" and python_version < "4.0"
71
- semantic-version==2.10.0 ; python_version >= "3.9" and python_version < "4.0"
72
- shellingham==1.5.4 ; python_version >= "3.9" and python_version < "4.0"
73
- six==1.16.0 ; python_version >= "3.9" and python_version < "4.0"
74
- sniffio==1.3.0 ; python_version >= "3.9" and python_version < "4.0"
75
- starlette==0.36.3 ; python_version >= "3.9" and python_version < "4.0"
76
- text-unidecode==1.3 ; python_version >= "3.9" and python_version < "4.0"
77
- tomlkit==0.12.0 ; python_version >= "3.9" and python_version < "4.0"
78
- toolz==0.12.1 ; python_version >= "3.9" and python_version < "4.0"
79
- tqdm==4.66.2 ; python_version >= "3.9" and python_version < "4.0"
80
- typer[all]==0.9.0 ; python_version >= "3.9" and python_version < "4.0"
81
- types-python-dateutil==2.8.19.20240106 ; python_version >= "3.9" and python_version < "4.0"
82
- typing-extensions==4.9.0 ; python_version >= "3.9" and python_version < "4.0"
83
- tzdata==2024.1 ; python_version >= "3.9" and python_version < "4.0"
84
- urllib3==2.2.0 ; python_version >= "3.9" and python_version < "4.0"
85
- uvicorn==0.27.1 ; python_version >= "3.9" and python_version < "4.0"
86
- websockets==11.0.3 ; python_version >= "3.9" and python_version < "4.0"
87
- xxhash==3.4.1 ; python_version >= "3.9" and python_version < "4.0"
88
- yarl==1.9.4 ; python_version >= "3.9" and python_version < "4.0"
89
- zipp==3.17.0 ; python_version >= "3.9" and python_version < "3.10"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file was autogenerated by uv via the following command:
2
+ # uv export --package layout_overlay --no-dev --no-hashes --format requirements-txt
3
+ aiohappyeyeballs==2.6.1
4
+ # via aiohttp
5
+ aiohttp==3.13.2
6
+ # via fsspec
7
+ aiosignal==1.4.0
8
+ # via aiohttp
9
+ anyio==4.12.0
10
+ # via httpx
11
+ attrs==25.4.0
12
+ # via aiohttp
13
+ certifi==2025.11.12
14
+ # via
15
+ # httpcore
16
+ # httpx
17
+ # requests
18
+ charset-normalizer==3.4.4
19
+ # via requests
20
+ click==8.3.1
21
+ # via typer-slim
22
+ colorama==0.4.6 ; sys_platform == 'win32'
23
+ # via
24
+ # click
25
+ # tqdm
26
+ datasets==4.4.2
27
+ # via evaluate
28
+ dill==0.4.0
29
+ # via
30
+ # datasets
31
+ # evaluate
32
+ # multiprocess
33
+ evaluate==0.4.6
34
+ # via layout-overlay
35
+ filelock==3.20.1
36
+ # via
37
+ # datasets
38
+ # huggingface-hub
39
+ frozenlist==1.8.0
40
+ # via
41
+ # aiohttp
42
+ # aiosignal
43
+ fsspec==2025.10.0
44
+ # via
45
+ # datasets
46
+ # evaluate
47
+ # huggingface-hub
48
+ h11==0.16.0
49
+ # via httpcore
50
+ hf-xet==1.2.0 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'
51
+ # via huggingface-hub
52
+ httpcore==1.0.9
53
+ # via httpx
54
+ httpx==0.28.1
55
+ # via
56
+ # datasets
57
+ # huggingface-hub
58
+ huggingface-hub==1.2.3
59
+ # via
60
+ # datasets
61
+ # evaluate
62
+ idna==3.11
63
+ # via
64
+ # anyio
65
+ # httpx
66
+ # requests
67
+ # yarl
68
+ multidict==6.7.0
69
+ # via
70
+ # aiohttp
71
+ # yarl
72
+ multiprocess==0.70.18
73
+ # via
74
+ # datasets
75
+ # evaluate
76
+ numpy==2.2.6
77
+ # via
78
+ # datasets
79
+ # evaluate
80
+ # pandas
81
+ packaging==25.0
82
+ # via
83
+ # datasets
84
+ # evaluate
85
+ # huggingface-hub
86
+ pandas==2.3.3
87
+ # via
88
+ # datasets
89
+ # evaluate
90
+ propcache==0.4.1
91
+ # via
92
+ # aiohttp
93
+ # yarl
94
+ pyarrow==22.0.0
95
+ # via datasets
96
+ python-dateutil==2.9.0.post0
97
+ # via pandas
98
+ pytz==2025.2
99
+ # via pandas
100
+ pyyaml==6.0.3
101
+ # via
102
+ # datasets
103
+ # huggingface-hub
104
+ requests==2.32.5
105
+ # via
106
+ # datasets
107
+ # evaluate
108
+ shellingham==1.5.4
109
+ # via huggingface-hub
110
+ six==1.17.0
111
+ # via python-dateutil
112
+ tqdm==4.67.1
113
+ # via
114
+ # datasets
115
+ # evaluate
116
+ # huggingface-hub
117
+ typer-slim==0.21.0
118
+ # via huggingface-hub
119
+ typing-extensions==4.15.0
120
+ # via
121
+ # aiosignal
122
+ # anyio
123
+ # huggingface-hub
124
+ # typer-slim
125
+ tzdata==2025.3
126
+ # via pandas
127
+ urllib3==2.6.2
128
+ # via requests
129
+ xxhash==3.6.0
130
+ # via
131
+ # datasets
132
+ # evaluate
133
+ yarl==1.22.0
134
+ # via aiohttp