This project uses a CNN to detect road overpasses in satellite imagery. Feed it a satellite image and it tells you whether there's an overpass in it or not.
I trained the model on thousands of satellite images that I automatically labeled using OpenStreetMap data. It hits around 92% accuracy on the validation set.
There's a demo running on Hugging Face Spaces: Road Overpass Detector Demo
You can drop in coordinates and see what the model thinks. No setup required.
Screenshot: The live Streamlit app running on Hugging Face Spaces
Data Collection: I used the Google Maps Static API to grab satellite images from different regions (North America, Europe, Asia). Instead of manually labeling thousands of images, I wrote a script that queries OpenStreetMap via OSMnx to count how many overpass crossings are in each image. This gave me labels automatically.
The Model: It's a straightforward CNN built in TensorFlow/Keras. I added some data augmentation (random flips, brightness tweaks) to make it more robust. The model outputs a probability - like "95% confident there's an overpass here."
The Demo: Built a simple Streamlit app where you can enter lat/long coordinates, fetch the satellite tile, and get an instant prediction. It's deployed on Hugging Face Spaces so anyone can try it.
Clone the repository:
git clone https://github.com/jableable/my_road_project.git
cd my_road_projectOption 1: Conda (recommended)
Create the environment using the provided environment.yml:
conda env create -f environment.yml
conda activate roadprojectOption 2: Pip (lightweight)
Install the minimal pinned dependencies:
pip install -r requirements.txtGoogle Static Maps API (optional)
If you want to generate new satellite tiles or run the full demo, set your Google Static Maps API key as an environment variable:
# Linux / macOS
export goog_api="YOUR_API_KEY"
# Windows (PowerShell)
setx goog_api "YOUR_API_KEY"Easiest option: Just use the web demo.
Use in your own code:
from keras.models import load_model
import numpy as np
from PIL import Image
model = load_model("0.0008-0.92.keras") # or binary_classification_model.keras
img = Image.open("your_image.png").convert("RGB").resize((640, 640))
img_array = np.array(img)[None, ...] # no /255, model rescales internally
pred = model.predict(img_array)
prob_overpass = pred[0][1] * 100 # second value is overpass probability
print(f"Overpass probability: {prob_overpass:.2f}%")The model outputs an overpass probability between 0% and 100%.
Note: The trained model file (~2.3 GB) isn't in this repo. You can grab it from the Hugging Face Space or retrain it yourself.
Retrain from scratch:
- Generate a dataset using the scripts in
dataset_generation/(fetch images, label them with OSM data) - Preprocess using
dataset_processing/ - Train:
python model/binary_classification_model.py
Training from scratch requires ~12k images and a GPU.
- OpenStreetMap & OSMnx - for the road network data that made automatic labeling possible
- Google Static Maps API - for the satellite imagery
- TensorFlow/Keras - for the deep learning framework
- Streamlit & Hugging Face Spaces - for making the demo simple to deploy
MIT License - use it however you want. See LICENSE file.


