Paul-Edouard Sarlin commited on
Commit
57d7f45
·
unverified ·
1 Parent(s): c5e08dd

Add Gradio demo (#54)

Browse files
Files changed (1) hide show
  1. app.py +127 -0
app.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import matplotlib.pyplot as plt
3
+
4
+ from maploc.demo import Demo
5
+ from maploc.osm.tiling import TileManager
6
+ from maploc.osm.viz import Colormap, GeoPlotter, plot_nodes
7
+ from maploc.utils.viz_2d import features_to_RGB, plot_images
8
+ from maploc.utils.viz_localization import (
9
+ add_circle_inset,
10
+ likelihood_overlay,
11
+ plot_dense_rotations,
12
+ )
13
+
14
+
15
+ def run(image, address, tile_size_meters, num_rotations):
16
+ image_path = image.name
17
+ demo = Demo(num_rotations=int(num_rotations))
18
+
19
+ try:
20
+ image, camera, gravity, proj, bbox = demo.read_input_image(
21
+ image_path,
22
+ prior_address=address or None,
23
+ tile_size_meters=int(tile_size_meters),
24
+ )
25
+ except ValueError as e:
26
+ raise gr.Error(str(e))
27
+
28
+ tiler = TileManager.from_bbox(proj, bbox + 10, demo.config.data.pixel_per_meter)
29
+ canvas = tiler.query(bbox)
30
+ map_viz = Colormap.apply(canvas.raster)
31
+
32
+ plot_images([image, map_viz], titles=["input image", "OpenStreetMap raster"], pad=2)
33
+ plot_nodes(1, canvas.raster[2], fontsize=6, size=10)
34
+ fig1 = plt.gcf()
35
+
36
+ # Run the inference
37
+ try:
38
+ uv, yaw, prob, neural_map, image_rectified = demo.localize(
39
+ image, camera, canvas, gravity=gravity
40
+ )
41
+ except RuntimeError as e:
42
+ raise gr.Error(str(e))
43
+
44
+ # Visualize the predictions
45
+ overlay = likelihood_overlay(prob.numpy().max(-1), map_viz.mean(-1, keepdims=True))
46
+ (neural_map_rgb,) = features_to_RGB(neural_map.numpy())
47
+ plot_images([overlay, neural_map_rgb], titles=["heatmap", "neural map"], pad=2)
48
+ ax = plt.gcf().axes[0]
49
+ ax.scatter(*canvas.to_uv(bbox.center), s=5, c="red")
50
+ plot_dense_rotations(ax, prob, w=0.005, s=1 / 25)
51
+ add_circle_inset(ax, uv)
52
+ fig2 = plt.gcf()
53
+
54
+ # Plot as interactive figure
55
+ latlon = proj.unproject(canvas.to_xy(uv))
56
+ bbox_latlon = proj.unproject(canvas.bbox)
57
+ plot = GeoPlotter(zoom=16.5)
58
+ plot.raster(map_viz, bbox_latlon, opacity=0.5)
59
+ plot.raster(likelihood_overlay(prob.numpy().max(-1)), proj.unproject(bbox))
60
+ plot.points(proj.latlonalt[:2], "red", name="location prior", size=10)
61
+ plot.points(latlon, "black", name="argmax", size=10, visible="legendonly")
62
+ plot.bbox(bbox_latlon, "blue", name="map tile")
63
+
64
+ coordinates = f"(latitude, longitude) = {tuple(latlon)}\nheading angle = {yaw:.2f}°"
65
+ return fig1, fig2, plot.fig, coordinates
66
+
67
+
68
+ examples = [
69
+ ["assets/query_zurich_1.JPG", "ETH CAB Zurich", 128, 256],
70
+ ["assets/query_vancouver_1.JPG", "Vancouver Waterfront Station", 128, 256],
71
+ ["assets/query_vancouver_2.JPG", None, 128, 256],
72
+ ["assets/query_vancouver_3.JPG", None, 128, 256],
73
+ ]
74
+
75
+ description = """
76
+ <h1 align="center">
77
+ <ins>OrienterNet</ins>
78
+ <br>
79
+ Visual Localization in 2D Public Maps
80
+ <br>
81
+ with Neural Matching</h1>
82
+ <h3 align="center">
83
+ <a href="https://psarlin.com/orienternet" target="_blank">Project Page</a> |
84
+ <a href="https://arxiv.org/pdf/2304.02009.pdf" target="_blank">Paper</a> |
85
+ <a href="https://github.com/facebookresearch/OrienterNet" target="_blank">Code</a> |
86
+ <a href="https://youtu.be/wglW8jnupSs" target="_blank">Video</a>
87
+ </h3>
88
+ <p align="center">
89
+ OrienterNet finds the position and orientation of any image using OpenStreetMap.
90
+ Click on one of the provided examples or upload your own image!
91
+ </p>
92
+ """
93
+
94
+ app = gr.Interface(
95
+ fn=run,
96
+ inputs=[
97
+ gr.File(file_types=["image"]),
98
+ gr.Textbox(
99
+ label="Prior location (optional)",
100
+ info="Required if the image metadata (EXIF) does not contain a GPS prior. "
101
+ "Enter an address or a street or building name.",
102
+ ),
103
+ gr.Radio(
104
+ [64, 128, 256, 512],
105
+ value=128,
106
+ label="Search radius (meters)",
107
+ info="Depends on how coarse the prior location is.",
108
+ ),
109
+ gr.Radio(
110
+ [64, 128, 256, 360],
111
+ value=256,
112
+ label="Number of rotations",
113
+ info="Reduce to scale to larger areas.",
114
+ ),
115
+ ],
116
+ outputs=[
117
+ gr.Plot(label="Inputs"),
118
+ gr.Plot(label="Outputs"),
119
+ gr.Plot(label="Interactive map"),
120
+ gr.Textbox(label="Predicted coordinates"),
121
+ ],
122
+ description=description,
123
+ examples=examples,
124
+ cache_examples=True,
125
+ )
126
+
127
+ app.launch(share=False)