BilalSardar
commited on
Update app.py
Browse files
app.py
CHANGED
@@ -13,28 +13,11 @@ import asyncio
|
|
13 |
import aiohttp
|
14 |
import io
|
15 |
|
16 |
-
import gradio as gr
|
17 |
-
from PIL import Image
|
18 |
-
import tempfile
|
19 |
-
import os
|
20 |
-
from pathlib import Path
|
21 |
-
import shutil
|
22 |
-
import base64
|
23 |
-
import requests
|
24 |
-
import re
|
25 |
-
import time
|
26 |
-
from PIL import ImageEnhance
|
27 |
-
import concurrent.futures
|
28 |
-
import asyncio
|
29 |
-
import aiohttp
|
30 |
-
import io
|
31 |
-
|
32 |
class StreetViewDownloader:
|
33 |
def __init__(self):
|
34 |
self.headers = {
|
35 |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
36 |
}
|
37 |
-
# Using a smaller session for better connection reuse
|
38 |
self.session = requests.Session()
|
39 |
|
40 |
def extract_panoid(self, url):
|
@@ -43,7 +26,7 @@ class StreetViewDownloader:
|
|
43 |
match = re.search(pattern, url)
|
44 |
if match:
|
45 |
return match.group(1)
|
46 |
-
raise ValueError("Could not find panorama ID in URL")
|
47 |
|
48 |
async def download_tile_async(self, session, panoid, x, y, adjusted_y, zoom, output_dir):
|
49 |
"""Download a single tile asynchronously."""
|
@@ -61,17 +44,11 @@ class StreetViewDownloader:
|
|
61 |
print(f"Error downloading tile {x},{y}: {str(e)}")
|
62 |
return None
|
63 |
|
64 |
-
async def download_tiles_async(self, panoid, output_dir):
|
65 |
-
"""Download tiles asynchronously with
|
66 |
Path(output_dir).mkdir(parents=True, exist_ok=True)
|
67 |
|
68 |
-
#
|
69 |
-
zoom = 2 # Reduced zoom level (less detail but faster)
|
70 |
-
cols = 16 # Reduced number of horizontal tiles
|
71 |
-
rows = 8 # Reduced number of vertical tiles
|
72 |
-
vertical_offset = 2 # Adjusted for the new grid
|
73 |
-
|
74 |
-
print(f"Downloading {cols * rows} tiles for panorama...")
|
75 |
|
76 |
async with aiohttp.ClientSession() as session:
|
77 |
tasks = []
|
@@ -88,9 +65,9 @@ class StreetViewDownloader:
|
|
88 |
|
89 |
return cols, rows, downloaded_tiles
|
90 |
|
91 |
-
def download_tiles(self, panoid, output_dir):
|
92 |
"""Synchronous wrapper for async download."""
|
93 |
-
return asyncio.run(self.download_tiles_async(panoid, output_dir))
|
94 |
|
95 |
def create_360_panorama(self, directory, cols, rows, downloaded_tiles, output_file):
|
96 |
"""Create an equirectangular 360° panorama from tiles with optimized processing."""
|
@@ -110,14 +87,11 @@ class StreetViewDownloader:
|
|
110 |
tile_width, tile_height = valid_tile.size
|
111 |
valid_tile.close()
|
112 |
|
113 |
-
# Create the panorama at optimized resolution
|
114 |
panorama_width = tile_width * cols
|
115 |
panorama_height = tile_height * rows
|
116 |
|
117 |
-
# Use RGB mode directly for better performance
|
118 |
panorama = Image.new('RGB', (panorama_width, panorama_height))
|
119 |
|
120 |
-
# Process tiles in parallel
|
121 |
def process_tile(tile_info):
|
122 |
x, y = tile_info
|
123 |
tile_path = directory / f"tile_{x}_{y}.jpg"
|
@@ -127,28 +101,22 @@ class StreetViewDownloader:
|
|
127 |
return (x * tile_width, y * tile_height, tile.copy())
|
128 |
return None
|
129 |
|
130 |
-
# Use ThreadPoolExecutor for parallel processing
|
131 |
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
|
132 |
tile_results = list(executor.map(process_tile, downloaded_tiles))
|
133 |
|
134 |
-
# Paste all valid tiles
|
135 |
for result in tile_results:
|
136 |
if result:
|
137 |
x, y, tile = result
|
138 |
panorama.paste(tile, (x, y))
|
139 |
tile.close()
|
140 |
|
141 |
-
# Crop out any remaining black regions
|
142 |
bbox = panorama.getbbox()
|
143 |
if bbox:
|
144 |
panorama = panorama.crop(bbox)
|
145 |
|
146 |
-
# Quick enhancement
|
147 |
panorama = self.enhance_panorama(panorama)
|
148 |
-
|
149 |
-
# Save with optimized settings
|
150 |
panorama.save(output_file, 'JPEG', quality=95, optimize=True)
|
151 |
-
return
|
152 |
|
153 |
def enhance_panorama(self, panorama):
|
154 |
"""Quick enhancement with minimal processing."""
|
@@ -157,6 +125,7 @@ class StreetViewDownloader:
|
|
157 |
return panorama
|
158 |
|
159 |
|
|
|
160 |
def process_street_view(url, zoom, cols, rows, progress=gr.Progress()):
|
161 |
"""Process the Street View URL with custom parameters."""
|
162 |
try:
|
|
|
13 |
import aiohttp
|
14 |
import io
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
class StreetViewDownloader:
|
17 |
def __init__(self):
|
18 |
self.headers = {
|
19 |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
20 |
}
|
|
|
21 |
self.session = requests.Session()
|
22 |
|
23 |
def extract_panoid(self, url):
|
|
|
26 |
match = re.search(pattern, url)
|
27 |
if match:
|
28 |
return match.group(1)
|
29 |
+
raise ValueError("Could not find panorama ID in URL. Please make sure you're using a valid Street View URL.")
|
30 |
|
31 |
async def download_tile_async(self, session, panoid, x, y, adjusted_y, zoom, output_dir):
|
32 |
"""Download a single tile asynchronously."""
|
|
|
44 |
print(f"Error downloading tile {x},{y}: {str(e)}")
|
45 |
return None
|
46 |
|
47 |
+
async def download_tiles_async(self, panoid, output_dir, zoom, cols, rows):
|
48 |
+
"""Download tiles asynchronously with custom parameters."""
|
49 |
Path(output_dir).mkdir(parents=True, exist_ok=True)
|
50 |
|
51 |
+
vertical_offset = rows // 4 # Dynamic vertical offset based on rows
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
async with aiohttp.ClientSession() as session:
|
54 |
tasks = []
|
|
|
65 |
|
66 |
return cols, rows, downloaded_tiles
|
67 |
|
68 |
+
def download_tiles(self, panoid, output_dir, zoom, cols, rows):
|
69 |
"""Synchronous wrapper for async download."""
|
70 |
+
return asyncio.run(self.download_tiles_async(panoid, output_dir, zoom, cols, rows))
|
71 |
|
72 |
def create_360_panorama(self, directory, cols, rows, downloaded_tiles, output_file):
|
73 |
"""Create an equirectangular 360° panorama from tiles with optimized processing."""
|
|
|
87 |
tile_width, tile_height = valid_tile.size
|
88 |
valid_tile.close()
|
89 |
|
|
|
90 |
panorama_width = tile_width * cols
|
91 |
panorama_height = tile_height * rows
|
92 |
|
|
|
93 |
panorama = Image.new('RGB', (panorama_width, panorama_height))
|
94 |
|
|
|
95 |
def process_tile(tile_info):
|
96 |
x, y = tile_info
|
97 |
tile_path = directory / f"tile_{x}_{y}.jpg"
|
|
|
101 |
return (x * tile_width, y * tile_height, tile.copy())
|
102 |
return None
|
103 |
|
|
|
104 |
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
|
105 |
tile_results = list(executor.map(process_tile, downloaded_tiles))
|
106 |
|
|
|
107 |
for result in tile_results:
|
108 |
if result:
|
109 |
x, y, tile = result
|
110 |
panorama.paste(tile, (x, y))
|
111 |
tile.close()
|
112 |
|
|
|
113 |
bbox = panorama.getbbox()
|
114 |
if bbox:
|
115 |
panorama = panorama.crop(bbox)
|
116 |
|
|
|
117 |
panorama = self.enhance_panorama(panorama)
|
|
|
|
|
118 |
panorama.save(output_file, 'JPEG', quality=95, optimize=True)
|
119 |
+
return panorama
|
120 |
|
121 |
def enhance_panorama(self, panorama):
|
122 |
"""Quick enhancement with minimal processing."""
|
|
|
125 |
return panorama
|
126 |
|
127 |
|
128 |
+
|
129 |
def process_street_view(url, zoom, cols, rows, progress=gr.Progress()):
|
130 |
"""Process the Street View URL with custom parameters."""
|
131 |
try:
|