clement-bonnet commited on
Commit
e1b10c7
·
1 Parent(s): 4754e4d

feat: resize page

Browse files
Files changed (1) hide show
  1. app.py +151 -132
app.py CHANGED
@@ -8,9 +8,7 @@ TASK_OPTIMAL_COORDS = {0: (325, 326), 1: (59, 1126), 2: (47, 102), 3: (497, 933)
8
 
9
 
10
  def create_marker_overlay(image_path: str, x: int, y: int) -> Image.Image:
11
- """
12
- Creates an image with a marker at the specified coordinates
13
- """
14
  base_image = Image.open(image_path)
15
  marked_image = base_image.copy()
16
  draw = ImageDraw.Draw(marked_image)
@@ -22,39 +20,24 @@ def create_marker_overlay(image_path: str, x: int, y: int) -> Image.Image:
22
 
23
 
24
  def update_reference_image(choice: int) -> tuple[str, int, str]:
25
- """
26
- Update the reference image display based on radio button selection
27
- Returns the image path, selected index, and corresponding heatmap
28
- """
29
  image_path = f"imgs/pattern_{choice}.png"
30
  heatmap_path = f"imgs/heatmap_{choice}.png"
31
  return image_path, choice, heatmap_path
32
 
33
 
34
  def update_marker(image_idx: int, evt: gr.SelectData) -> tuple[Image.Image, tuple[int, int]]:
35
- """
36
- Update the coordinate selector with the marker
37
- Returns the marked image and the coordinates for the next function
38
- """
39
  x, y = evt.index[0], evt.index[1]
40
  heatmap_path = f"imgs/heatmap_{image_idx}.png"
41
  return create_marker_overlay(heatmap_path, x, y), (x, y)
42
 
43
 
44
  def generate_output_image(image_idx: int, coords: tuple[int, int]) -> Image.Image:
45
- """
46
- Generate the output image based on the selected coordinates
47
- """
48
  x, y = coords
49
  x_norm, y_norm = x / 1155, y / 1155
50
  return generate_image(image_idx, x_norm, y_norm)
51
 
52
 
53
  def find_optimal_latent(image_idx: int) -> tuple[Image.Image, tuple[int, int], Image.Image]:
54
- """
55
- Simulate clicking at the optimal coordinates for the current task
56
- Returns the marked heatmap, coordinates, and generated output image
57
- """
58
  x, y = TASK_OPTIMAL_COORDS[image_idx]
59
  heatmap_path = f"imgs/heatmap_{image_idx}.png"
60
  marked_heatmap = create_marker_overlay(heatmap_path, x, y)
@@ -64,32 +47,69 @@ def find_optimal_latent(image_idx: int) -> tuple[Image.Image, tuple[int, int], I
64
 
65
  with gr.Blocks(
66
  css="""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  .radio-container {
68
- width: 450px !important;
 
69
  margin-left: auto !important;
70
  margin-right: auto !important;
71
  }
 
 
 
 
 
 
 
 
 
 
 
 
72
  .coordinate-container {
73
- width: 600px !important;
74
- height: 600px !important;
75
  position: relative !important;
 
 
 
76
  }
77
  .coordinate-container img {
78
  width: 100% !important;
79
  height: 100% !important;
80
  object-fit: contain !important;
81
  }
 
 
 
 
 
 
 
 
82
  .documentation {
83
  margin-top: 2rem !important;
84
  padding: 1rem !important;
85
  background-color: #f8f9fa !important;
86
  border-radius: 8px !important;
87
  }
88
- .button-container {
89
- display: flex !important;
90
- justify-content: center !important;
91
- width: 600px !important;
92
- }
93
  .optimal-button {
94
  margin-top: 1rem !important;
95
  margin-bottom: 1rem !important;
@@ -97,124 +117,123 @@ with gr.Blocks(
97
  }
98
  """
99
  ) as demo:
100
- gr.Markdown(
101
- """
102
- # Interactive Image Generation
103
-
104
- ## Method Overview
105
- This interactive demo showcases our novel image generation method that uses coordinate-based control.
106
- The process allows precise control over generated patterns through a coordinate-conditioning mechanism.
107
- """
108
- )
109
-
110
- # Add the diagram at the top
111
- gr.Image(
112
- value="imgs/lpn_diagram.png",
113
- show_label=False,
114
- interactive=False,
115
- show_download_button=False,
116
- show_fullscreen_button=False,
117
- )
118
-
119
- gr.Markdown(
120
- """
121
- ### How to Use
122
- 1. Choose a pattern generation task using the radio buttons
123
- 2. View the target pattern for your selected task
124
- 3. Click anywhere in the heatmap to specify coordinates in the latent space
125
- 4. See the generated image based on your selection
126
-
127
- Use the "Find Optimal Latent" button to automatically select pre-determined optimal coordinates.
128
- """
129
- )
130
-
131
- with gr.Row():
132
- # Left column
133
- with gr.Column(scale=3):
134
- selected_idx = gr.State(value=0)
135
- coords = gr.State()
136
-
137
- with gr.Column(elem_classes="radio-container"):
138
- task_select = gr.Radio(
139
- choices=["Task 1", "Task 2", "Task 3", "Task 4"],
140
- value="Task 1",
141
- label="Select Task",
142
- interactive=True,
143
- )
144
 
145
- gr.Markdown("### Reference Pattern")
146
- reference_image = gr.Image(
147
- value="imgs/pattern_0.png",
148
  show_label=False,
149
  interactive=False,
150
- height=300,
151
- width=450,
152
  show_download_button=False,
153
  show_fullscreen_button=False,
154
  )
155
 
156
- gr.Markdown("### Generated Output")
157
- output_image = gr.Image(
158
- show_label=False,
159
- height=300,
160
- width=450,
161
- show_download_button=False,
162
- show_fullscreen_button=False,
163
- interactive=False,
164
- )
 
 
165
 
166
- # Right column
167
- with gr.Column(scale=4):
168
- gr.Markdown("### Coordinate Selector")
169
- gr.Markdown("Click anywhere in the image below to select (x, y) coordinates in the latent space")
170
- with gr.Column(elem_classes="coordinate-container"):
171
- coord_selector = gr.Image(
172
- value="imgs/heatmap_0.png",
173
- show_label=False,
174
- interactive=False,
175
- sources=[],
176
- container=True,
177
- show_download_button=False,
178
- show_fullscreen_button=False,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  )
180
 
181
- with gr.Column(elem_classes="button-container"):
182
- optimal_button = gr.Button("Find Optimal Latent", elem_classes="optimal-button")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
- # Footer with additional information
185
- with gr.Column(elem_classes="documentation"):
186
- gr.Markdown(
187
- """
188
- ### Technical Details
189
- Our approach uses a novel coordinate-conditioning mechanism that allows precise control over the generated patterns.
190
- The heatmap visualization shows the distribution of pattern characteristics across the latent space.
191
-
192
- For more information, please refer to our [paper](https://arxiv.org/pdf/2411.08706) or GitHub [repository](https://github.com/clement-bonnet/lpn).
193
- """
194
  )
195
 
196
- # Event handlers
197
- task_select.change(
198
- fn=lambda x: update_reference_image(TASK_TO_INDEX[x]),
199
- inputs=[task_select],
200
- outputs=[reference_image, selected_idx, coord_selector],
201
- )
202
-
203
- coord_selector.select(
204
- fn=update_marker,
205
- inputs=[selected_idx],
206
- outputs=[coord_selector, coords],
207
- trigger_mode="multiple",
208
- ).then(
209
- fn=generate_output_image,
210
- inputs=[selected_idx, coords],
211
- outputs=output_image,
212
- )
213
-
214
- optimal_button.click(
215
- fn=find_optimal_latent,
216
- inputs=[selected_idx],
217
- outputs=[coord_selector, coords, output_image],
218
- )
219
 
220
  demo.launch()
 
8
 
9
 
10
  def create_marker_overlay(image_path: str, x: int, y: int) -> Image.Image:
11
+ """Creates an image with a marker at the specified coordinates"""
 
 
12
  base_image = Image.open(image_path)
13
  marked_image = base_image.copy()
14
  draw = ImageDraw.Draw(marked_image)
 
20
 
21
 
22
  def update_reference_image(choice: int) -> tuple[str, int, str]:
 
 
 
 
23
  image_path = f"imgs/pattern_{choice}.png"
24
  heatmap_path = f"imgs/heatmap_{choice}.png"
25
  return image_path, choice, heatmap_path
26
 
27
 
28
  def update_marker(image_idx: int, evt: gr.SelectData) -> tuple[Image.Image, tuple[int, int]]:
 
 
 
 
29
  x, y = evt.index[0], evt.index[1]
30
  heatmap_path = f"imgs/heatmap_{image_idx}.png"
31
  return create_marker_overlay(heatmap_path, x, y), (x, y)
32
 
33
 
34
  def generate_output_image(image_idx: int, coords: tuple[int, int]) -> Image.Image:
 
 
 
35
  x, y = coords
36
  x_norm, y_norm = x / 1155, y / 1155
37
  return generate_image(image_idx, x_norm, y_norm)
38
 
39
 
40
  def find_optimal_latent(image_idx: int) -> tuple[Image.Image, tuple[int, int], Image.Image]:
 
 
 
 
41
  x, y = TASK_OPTIMAL_COORDS[image_idx]
42
  heatmap_path = f"imgs/heatmap_{image_idx}.png"
43
  marked_heatmap = create_marker_overlay(heatmap_path, x, y)
 
47
 
48
  with gr.Blocks(
49
  css="""
50
+ .container {
51
+ max-width: 1000px !important;
52
+ width: 100% !important;
53
+ margin-left: auto !important;
54
+ margin-right: auto !important;
55
+ padding: 0 1rem !important;
56
+ }
57
+ .diagram-container {
58
+ width: 80% !important;
59
+ max-width: 800px !important;
60
+ margin-left: auto !important;
61
+ margin-right: auto !important;
62
+ }
63
+ .diagram-container img {
64
+ width: 100% !important;
65
+ height: auto !important;
66
+ object-fit: contain !important;
67
+ }
68
  .radio-container {
69
+ width: 100% !important;
70
+ max-width: 450px !important;
71
  margin-left: auto !important;
72
  margin-right: auto !important;
73
  }
74
+ .image-container {
75
+ width: 100% !important;
76
+ aspect-ratio: 1 !important;
77
+ max-width: 450px !important;
78
+ margin-left: auto !important;
79
+ margin-right: auto !important;
80
+ }
81
+ .image-container img {
82
+ width: 100% !important;
83
+ height: 100% !important;
84
+ object-fit: contain !important;
85
+ }
86
  .coordinate-container {
87
+ width: 100% !important;
88
+ aspect-ratio: 1 !important;
89
  position: relative !important;
90
+ max-width: 600px !important;
91
+ margin-left: auto !important;
92
+ margin-right: auto !important;
93
  }
94
  .coordinate-container img {
95
  width: 100% !important;
96
  height: 100% !important;
97
  object-fit: contain !important;
98
  }
99
+ .button-container {
100
+ display: flex !important;
101
+ justify-content: center !important;
102
+ width: 100% !important;
103
+ max-width: 600px !important;
104
+ margin-left: auto !important;
105
+ margin-right: auto !important;
106
+ }
107
  .documentation {
108
  margin-top: 2rem !important;
109
  padding: 1rem !important;
110
  background-color: #f8f9fa !important;
111
  border-radius: 8px !important;
112
  }
 
 
 
 
 
113
  .optimal-button {
114
  margin-top: 1rem !important;
115
  margin-bottom: 1rem !important;
 
117
  }
118
  """
119
  ) as demo:
120
+ with gr.Column(elem_classes="container"):
121
+ gr.Markdown(
122
+ """
123
+ # Interactive Image Generation
124
+
125
+ ## Method Overview
126
+ This interactive demo showcases our novel image generation method that uses coordinate-based control.
127
+ The process allows precise control over generated patterns through a coordinate-conditioning mechanism.
128
+ """
129
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ with gr.Column(elem_classes="diagram-container"):
132
+ gr.Image(
133
+ value="imgs/lpn_diagram.png",
134
  show_label=False,
135
  interactive=False,
 
 
136
  show_download_button=False,
137
  show_fullscreen_button=False,
138
  )
139
 
140
+ gr.Markdown(
141
+ """
142
+ ### How to Use
143
+ 1. Choose a pattern generation task using the radio buttons
144
+ 2. View the target pattern for your selected task
145
+ 3. Click anywhere in the heatmap to specify coordinates in the latent space
146
+ 4. See the generated image based on your selection
147
+
148
+ Use the "Find Optimal Latent" button to automatically select pre-determined optimal coordinates.
149
+ """
150
+ )
151
 
152
+ with gr.Row():
153
+ with gr.Column(scale=3):
154
+ selected_idx = gr.State(value=0)
155
+ coords = gr.State()
156
+
157
+ with gr.Column(elem_classes="radio-container"):
158
+ task_select = gr.Radio(
159
+ choices=["Task 1", "Task 2", "Task 3", "Task 4"],
160
+ value="Task 1",
161
+ label="Select Task",
162
+ interactive=True,
163
+ )
164
+
165
+ gr.Markdown("### Reference Pattern")
166
+ with gr.Column(elem_classes="image-container"):
167
+ reference_image = gr.Image(
168
+ value="imgs/pattern_0.png",
169
+ show_label=False,
170
+ interactive=False,
171
+ show_download_button=False,
172
+ show_fullscreen_button=False,
173
+ )
174
+
175
+ gr.Markdown("### Generated Output")
176
+ with gr.Column(elem_classes="image-container"):
177
+ output_image = gr.Image(
178
+ show_label=False,
179
+ interactive=False,
180
+ show_download_button=False,
181
+ show_fullscreen_button=False,
182
+ )
183
+
184
+ with gr.Column(scale=4):
185
+ gr.Markdown("### Coordinate Selector")
186
+ gr.Markdown(
187
+ "Click anywhere in the image below to select (x, y) coordinates in the latent space"
188
  )
189
 
190
+ with gr.Column(elem_classes="coordinate-container"):
191
+ coord_selector = gr.Image(
192
+ value="imgs/heatmap_0.png",
193
+ show_label=False,
194
+ interactive=False,
195
+ sources=[],
196
+ container=True,
197
+ show_download_button=False,
198
+ show_fullscreen_button=False,
199
+ )
200
+
201
+ with gr.Column(elem_classes="button-container"):
202
+ optimal_button = gr.Button("Find Optimal Latent", elem_classes="optimal-button")
203
+
204
+ with gr.Column(elem_classes="documentation"):
205
+ gr.Markdown(
206
+ """
207
+ ### Technical Details
208
+ Our approach uses a novel coordinate-conditioning mechanism that allows precise control over the generated patterns.
209
+ The heatmap visualization shows the distribution of pattern characteristics across the latent space.
210
+
211
+ For more information, please refer to our [paper](https://arxiv.org/pdf/2411.08706) or GitHub [repository](https://github.com/clement-bonnet/lpn).
212
+ """
213
+ )
214
 
215
+ # Event handlers
216
+ task_select.change(
217
+ fn=lambda x: update_reference_image(TASK_TO_INDEX[x]),
218
+ inputs=[task_select],
219
+ outputs=[reference_image, selected_idx, coord_selector],
 
 
 
 
 
220
  )
221
 
222
+ coord_selector.select(
223
+ fn=update_marker,
224
+ inputs=[selected_idx],
225
+ outputs=[coord_selector, coords],
226
+ trigger_mode="multiple",
227
+ ).then(
228
+ fn=generate_output_image,
229
+ inputs=[selected_idx, coords],
230
+ outputs=output_image,
231
+ )
232
+
233
+ optimal_button.click(
234
+ fn=find_optimal_latent,
235
+ inputs=[selected_idx],
236
+ outputs=[coord_selector, coords, output_image],
237
+ )
 
 
 
 
 
 
 
238
 
239
  demo.launch()