shunk031 commited on
Commit
080abbb
·
1 Parent(s): 79d0cab

deploy: fb8481effdf5a0b23ff86fad414906046d7620bd

Browse files
Files changed (1) hide show
  1. layout-utility.py +64 -15
layout-utility.py CHANGED
@@ -13,7 +13,33 @@ Computes the utilization rate of space suitable for arranging elements, implemen
13
  """
14
 
15
  _KWARGS_DESCRIPTION = """\
16
- FIXME
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  """
18
 
19
  _CITATION = """\
@@ -31,8 +57,8 @@ _CITATION = """\
31
  class LayoutUtility(evaluate.Metric):
32
  def __init__(
33
  self,
34
- canvas_width: int,
35
- canvas_height: int,
36
  **kwargs,
37
  ) -> None:
38
  super().__init__(**kwargs)
@@ -60,6 +86,8 @@ class LayoutUtility(evaluate.Metric):
60
  def load_saliency_map(
61
  self,
62
  filepath: Union[os.PathLike, List[os.PathLike]],
 
 
63
  ) -> npt.NDArray[np.float64]:
64
  if isinstance(filepath, list):
65
  assert len(filepath) == 1, filepath
@@ -68,28 +96,32 @@ class LayoutUtility(evaluate.Metric):
68
  map_pil = Image.open(filepath) # type: ignore
69
  map_pil = map_pil.convert("L") # type: ignore
70
 
71
- if map_pil.size != (self.canvas_width, self.canvas_height):
72
- map_pil = map_pil.resize((self.canvas_width, self.canvas_height)) # type: ignore
73
 
74
  map_arr = np.array(map_pil)
75
  map_arr = map_arr / 255.0
76
  return map_arr
77
 
78
  def get_rid_of_invalid(
79
- self, predictions: npt.NDArray[np.float64], gold_labels: npt.NDArray[np.int64]
 
 
 
 
80
  ) -> npt.NDArray[np.int64]:
81
  assert len(predictions) == len(gold_labels)
82
 
83
- w = self.canvas_width / 100
84
- h = self.canvas_height / 100
85
 
86
  for i, prediction in enumerate(predictions):
87
  for j, b in enumerate(prediction):
88
  xl, yl, xr, yr = b
89
  xl = max(0, xl)
90
  yl = max(0, yl)
91
- xr = min(self.canvas_width, xr)
92
- yr = min(self.canvas_height, yr)
93
  if abs((xr - xl) * (yr - yl)) < w * h * 10:
94
  if gold_labels[i, j]:
95
  gold_labels[i, j] = 0
@@ -102,15 +134,32 @@ class LayoutUtility(evaluate.Metric):
102
  gold_labels: Union[npt.NDArray[np.int64], List[int]],
103
  saliency_maps_1: List[os.PathLike],
104
  saliency_maps_2: List[os.PathLike],
 
 
105
  ) -> float:
 
 
 
 
 
 
 
 
 
 
 
 
106
  predictions = np.array(predictions)
107
  gold_labels = np.array(gold_labels)
108
 
109
- predictions[:, :, ::2] *= self.canvas_width
110
- predictions[:, :, 1::2] *= self.canvas_height
111
 
112
  gold_labels = self.get_rid_of_invalid(
113
- predictions=predictions, gold_labels=gold_labels
 
 
 
114
  )
115
 
116
  score = []
@@ -124,8 +173,8 @@ class LayoutUtility(evaluate.Metric):
124
  it = zip(predictions, gold_labels, saliency_maps_1, saliency_maps_2)
125
 
126
  for prediction, gold_label, smap_1, smap_2 in it:
127
- smap_arr_1 = self.load_saliency_map(smap_1)
128
- smap_arr_2 = self.load_saliency_map(smap_2)
129
 
130
  smap_arr = np.maximum(smap_arr_1, smap_arr_2)
131
  c_smap = np.ones_like(smap_arr) - smap_arr
 
13
  """
14
 
15
  _KWARGS_DESCRIPTION = """\
16
+ Args:
17
+ predictions (`list` of `list` of `float`): A list of lists of floats representing normalized `ltrb`-format bounding boxes.
18
+ gold_labels (`list` of `list` of `int`): A list of lists of integers representing class labels.
19
+ saliency_maps_1 (`list` of `str`): A list of file paths to the first set of saliency maps (grayscale images).
20
+ saliency_maps_2 (`list` of `str`): A list of file paths to the second set of saliency maps (grayscale images).
21
+ canvas_width (`int`, *optional*): Width of the canvas in pixels. Can be provided at initialization or during computation.
22
+ canvas_height (`int`, *optional*): Height of the canvas in pixels. Can be provided at initialization or during computation.
23
+
24
+ Returns:
25
+ float: The utilization rate of space suitable for arranging elements. Computed as the ratio of elements placed in non-salient regions (the inverse of the saliency map). Higher values indicate better utilization of appropriate space.
26
+
27
+ Examples:
28
+ >>> import evaluate
29
+ >>> metric = evaluate.load("creative-graphic-design/layout-utility")
30
+ >>> predictions = [[[0.1, 0.1, 0.3, 0.3], [0.6, 0.6, 0.9, 0.9]]]
31
+ >>> gold_labels = [[1, 2]]
32
+ >>> saliency_maps_1 = ["/path/to/saliency_map1.png"]
33
+ >>> saliency_maps_2 = ["/path/to/saliency_map2.png"]
34
+ >>> result = metric.compute(
35
+ ... predictions=predictions,
36
+ ... gold_labels=gold_labels,
37
+ ... saliency_maps_1=saliency_maps_1,
38
+ ... saliency_maps_2=saliency_maps_2,
39
+ ... canvas_width=512,
40
+ ... canvas_height=512
41
+ ... )
42
+ >>> print(f"Utility score: {result:.4f}")
43
  """
44
 
45
  _CITATION = """\
 
57
  class LayoutUtility(evaluate.Metric):
58
  def __init__(
59
  self,
60
+ canvas_width: int | None = None,
61
+ canvas_height: int | None = None,
62
  **kwargs,
63
  ) -> None:
64
  super().__init__(**kwargs)
 
86
  def load_saliency_map(
87
  self,
88
  filepath: Union[os.PathLike, List[os.PathLike]],
89
+ canvas_width: int,
90
+ canvas_height: int,
91
  ) -> npt.NDArray[np.float64]:
92
  if isinstance(filepath, list):
93
  assert len(filepath) == 1, filepath
 
96
  map_pil = Image.open(filepath) # type: ignore
97
  map_pil = map_pil.convert("L") # type: ignore
98
 
99
+ if map_pil.size != (canvas_width, canvas_height):
100
+ map_pil = map_pil.resize((canvas_width, canvas_height)) # type: ignore
101
 
102
  map_arr = np.array(map_pil)
103
  map_arr = map_arr / 255.0
104
  return map_arr
105
 
106
  def get_rid_of_invalid(
107
+ self,
108
+ predictions: npt.NDArray[np.float64],
109
+ gold_labels: npt.NDArray[np.int64],
110
+ canvas_width: int,
111
+ canvas_height: int,
112
  ) -> npt.NDArray[np.int64]:
113
  assert len(predictions) == len(gold_labels)
114
 
115
+ w = canvas_width / 100
116
+ h = canvas_height / 100
117
 
118
  for i, prediction in enumerate(predictions):
119
  for j, b in enumerate(prediction):
120
  xl, yl, xr, yr = b
121
  xl = max(0, xl)
122
  yl = max(0, yl)
123
+ xr = min(canvas_width, xr)
124
+ yr = min(canvas_height, yr)
125
  if abs((xr - xl) * (yr - yl)) < w * h * 10:
126
  if gold_labels[i, j]:
127
  gold_labels[i, j] = 0
 
134
  gold_labels: Union[npt.NDArray[np.int64], List[int]],
135
  saliency_maps_1: List[os.PathLike],
136
  saliency_maps_2: List[os.PathLike],
137
+ canvas_width: int | None = None,
138
+ canvas_height: int | None = None,
139
  ) -> float:
140
+ # パラメータの優先順位処理
141
+ canvas_width = canvas_width if canvas_width is not None else self.canvas_width
142
+ canvas_height = (
143
+ canvas_height if canvas_height is not None else self.canvas_height
144
+ )
145
+
146
+ if canvas_width is None or canvas_height is None:
147
+ raise ValueError(
148
+ "canvas_width and canvas_height must be provided either "
149
+ "at initialization or during computation"
150
+ )
151
+
152
  predictions = np.array(predictions)
153
  gold_labels = np.array(gold_labels)
154
 
155
+ predictions[:, :, ::2] *= canvas_width
156
+ predictions[:, :, 1::2] *= canvas_height
157
 
158
  gold_labels = self.get_rid_of_invalid(
159
+ predictions=predictions,
160
+ gold_labels=gold_labels,
161
+ canvas_width=canvas_width,
162
+ canvas_height=canvas_height,
163
  )
164
 
165
  score = []
 
173
  it = zip(predictions, gold_labels, saliency_maps_1, saliency_maps_2)
174
 
175
  for prediction, gold_label, smap_1, smap_2 in it:
176
+ smap_arr_1 = self.load_saliency_map(smap_1, canvas_width, canvas_height)
177
+ smap_arr_2 = self.load_saliency_map(smap_2, canvas_width, canvas_height)
178
 
179
  smap_arr = np.maximum(smap_arr_1, smap_arr_2)
180
  c_smap = np.ones_like(smap_arr) - smap_arr