histOSM / inference_tab /inference_setup.py
muk42's picture
marginalized blobs with marginalized tiles
9531418
Raw History Blame Contribute Delete
5.73 kB
import gradio as gr
import cv2
import numpy as np
from PIL import Image
import os
TILE_SIZE = 1024
MARGIN_TILE = 150
TILE_FOLDER = "tiles"
os.makedirs(TILE_FOLDER, exist_ok=True)
tiles_cache = {"tiles": [], "selected_tile": None}
def make_tiles(image, tile_size=TILE_SIZE):
h, w, _ = image.shape
annotated = image.copy()
tiles = []
tile_id = 0
for y in range(0, h, tile_size):
for x in range(0, w, tile_size):
tile = image[y:y+tile_size, x:x+tile_size]
tiles.append(((x, y, x+tile_size, y+tile_size), tile))
cv2.rectangle(annotated, (x, y), (x+tile_size, y+tile_size), (255,0,0), 2)
cv2.putText(annotated, str(tile_id), (x+50, y+50),
cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,0), 5)
tile_id += 1
return annotated, tiles
def create_tiles(image_file):
img = Image.open(image_file.name).convert("RGB")
img = np.array(img)
H, W, _ = img.shape
annotated, tiles = make_tiles(img, TILE_SIZE)
tiles_cache["tiles"] = []
for idx, (coords, tile) in enumerate(tiles):
x, y, x_end, y_end = coords
tile_path = os.path.join(TILE_FOLDER, f"tile_{idx}.png")
Image.fromarray(tile).save(tile_path)
# Marginalized tile
x_m = max(0, x - MARGIN_TILE)
y_m = max(0, y - MARGIN_TILE)
x_end_m = min(W, x_end + MARGIN_TILE)
y_end_m = min(H, y_end + MARGIN_TILE)
tile_margin = img[y_m:y_end_m, x_m:x_end_m]
tile_margin_path = os.path.join(TILE_FOLDER, f"tile_{idx}_margin.png")
Image.fromarray(tile_margin).save(tile_margin_path)
tiles_cache["tiles"].append((coords, tile_path)) # store path instead of array
tiles_cache["selected_tile"] = None
return annotated, gr.update(interactive=False)
def select_tile(evt: gr.SelectData,state):
# compute tile index
if not tiles_cache["tiles"]:
return None, gr.update(interactive=False), state
num_tiles_x = (tiles_cache["tiles"][-1][0][2]) // TILE_SIZE
tile_id = (evt.index[1] // TILE_SIZE) * num_tiles_x + (evt.index[0] // TILE_SIZE)
if 0 <= tile_id < len(tiles_cache["tiles"]):
coords, tile_path = tiles_cache["tiles"][tile_id]
# store the path, not the array
tiles_cache["selected_tile"] = {
"tile_path": tile_path,
"coords": coords
}
updated_state = {
"tile_path": tile_path,
"coords": coords
}
# load tile only for display
tile_array = np.array(Image.open(tile_path))
cv2.putText(tile_array, str(tile_id), (100, 100),
cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,0), 4, cv2.LINE_AA)
return tile_array, gr.update(interactive=True),updated_state
return None, gr.update(interactive=False), state
def enable_textbox(file):
return gr.update(interactive=bool(file))
def get_inference_widgets(run_inference,georefImg,selected_tile_state):
with gr.Row():
# Left column
with gr.Column(scale=1,min_width=500):
annotated_out = gr.Image(
type="numpy", label="City Map",
height=500, width=500
)
image_input = gr.File(label="Select Image File")
gcp_input = gr.File(label="Select GCP Points File", file_types=[".points"])
city_name = gr.Textbox(label="Enter city name")
user_crs = gr.Textbox(label="Enter CRS for the GCP",value="3395")
create_btn = gr.Button("Create Tiles")
georef_btn = gr.Button("Georeference Full Map")
# Right column
with gr.Column(scale=1):
selected_tile = gr.Image(
type="numpy", label="Selected Tile",
height=500, width=500
)
score_th = gr.Textbox(label="Score threshold below which to annotate manually (OSM)",
info="Computes fuzzy match of the detected street names with OSM street names within 100m buffer")
# Historic dictionary of street names and matching score threshold
hist_dic = gr.File(label="Upload csv with historic street names",file_types=[".csv"])
hist_th = gr.Textbox(label="Score threshold below which to annotate manually (Directory)",
info="Computes fuzzy match of the detected street names with the historic street names",
interactive=False)
hist_dic.change(enable_textbox, inputs=hist_dic, outputs=hist_th)
run_button = gr.Button("Run Inference", interactive=False)
output = gr.Textbox(label="Progress", lines=5, interactive=False)
download_file = gr.File(label="Download CSV",
file_types=[".csv"],
type="filepath")
# pass globally instead
#selected_tile_state = gr.State()
# Wire events
create_btn.click(
fn=create_tiles, inputs=image_input,
outputs=[annotated_out, run_button]
)
annotated_out.select(
fn=select_tile, inputs=[selected_tile_state],
outputs=[selected_tile, run_button, selected_tile_state]
)
run_button.click(
fn=run_inference,
inputs=[selected_tile_state, gcp_input,user_crs, city_name, score_th, hist_th,hist_dic],
outputs=[output, download_file]
)
georef_btn.click(
fn=georefImg,
inputs=[image_input, gcp_input,user_crs],
outputs=[output]
)
return image_input, gcp_input, city_name, user_crs, score_th, hist_th,hist_dic, run_button, output, download_file