Note
This page was generated from scenes_and_aois.ipynb.
Note
If running outside of the Docker image, you may need to set some environment variables manually. You can do it like so:
import os
from subprocess import check_output
os.environ['GDAL_DATA'] = check_output('pip show rasterio | grep Location | awk \'{print $NF"/rasterio/gdal_data/"}\'', shell=True).decode().strip()
We will be accessing files on S3 in this notebook. Since those files are public, we set the AWS_NO_SIGN_REQUEST
to tell rasterio
to skip the sign-in.
[ ]:
%env AWS_NO_SIGN_REQUEST=YES
Scenes and AOIs#
We have seen how to use RasterSources and LabelSources in other tutorials.
This tutorial introduces the Scene
abstraction, which bundles them together. Additionally, it allows specifying one or more “Areas of Interest” (AOIs) if we are only interested in a subset of the scene.
Example#
[2]:
image_uri = 's3://spacenet-dataset/spacenet/SN7_buildings/train/L15-0331E-1257N_1327_3160_13/images/global_monthly_2018_01_mosaic_L15-0331E-1257N_1327_3160_13.tif'
label_uri = 's3://spacenet-dataset/spacenet/SN7_buildings/train/L15-0331E-1257N_1327_3160_13/labels/global_monthly_2018_01_mosaic_L15-0331E-1257N_1327_3160_13_Buildings.geojson'
[3]:
from rastervision.core.data import RasterioSource
raster_source = RasterioSource(image_uri, allow_streaming=True)
[4]:
from rastervision.core.data import (
ClassConfig, ClassInferenceTransformer, GeoJSONVectorSource,
RasterizedSource, Scene)
class_config = ClassConfig(
names=['background', 'building'],
colors=['lightgray', 'darkred'],
null_class='background')
class_inf_tf = ClassInferenceTransformer(
default_class_id=class_config.get_class_id('building'))
vector_source = GeoJSONVectorSource(
label_uri,
crs_transformer=raster_source.crs_transformer,
vector_transformers=[class_inf_tf])
label_raster_source = RasterizedSource(
vector_source=vector_source,
background_class_id=class_config.null_class_id,
bbox=raster_source.bbox)
2024-04-09 20:03:53:rastervision.pipeline.file_system.utils: INFO - Using cached file /opt/data/tmp/cache/s3/spacenet-dataset/spacenet/SN7_buildings/train/L15-0331E-1257N_1327_3160_13/labels/global_monthly_2018_01_mosaic_L15-0331E-1257N_1327_3160_13_Buildings.geojson.
Define some AOI using polygons:
[5]:
from shapely.geometry import Polygon
aoi_polygons = [
Polygon.from_bounds(xmin=0, ymin=0, xmax=500, ymax=500),
Polygon.from_bounds(xmin=600, ymin=600, xmax=1024, ymax=1024),
]
Visualize the AOI:
[6]:
import numpy as np
from shapely.ops import unary_union
from matplotlib import pyplot as plt
from matplotlib import patches as mpatches
img = raster_source[:, :]
H, W = img.shape[:2]
extent = Polygon.from_bounds(0, 0, W, H)
bg = extent.difference(unary_union(aoi_polygons))
bg = bg if bg.geom_type == 'MultiPolygon' else [bg]
fig, ax = plt.subplots(1, 1, squeeze=True, figsize=(8, 8))
ax.imshow(img)
for p in bg:
p = mpatches.Polygon(np.array(p.exterior.coords), color='k', linewidth=2, alpha=0.5)
ax.add_patch(p)
for aoi in aoi_polygons:
p = mpatches.Polygon(
np.array(aoi.exterior.coords), color='#d9d9d9', linewidth=2, fill=False)
ax.add_patch(p)
plt.show()
Finally, define a Scene
:
[7]:
from rastervision.core.data import Scene
scene = Scene(
id='my_scene',
raster_source=raster_source,
label_source=label_raster_source,
aoi_polygons=aoi_polygons)
We can now index the scene like so:
[8]:
x, y = scene[100:200, 100:200]
x.shape, y.shape
[8]:
((100, 100, 3), (100, 100, 1))
Note that the Scene
itself does not prevent you from reading windows outside the AOI.
A simple check to make sure you’re inside the AOI before reading is to use the Box.within_aoi()
method:
[9]:
from rastervision.core.box import Box
window_inside_aoi = Box(ymin=100, xmin=100, ymax=200, xmax=200)
window_not_inside_aoi = Box(ymin=500, xmin=500, ymax=600, xmax=600)
print(window_inside_aoi, Box.within_aoi(window_inside_aoi, aoi_polygons))
print(window_not_inside_aoi, Box.within_aoi(window_not_inside_aoi, aoi_polygons))
Box(ymin=100, xmin=100, ymax=200, xmax=200) True
Box(ymin=500, xmin=500, ymax=600, xmax=600) False
Easier initialization#
If you found the above steps to be tedious, there is an alternative, simpler way of creating a scene:
[10]:
from rastervision.core.data.utils import make_ss_scene
scene = make_ss_scene(
class_config=class_config,
image_uri=image_uri,
label_vector_uri=label_uri,
label_vector_default_class_id=class_config.get_class_id('building'),
image_raster_source_kw=dict(allow_streaming=True))
2024-04-09 20:04:22:rastervision.pipeline.file_system.utils: INFO - Using cached file /opt/data/tmp/cache/s3/spacenet-dataset/spacenet/SN7_buildings/train/L15-0331E-1257N_1327_3160_13/labels/global_monthly_2018_01_mosaic_L15-0331E-1257N_1327_3160_13_Buildings.geojson.
make_ss_scene()
is for creating semantic segmentation scenes. There is also make_cc_scene()
for chip classificaiton and make_od_scene()
for object detection.