Downloads · 30 days
7
4% of all-time downloads
BiliSakura/GeoSynth-ControlNets
GeoSynth-ControlNets is a image-to-image model from BiliSakura. Use it when you need one image transformed into another. It is set up for diffusers. The card lists the license as apache-2.0.
[!WARNING] we do not have a full checkpoint conversion validation, if you encounter pipeline loading failure and unsidered output, please contact me via [email protected]
Downloads · 30 days
7
4% of all-time downloads
All-time downloads
172
Public
Parameters
866M
9.5 GB on disk
Likes
1
Public
Click a slice to open those files.
.safetensors9.5 GB · 100%
From the Hugging Face model README
[!WARNING] we do not have a full checkpoint conversion validation, if you encounter pipeline loading failure and unsidered output, please contact me via [email protected]
We maintain two repositories—one per base checkpoint—each with its compatible ControlNets:
| Repo | Base Model | ControlNets |
|---|---|---|
| This repo | GeoSynth (text encoder & UNet same as SD 2.1) | GeoSynth-OSM, GeoSynth-Canny, GeoSynth-SAM |
| GeoSynth-ControlNets-Location | GeoSynth-Location (adds CoordNet branch) | GeoSynth-Location-OSM, GeoSynth-Location-SAM*, GeoSynth-Location-Canny |
GeoSynth-Location-SAM controlnet ckpt is missing from source.
controlnet/.Location-conditioned variants (GeoSynth-Location-*) use a different base checkpoint that adds a CoordNet branch. The branch takes [lon, lat] as input, passes it through a SatCLIP location encoder, then through a CoordNet (13 stacked cross-attention blocks, inner dim 256, 4 heads). ControlNet and CoordNet both condition the UNet. See the GeoSynth paper Figure 3.
| Control | Subfolder | Status |
|---|---|---|
| OSM | controlnet/GeoSynth-OSM | ✅ Integrated |
| Canny | controlnet/GeoSynth-Canny | ✅ Integrated |
| SAM | controlnet/GeoSynth-SAM | ✅ Integrated |
Use it with 🧨 diffusers or the Stable Diffusion repository.
from diffusers import StableDiffusionPipeline
pipe = StableDiffusionPipeline.from_pretrained("BiliSakura/GeoSynth-ControlNets")
pipe = pipe.to("cuda")
image = pipe("Satellite image features a city neighborhood").images[0]
image.save("generated_city.jpg")
Use the 🧨 diffusers ControlNetModel wrapper with StableDiffusionControlNetPipeline:
GeoSynth-OSM — synthesizes satellite images from OpenStreetMap tiles (RGB):
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from PIL import Image
import torch
controlnet = ControlNetModel.from_pretrained(
"BiliSakura/GeoSynth-ControlNets",
subfolder="controlnet/GeoSynth-OSM",
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"BiliSakura/GeoSynth-ControlNets",
controlnet=controlnet,
)
pipe = pipe.to("cuda")
img = Image.open("osm_tile.jpeg") # OSM tile (RGB, 512x512)
generator = torch.manual_seed(42)
image = pipe("Satellite image features a city neighborhood", image=img, generator=generator, num_inference_steps=20).images[0]
image.save("generated_city.jpg")
GeoSynth-Canny — synthesizes satellite images from Canny edge maps:
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from PIL import Image
import torch
controlnet = ControlNetModel.from_pretrained(
"BiliSakura/GeoSynth-ControlNets",
subfolder="controlnet/GeoSynth-Canny",
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"BiliSakura/GeoSynth-ControlNets",
controlnet=controlnet,
)
pipe = pipe.to("cuda")
img = Image.open("canny_edges.jpeg") # Canny edge image (RGB, 512x512)
generator = torch.manual_seed(42)
image = pipe("Satellite image features a city neighborhood", image=img, generator=generator, num_inference_steps=20).images[0]
image.save("generated_city.jpg")
GeoSynth-SAM — synthesizes satellite images from SAM (Segment Anything Model) segmentation masks:
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from PIL import Image
import torch
controlnet = ControlNetModel.from_pretrained(
"BiliSakura/GeoSynth-ControlNets",
subfolder="controlnet/GeoSynth-SAM",
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"BiliSakura/GeoSynth-ControlNets",
controlnet=controlnet,
)
pipe = pipe.to("cuda")
img = Image.open("sam_segmentation.jpeg") # SAM mask (RGB, 512x512)
generator = torch.manual_seed(42)
image = pipe("Satellite image features a city neighborhood", image=img, generator=generator, num_inference_steps=20).images[0]
image.save("generated_city.jpg")
For location-conditioned variants (GeoSynth-Location-OSM, GeoSynth-Location-SAM, GeoSynth-Location-Canny), see the separate GeoSynth-ControlNets-Location repo.
If you use this model, please cite the GeoSynth paper. For location-conditioned variants, also cite SatCLIP.
@inproceedings{sastry2024geosynth,
title={GeoSynth: Contextually-Aware High-Resolution Satellite Image Synthesis},
author={Sastry, Srikumar and Khanal, Subash and Dhakal, Aayush and Jacobs, Nathan},
booktitle={IEEE/ISPRS Workshop: Large Scale Computer Vision for Remote Sensing (EARTHVISION)},
year={2024}
}
@article{klemmer2025satclip,
title={{SatCLIP}: {Global}, General-Purpose Location Embeddings with Satellite Imagery},
author={Klemmer, Konstantin and Rolf, Esther and Robinson, Caleb and Mackey, Lester and Ru{\ss}wurm, Marc},
journal={Proceedings of the AAAI Conference on Artificial Intelligence},
volume={39},
number={4},
pages={4347--4355},
year={2025},
doi={10.1609/aaai.v39i4.32457}
}