shunk031 commited on
Commit
3cb3095
·
1 Parent(s): f8502f5

deploy: 63a85616f5fc427cf1e1e7b425293131f2fce2b8

Browse files
Files changed (3) hide show
  1. README.md +146 -1
  2. layout-alignment.py +2 -0
  3. requirements.txt +134 -89
README.md CHANGED
@@ -9,4 +9,149 @@ 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 Alignment
13
+
14
+ ## Description
15
+
16
+ The Layout Alignment metric evaluates how well layout elements are aligned with each other. This metric implements alignment scoring methods from multiple research papers, providing a comprehensive assessment of spatial organization and visual harmony in graphic layouts.
17
+
18
+ ## What It Measures
19
+
20
+ This metric computes alignment scores that quantify how elements in a layout adhere to alignment principles:
21
+
22
+ - **Edge alignment**: How well element edges (left, right, top, bottom, center) align with each other
23
+ - **Spatial relationships**: Detection of common alignment patterns (grids, columns, rows)
24
+ - **Visual coherence**: Overall harmony created by consistent element positioning
25
+
26
+ Well-aligned layouts typically score lower (less alignment violation) and appear more professional and organized.
27
+
28
+ ## Metric Details
29
+
30
+ Implements alignment metrics from multiple influential layout generation papers:
31
+
32
+ - **NDN-Net (Lee et al., ECCV 2020)**: Neural Design Network alignment evaluation
33
+ - **AC-GAN (Li et al., TVCG 2021)**: Attribute-Conditioned GAN alignment metrics
34
+ - **CGL (Kikuchi et al., ACM MM 2021)**: Constrained Graphic Layout alignment scores
35
+
36
+ The metric analyzes element positioning to detect alignment relationships and violations.
37
+
38
+ ## Usage
39
+
40
+ ### Installation
41
+
42
+ ```bash
43
+ pip install evaluate
44
+ ```
45
+
46
+ ### Basic Example
47
+
48
+ ```python
49
+ import evaluate
50
+ import numpy as np
51
+
52
+ # Load the metric
53
+ metric = evaluate.load("creative-graphic-design/layout-alignment")
54
+
55
+ # Single layout processing
56
+ model_max_length, num_coordinates = 25, 4
57
+ bbox = np.random.rand(model_max_length, num_coordinates)
58
+ mask = np.random.choice(a=[True, False], size=(model_max_length,))
59
+ metric.add(bbox=bbox, mask=mask)
60
+ print(metric.compute())
61
+ ```
62
+
63
+ ### Batch Processing Example
64
+
65
+ ```python
66
+ import evaluate
67
+ import numpy as np
68
+
69
+ # Load the metric
70
+ metric = evaluate.load("creative-graphic-design/layout-alignment")
71
+
72
+ # Batch processing
73
+ batch_size, model_max_length, num_coordinates = 512, 25, 4
74
+ batch_bbox = np.random.rand(batch_size, model_max_length, num_coordinates)
75
+ batch_mask = np.random.choice(a=[True, False], size=(batch_size, model_max_length))
76
+ metric.add_batch(bbox=batch_bbox, mask=batch_mask)
77
+ print(metric.compute())
78
+ ```
79
+
80
+ ## Parameters
81
+
82
+ ### Initialization Parameters
83
+
84
+ This metric does not require any initialization parameters.
85
+
86
+ ### Computation Parameters
87
+
88
+ - **bbox** (`list` of `lists` of `int`): Bounding boxes for elements in normalized coordinates
89
+ - **mask** (`list` of `lists` of `bool`): Boolean mask indicating valid elements (True) vs padding (False)
90
+
91
+ **Note**: The mask parameter is crucial for handling variable-length layouts, where padding elements should be excluded from computation.
92
+
93
+ ## Returns
94
+
95
+ Returns a dictionary containing multiple alignment scores from different methods:
96
+
97
+ - Different variants measuring alignment quality from various perspectives
98
+ - Specific score names depend on the implementation details from referenced papers
99
+
100
+ ## Interpretation
101
+
102
+ - **Lower values generally indicate better alignment** (fewer alignment violations)
103
+ - **Value interpretation depends on specific score variant**:
104
+ - Some scores measure alignment violations (lower is better)
105
+ - Others measure alignment quality (higher is better)
106
+ - **Typical use**: Compare relative scores between different layout generation methods
107
+
108
+ ### Key Insights
109
+
110
+ - **Professional layouts** tend to have good alignment scores due to consistent spatial relationships
111
+ - **Grid-based layouts** typically achieve better alignment than freeform designs
112
+ - **Alignment patterns** (left-aligned, centered, etc.) are important for visual hierarchy
113
+
114
+ ## Citations
115
+
116
+ ```bibtex
117
+ @inproceedings{lee2020neural,
118
+ title={Neural design network: Graphic layout generation with constraints},
119
+ author={Lee, Hsin-Ying and Jiang, Lu and Essa, Irfan and Le, Phuong B and Gong, Haifeng and Yang, Ming-Hsuan and Yang, Weilong},
120
+ booktitle={Computer Vision--ECCV 2020: 16th European Conference, Glasgow, UK, August 23--28, 2020, Proceedings, Part III 16},
121
+ pages={491--506},
122
+ year={2020},
123
+ organization={Springer}
124
+ }
125
+
126
+ @article{li2020attribute,
127
+ title={Attribute-conditioned layout gan for automatic graphic design},
128
+ author={Li, Jianan and Yang, Jimei and Zhang, Jianming and Liu, Chang and Wang, Christina and Xu, Tingfa},
129
+ journal={IEEE Transactions on Visualization and Computer Graphics},
130
+ volume={27},
131
+ number={10},
132
+ pages={4039--4048},
133
+ year={2020},
134
+ publisher={IEEE}
135
+ }
136
+
137
+ @inproceedings{kikuchi2021constrained,
138
+ title={Constrained graphic layout generation via latent optimization},
139
+ author={Kikuchi, Kotaro and Simo-Serra, Edgar and Otani, Mayu and Yamaguchi, Kota},
140
+ booktitle={Proceedings of the 29th ACM International Conference on Multimedia},
141
+ pages={88--96},
142
+ year={2021}
143
+ }
144
+ ```
145
+
146
+ ## References
147
+
148
+ - **Paper**: [Neural Design Network (Lee et al., ECCV 2020)](https://arxiv.org/abs/1912.09421)
149
+ - **Paper**: [Attribute-Conditioned Layout GAN (Li et al., TVCG 2021)](https://arxiv.org/abs/2009.05284)
150
+ - **Paper**: [Constrained Graphic Layout Generation (Kikuchi et al., ACM MM 2021)](https://arxiv.org/abs/2108.00871)
151
+ - **Hugging Face Space**: [creative-graphic-design/layout-alignment](https://huggingface.co/spaces/creative-graphic-design/layout-alignment)
152
+
153
+ ## Related Metrics
154
+
155
+ - [Layout Non-Alignment](../layout_non_alignment/): Measures spatial non-alignment between elements
156
+ - [Layout Overlap](../layout_overlap/): Evaluates element overlap and spacing
157
+ - [Layout Validity](../layout_validity/): Checks basic layout validity constraints
layout-alignment.py CHANGED
@@ -4,6 +4,7 @@ import datasets as ds
4
  import evaluate
5
  import numpy as np
6
  import numpy.typing as npt
 
7
 
8
  _DESCRIPTION = """\
9
  Computes some alignment metrics that are different to each other in previous works.
@@ -83,6 +84,7 @@ def convert_xywh_to_ltrb(
83
  return (x1, y1, x2, y2)
84
 
85
 
 
86
  class LayoutAlignment(evaluate.Metric):
87
  def _info(self) -> evaluate.EvaluationModuleInfo:
88
  return evaluate.MetricInfo(
 
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 = """\
10
  Computes some alignment metrics that are different to each other in previous works.
 
84
  return (x1, y1, x2, y2)
85
 
86
 
87
+ @add_start_docstrings(_DESCRIPTION, _KWARGS_DESCRIPTION)
88
  class LayoutAlignment(evaluate.Metric):
89
  def _info(self) -> evaluate.EvaluationModuleInfo:
90
  return evaluate.MetricInfo(
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_alignment --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-alignment
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