| import gradio as gr |
| import cv2 |
| import numpy as np |
| from PIL import Image |
| import os |
|
|
| TILE_SIZE = 1024 |
| 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) |
|
|
| annotated, tiles = make_tiles(img, TILE_SIZE) |
| tiles_cache["tiles"] = [] |
|
|
| for idx, (coords, tile) in enumerate(tiles): |
| tile_path = os.path.join(TILE_FOLDER, f"tile_{idx}.png") |
| Image.fromarray(tile).save(tile_path) |
| tiles_cache["tiles"].append((coords, tile_path)) |
|
|
| tiles_cache["selected_tile"] = None |
| return annotated, gr.update(interactive=False) |
|
|
| def select_tile(evt: gr.SelectData,state): |
| |
| 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] |
|
|
| |
| tiles_cache["selected_tile"] = { |
| "tile_path": tile_path, |
| "coords": coords |
| } |
|
|
| updated_state = { |
| "tile_path": tile_path, |
| "coords": coords |
| } |
|
|
| |
| 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(): |
| |
| 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") |
| |
|
|
| |
| 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") |
| |
| |
| 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") |
|
|
| |
| |
|
|
|
|
| |
| 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 |