ImageEditor
Browse files
app.py
CHANGED
|
@@ -87,7 +87,7 @@ def get_heatmaps(source_num, x_coords, y_coords, uploaded_image):
|
|
| 87 |
|
| 88 |
# アップロード画像の前処理
|
| 89 |
if uploaded_image is not None:
|
| 90 |
-
uploaded_image = preprocess_uploaded_image(uploaded_image, image_size)
|
| 91 |
target_feature_map, _ = model(uploaded_image)
|
| 92 |
img = torch.cat((img, uploaded_image))
|
| 93 |
feature_map = torch.cat((feature_map, target_feature_map))
|
|
@@ -132,77 +132,6 @@ def get_heatmaps(source_num, x_coords, y_coords, uploaded_image):
|
|
| 132 |
plt.close(fig)
|
| 133 |
return fig
|
| 134 |
|
| 135 |
-
def process_image(cropped_image_data):
|
| 136 |
-
# Base64からPILイメージに変換
|
| 137 |
-
header, base64_data = cropped_image_data.split(',', 1)
|
| 138 |
-
image_data = base64.b64decode(base64_data)
|
| 139 |
-
image = Image.open(BytesIO(image_data))
|
| 140 |
-
return image
|
| 141 |
-
|
| 142 |
-
# JavaScriptコード
|
| 143 |
-
scripts = """
|
| 144 |
-
async () => {
|
| 145 |
-
const script = document.createElement("script");
|
| 146 |
-
script.src = "https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js";
|
| 147 |
-
document.head.appendChild(script);
|
| 148 |
-
|
| 149 |
-
const style = document.createElement("link");
|
| 150 |
-
style.rel = "stylesheet";
|
| 151 |
-
style.href = "https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css";
|
| 152 |
-
document.head.appendChild(style);
|
| 153 |
-
|
| 154 |
-
script.onload = () => {
|
| 155 |
-
let cropper;
|
| 156 |
-
|
| 157 |
-
document.getElementById("input_file_button").onclick = function() {
|
| 158 |
-
document.querySelector("#input_file").click();
|
| 159 |
-
};
|
| 160 |
-
|
| 161 |
-
document.querySelector("#input_file").addEventListener("change", function(e) {
|
| 162 |
-
const files = e.target.files;
|
| 163 |
-
console.log(files);
|
| 164 |
-
if (files && files.length > 0) {
|
| 165 |
-
console.log("File selected");
|
| 166 |
-
document.querySelector("#input_file_button").style.display = "none";
|
| 167 |
-
document.querySelector("#crop_view").style.display = "block";
|
| 168 |
-
document.querySelector("#crop_button").style.display = "block";
|
| 169 |
-
const url = URL.createObjectURL(files[0]);
|
| 170 |
-
const crop_view = document.getElementById("crop_view");
|
| 171 |
-
crop_view.src = url;
|
| 172 |
-
|
| 173 |
-
if (cropper) {
|
| 174 |
-
cropper.destroy();
|
| 175 |
-
}
|
| 176 |
-
cropper = new Cropper(crop_view, {
|
| 177 |
-
aspectRatio: 1,
|
| 178 |
-
viewMode: 1,
|
| 179 |
-
});
|
| 180 |
-
}
|
| 181 |
-
});
|
| 182 |
-
|
| 183 |
-
document.getElementById("crop_button").onclick = function() {
|
| 184 |
-
if (cropper) {
|
| 185 |
-
const canvas = cropper.getCroppedCanvas();
|
| 186 |
-
const croppedImageData = canvas.toDataURL();
|
| 187 |
-
|
| 188 |
-
// Gradioにクロップ画像を送信
|
| 189 |
-
const textbox = document.querySelector("#cropped_image_data textarea");
|
| 190 |
-
textbox.value = croppedImageData;
|
| 191 |
-
textbox.dispatchEvent(new Event("input", { bubbles: true }));
|
| 192 |
-
|
| 193 |
-
document.getElementById("crop_view").style.display = "none";
|
| 194 |
-
document.getElementById("crop_button").style.display = "none";
|
| 195 |
-
document.querySelector("#input_file_button").style.display = "block";
|
| 196 |
-
|
| 197 |
-
cropper.destroy();
|
| 198 |
-
}
|
| 199 |
-
};
|
| 200 |
-
document.getElementById("crop_view").style.display = "none";
|
| 201 |
-
document.getElementById("crop_button").style.display = "none";
|
| 202 |
-
};
|
| 203 |
-
}
|
| 204 |
-
"""
|
| 205 |
-
|
| 206 |
with gr.Blocks() as demo:
|
| 207 |
# title
|
| 208 |
gr.Markdown("# TripletGeoEncoder Feature Map Visualization")
|
|
@@ -214,44 +143,28 @@ with gr.Blocks() as demo:
|
|
| 214 |
|
| 215 |
"For further information, please contact me on X (formerly Twitter): @Yeq6X.")
|
| 216 |
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
inputs=[input_image],
|
| 240 |
-
)
|
| 241 |
-
with gr.Column():
|
| 242 |
-
output_plot = gr.Plot()
|
| 243 |
-
|
| 244 |
-
# ヒートマップの更新
|
| 245 |
-
source_num.change(get_heatmaps, inputs=[source_num, x_coords, y_coords, input_image], outputs=output_plot)
|
| 246 |
-
x_coords.change(get_heatmaps, inputs=[source_num, x_coords, y_coords, input_image], outputs=output_plot)
|
| 247 |
-
y_coords.change(get_heatmaps, inputs=[source_num, x_coords, y_coords, input_image], outputs=output_plot)
|
| 248 |
-
|
| 249 |
-
def change_input_image_hanlder(source_num, x_coords, y_coords, input_image):
|
| 250 |
-
visible = False if input_image is None else True
|
| 251 |
-
return get_heatmaps(source_num, x_coords, y_coords, input_image), gr.Image(visible=visible, label="Cropped Image", elem_id="input_image")
|
| 252 |
-
input_image.change(change_input_image_hanlder, inputs=[source_num, x_coords, y_coords, input_image], outputs=[output_plot, input_image])
|
| 253 |
-
|
| 254 |
# JavaScriptコードをロード
|
| 255 |
-
demo.load(None, None, None, js=scripts)
|
| 256 |
demo.launch()
|
| 257 |
|
|
|
|
| 87 |
|
| 88 |
# アップロード画像の前処理
|
| 89 |
if uploaded_image is not None:
|
| 90 |
+
uploaded_image = preprocess_uploaded_image(uploaded_image['composite'], image_size)
|
| 91 |
target_feature_map, _ = model(uploaded_image)
|
| 92 |
img = torch.cat((img, uploaded_image))
|
| 93 |
feature_map = torch.cat((feature_map, target_feature_map))
|
|
|
|
| 132 |
plt.close(fig)
|
| 133 |
return fig
|
| 134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
with gr.Blocks() as demo:
|
| 136 |
# title
|
| 137 |
gr.Markdown("# TripletGeoEncoder Feature Map Visualization")
|
|
|
|
| 143 |
|
| 144 |
"For further information, please contact me on X (formerly Twitter): @Yeq6X.")
|
| 145 |
|
| 146 |
+
input_image = gr.ImageEditor(label="Cropped Image", elem_id="input_image", crop_size=(112, 112), show_fullscreen_button=True)
|
| 147 |
+
gr.Interface(
|
| 148 |
+
get_heatmaps,
|
| 149 |
+
inputs=[
|
| 150 |
+
gr.Slider(0, batch_size - 1, step=1, label="Source Image Index"),
|
| 151 |
+
gr.Slider(0, image_size - 1, step=1, value=image_size // 2, label="X Coordinate"),
|
| 152 |
+
gr.Slider(0, image_size - 1, step=1, value=image_size // 2, label="Y Coordinate"),
|
| 153 |
+
input_image
|
| 154 |
+
],
|
| 155 |
+
outputs="plot",
|
| 156 |
+
live=True,
|
| 157 |
+
)
|
| 158 |
+
# examples
|
| 159 |
+
gr.Markdown("# Examples")
|
| 160 |
+
gr.Examples(
|
| 161 |
+
examples=[
|
| 162 |
+
["resources/examples/2488.jpg"],
|
| 163 |
+
["resources/examples/2899.jpg"]
|
| 164 |
+
],
|
| 165 |
+
inputs=[input_image],
|
| 166 |
+
)
|
| 167 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
# JavaScriptコードをロード
|
|
|
|
| 169 |
demo.launch()
|
| 170 |
|