shunk031 commited on
Commit
8331aa5
·
1 Parent(s): 88e5528

deploy: fb8481effdf5a0b23ff86fad414906046d7620bd

Browse files
Files changed (1) hide show
  1. layout-non-alignment.py +52 -15
layout-non-alignment.py CHANGED
@@ -12,7 +12,23 @@ Computes the extent of spatial non-alignment between elements.
12
  """
13
 
14
  _KWARGS_DESCRIPTION = """\
15
- FIXME
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  """
17
 
18
  _CITATION = """\
@@ -40,8 +56,8 @@ _CITATION = """\
40
  class LayoutNonAlignment(evaluate.Metric):
41
  def __init__(
42
  self,
43
- canvas_width: int,
44
- canvas_height: int,
45
  **kwargs,
46
  ) -> None:
47
  super().__init__(**kwargs)
@@ -77,20 +93,24 @@ class LayoutNonAlignment(evaluate.Metric):
77
  return -math.log(1 - x, 10)
78
 
79
  def get_rid_of_invalid(
80
- self, predictions: npt.NDArray[np.float64], gold_labels: npt.NDArray[np.int64]
 
 
 
 
81
  ) -> npt.NDArray[np.int64]:
82
  assert len(predictions) == len(gold_labels)
83
 
84
- w = self.canvas_width / 100
85
- h = self.canvas_height / 100
86
 
87
  for i, prediction in enumerate(predictions):
88
  for j, b in enumerate(prediction):
89
  xl, yl, xr, yr = b
90
  xl = max(0, xl)
91
  yl = max(0, yl)
92
- xr = min(self.canvas_width, xr)
93
- yr = min(self.canvas_height, yr)
94
  if abs((xr - xl) * (yr - yl)) < w * h * 10:
95
  if gold_labels[i, j]:
96
  gold_labels[i, j] = 0
@@ -101,15 +121,32 @@ class LayoutNonAlignment(evaluate.Metric):
101
  *,
102
  predictions: Union[npt.NDArray[np.float64], List[List[float]]],
103
  gold_labels: Union[npt.NDArray[np.int64], List[int]],
 
 
104
  ) -> float:
 
 
 
 
 
 
 
 
 
 
 
 
105
  predictions = np.array(predictions)
106
  gold_labels = np.array(gold_labels)
107
 
108
- predictions[:, :, ::2] *= self.canvas_width
109
- predictions[:, :, 1::2] *= self.canvas_height
110
 
111
  gold_labels = self.get_rid_of_invalid(
112
- predictions=predictions, gold_labels=gold_labels
 
 
 
113
  )
114
 
115
  metrics: float = 0.0
@@ -121,10 +158,10 @@ class LayoutNonAlignment(evaluate.Metric):
121
  theda = []
122
  for mb in mask_box:
123
  pos = copy.deepcopy(mb)
124
- pos[0] /= self.canvas_width
125
- pos[2] /= self.canvas_width
126
- pos[1] /= self.canvas_height
127
- pos[3] /= self.canvas_height
128
  theda.append(
129
  [
130
  pos[0],
 
12
  """
13
 
14
  _KWARGS_DESCRIPTION = """\
15
+ Args:
16
+ predictions (`list` of `list` of `float`): A list of lists of floats representing normalized `ltrb`-format bounding boxes.
17
+ gold_labels (`list` of `list` of `int`): A list of lists of integers representing class labels.
18
+ canvas_width (`int`, *optional*): Width of the canvas in pixels. Can be provided at initialization or during computation.
19
+ canvas_height (`int`, *optional*): Height of the canvas in pixels. Can be provided at initialization or during computation.
20
+
21
+ Returns:
22
+ float: The extent of spatial non-alignment between elements. Lower values indicate better alignment. Evaluates alignment across six aspects: left edge, top edge, center X, center Y, right edge, and bottom edge.
23
+
24
+ Examples:
25
+ >>> import evaluate
26
+ >>> metric = evaluate.load("creative-graphic-design/layout-non-alignment")
27
+ >>> # Normalized bounding boxes (left, top, right, bottom)
28
+ >>> predictions = [[[0.1, 0.1, 0.3, 0.3], [0.1, 0.4, 0.3, 0.6]]] # Left-aligned elements
29
+ >>> gold_labels = [[1, 2]]
30
+ >>> result = metric.compute(predictions=predictions, gold_labels=gold_labels, canvas_width=512, canvas_height=512)
31
+ >>> print(f"Non-alignment score: {result:.4f}")
32
  """
33
 
34
  _CITATION = """\
 
56
  class LayoutNonAlignment(evaluate.Metric):
57
  def __init__(
58
  self,
59
+ canvas_width: int | None = None,
60
+ canvas_height: int | None = None,
61
  **kwargs,
62
  ) -> None:
63
  super().__init__(**kwargs)
 
93
  return -math.log(1 - x, 10)
94
 
95
  def get_rid_of_invalid(
96
+ self,
97
+ predictions: npt.NDArray[np.float64],
98
+ gold_labels: npt.NDArray[np.int64],
99
+ canvas_width: int,
100
+ canvas_height: int,
101
  ) -> npt.NDArray[np.int64]:
102
  assert len(predictions) == len(gold_labels)
103
 
104
+ w = canvas_width / 100
105
+ h = canvas_height / 100
106
 
107
  for i, prediction in enumerate(predictions):
108
  for j, b in enumerate(prediction):
109
  xl, yl, xr, yr = b
110
  xl = max(0, xl)
111
  yl = max(0, yl)
112
+ xr = min(canvas_width, xr)
113
+ yr = min(canvas_height, yr)
114
  if abs((xr - xl) * (yr - yl)) < w * h * 10:
115
  if gold_labels[i, j]:
116
  gold_labels[i, j] = 0
 
121
  *,
122
  predictions: Union[npt.NDArray[np.float64], List[List[float]]],
123
  gold_labels: Union[npt.NDArray[np.int64], List[int]],
124
+ canvas_width: int | None = None,
125
+ canvas_height: int | None = None,
126
  ) -> float:
127
+ # パラメータの優先順位処理
128
+ canvas_width = canvas_width if canvas_width is not None else self.canvas_width
129
+ canvas_height = (
130
+ canvas_height if canvas_height is not None else self.canvas_height
131
+ )
132
+
133
+ if canvas_width is None or canvas_height is None:
134
+ raise ValueError(
135
+ "canvas_width and canvas_height must be provided either "
136
+ "at initialization or during computation"
137
+ )
138
+
139
  predictions = np.array(predictions)
140
  gold_labels = np.array(gold_labels)
141
 
142
+ predictions[:, :, ::2] *= canvas_width
143
+ predictions[:, :, 1::2] *= canvas_height
144
 
145
  gold_labels = self.get_rid_of_invalid(
146
+ predictions=predictions,
147
+ gold_labels=gold_labels,
148
+ canvas_width=canvas_width,
149
+ canvas_height=canvas_height,
150
  )
151
 
152
  metrics: float = 0.0
 
158
  theda = []
159
  for mb in mask_box:
160
  pos = copy.deepcopy(mb)
161
+ pos[0] /= canvas_width
162
+ pos[2] /= canvas_width
163
+ pos[1] /= canvas_height
164
+ pos[3] /= canvas_height
165
  theda.append(
166
  [
167
  pos[0],