Edw00765's picture
Upload 21 files
b39a019 verified
# A set of functions to automatically annotate images for training a classification model of crosswalks. Requires a paid API key for the images but tile locations are free to access.
import overpy
from geopy.geocoders import Nominatim
import requests
MAPBOX_API_KEY = None
crosswalk_images_folder = "crosswalk_images"
# Returns a list of crosswalk locations based on a given location geo-code, such as "Bloomsbury, London, UK"
# Geo-codes for a location may differ from the common name for a location, so check before putting in a location
def get_cross_walk_location(location_geo_code, bounds=0.001):
over_api = overpy.Overpass()
geo_locator = Nominatim(user_agent="crosswalk_locator")
location = geo_locator.geocode(location_geo_code)
if not location:
raise ValueError("This location could not be geocoded - try an alternative name?.")
geo_bounding_box = (location.latitude - bounds, location.longitude - bounds,
location.latitude + bounds, location.longitude + bounds) # South, West, North, East
query = f"""
[out:json][timeout:25];
(
node["highway"="crossing"]({geo_bounding_box[0]},{geo_bounding_box[1]},{geo_bounding_box[2]},{geo_bounding_box[3]});
);
out body;
""" # Should return all crosswalks within {bounds} longitude/ latitude points, in a square shape
result = over_api.query(query)
crosswalks = []
for node in result.nodes:
crosswalks.append((node.lat, node.lon))
# Now we have a list of all the (latitude, longitude) pairs in that area,
# and can use it access the images of those areas for annotation
return crosswalks
# Gets the aerial image associated with a particular longitude and latitude.
# Uses the mapbox api, which is cheaper alternative to google maps static tiles API, but has lower res. images.
def get_mapbox_aerial_image(location, output_file_name, zoom=18, size="256x256", style="satellite-v9",
api_key=MAPBOX_API_KEY):
longitude, latitude = location # We split here, so it's easier to map this function onto a set of (lon, lat) coords
base_url = f"https://api.mapbox.com/styles/v1/mapbox/{style}/static"
coords = f"{latitude},{longitude},{zoom}"
url = f"{base_url}/{coords}/{size}?access_token={api_key}"
response = requests.get(url)
if response.status_code == 200:
with open(output_file_name, "wb") as file:
file.write(response.content)
print(f"Retrieved aerial image and saved it as {output_file_name}")
else:
print("Error, Error, Error!", response.status_code, response.text)
# Saves a list of crosswalk locations for the given geo-code to a folder, and returns the names of the saved files
# This function executes the setup required for training a classification model requiring 256x256 images as ours did
# If you want to change the model you are training, adjsut the get_mapbox_aerial_image function
def get_crosswalk_images(geo_code, folder=crosswalk_images_folder, file_extension="png"):
crosswalk_image_files = []
crosswalk_set = get_cross_walk_location(geo_code, bounds=0.1)
for crosswalk in crosswalk_set:
formatted_crosswalk = list(map(float, crosswalk))
stored_file_name = str(formatted_crosswalk)
try:
get_mapbox_aerial_image(formatted_crosswalk,
f"{folder}/{formatted_crosswalk}.{file_extension}")
crosswalk_image_files.append(stored_file_name)
except Exception as e:
print(e)
return crosswalk_image_files
#print(len(get_cross_walk_location("Bloomsbury, London, UK")))