Wetland Mapping with GeoAI¶
Install packages¶
In [ ]:
Copied!
# %pip install geoai-py
# %pip install geoai-py
Import libraries¶
In [ ]:
Copied!
import geoai
import leafmap
import geoai
import leafmap
Create an interactive map¶
In [ ]:
Copied!
m = geoai.Map(center=[47.229011, -99.878662], zoom=13)
m.add_basemap("Esri.WorldImagery")
m
m = geoai.Map(center=[47.229011, -99.878662], zoom=13)
m.add_basemap("Esri.WorldImagery")
m
Draw an area of interest¶
In [ ]:
Copied!
if m.user_roi is not None:
bbox = m.user_roi_bounds()
else:
bbox = [-99.9057, 47.2143, -99.8686, 47.2419]
if m.user_roi is not None:
bbox = m.user_roi_bounds()
else:
bbox = [-99.9057, 47.2143, -99.8686, 47.2419]
Get the year of NWI data¶
In [ ]:
Copied!
nwi_year = leafmap.get_nwi_year(bbox=bbox, return_geometry=False)[0]
nwi_year
nwi_year = leafmap.get_nwi_year(bbox=bbox, return_geometry=False)[0]
nwi_year
In [ ]:
Copied!
nwi_year_geom = leafmap.get_nwi_year(bbox=bbox)
nwi_year_geom
nwi_year_geom = leafmap.get_nwi_year(bbox=bbox)
nwi_year_geom
In [ ]:
Copied!
m.add_gdf(nwi_year_geom, layer_name="NWI Year")
m.add_gdf(nwi_year_geom, layer_name="NWI Year")
Search for NAIP images for the corresponding NWI year¶
In [ ]:
Copied!
items = geoai.pc_stac_search(
collection="naip",
bbox=bbox,
time_range=f"{nwi_year}-01-01/{nwi_year}-12-30",
)
items
items = geoai.pc_stac_search(
collection="naip",
bbox=bbox,
time_range=f"{nwi_year}-01-01/{nwi_year}-12-30",
)
items
Visualize NAIP images¶
In [ ]:
Copied!
geoai.view_pc_items(items=items)
geoai.view_pc_items(items=items)
Download NAIP images¶
In [ ]:
Copied!
images = geoai.pc_stac_download(items, output_dir="naip", assets=["image"])
images
images = geoai.pc_stac_download(items, output_dir="naip", assets=["image"])
images
In [ ]:
Copied!
first_image = list(images.values())[0]["image"]
first_image
first_image = list(images.values())[0]["image"]
first_image
In [ ]:
Copied!
second_image = list(images.values())[1]["image"]
second_image
second_image = list(images.values())[1]["image"]
second_image
Download NWI data¶
In [ ]:
Copied!
image_bbox = leafmap.image_bbox(first_image, to_crs="EPSG:4326")
image_bbox
image_bbox = leafmap.image_bbox(first_image, to_crs="EPSG:4326")
image_bbox
In [ ]:
Copied!
nwi_gdf = leafmap.get_nwi(
geometry=image_bbox, clip=True, add_class=True, output="wetlands.geojson"
)
nwi_gdf
nwi_gdf = leafmap.get_nwi(
geometry=image_bbox, clip=True, add_class=True, output="wetlands.geojson"
)
nwi_gdf
In [ ]:
Copied!
wetlands_classes = nwi_gdf["WETLAND_TY"].unique()
wetlands_classes
wetlands_classes = nwi_gdf["WETLAND_TY"].unique()
wetlands_classes
In [ ]:
Copied!
num_classes = len(wetlands_classes) + 1
num_classes
num_classes = len(wetlands_classes) + 1
num_classes
Visualize NWI data¶
In [ ]:
Copied!
m.remove_layer(m.layers[-1])
m.add_raster(first_image, layer_name="NAIP")
m.add_nwi(nwi_gdf, layer_name="NWI")
m
m.remove_layer(m.layers[-1])
m.add_raster(first_image, layer_name="NAIP")
m.add_nwi(nwi_gdf, layer_name="NWI")
m
Select training and test images¶
In [ ]:
Copied!
train_raster_path = first_image
test_raster_path = second_image
train_vector_path = "wetlands.geojson"
train_raster_path = first_image
test_raster_path = second_image
train_vector_path = "wetlands.geojson"
In [ ]:
Copied!
geoai.view_vector_interactive(
train_vector_path, column="WETLAND_TY", tiles=train_raster_path
)
geoai.view_vector_interactive(
train_vector_path, column="WETLAND_TY", tiles=train_raster_path
)
Create image chips for training¶
In [ ]:
Copied!
out_folder = "output"
out_folder = "output"
In [ ]:
Copied!
tiles = geoai.export_geotiff_tiles(
in_raster=train_raster_path,
out_folder=out_folder,
in_class_data=train_vector_path,
tile_size=1024,
stride=256,
buffer_radius=0,
)
tiles = geoai.export_geotiff_tiles(
in_raster=train_raster_path,
out_folder=out_folder,
in_class_data=train_vector_path,
tile_size=1024,
stride=256,
buffer_radius=0,
)
Train a segmentation model¶
In [ ]:
Copied!
# Train U-Net model
geoai.train_segmentation_model(
images_dir=f"{out_folder}/images",
labels_dir=f"{out_folder}/labels",
output_dir=f"{out_folder}/unet_models",
architecture="unet",
encoder_name="resnet34",
encoder_weights="imagenet",
num_channels=4,
num_classes=num_classes, # background and wetlands classes
batch_size=8,
num_epochs=50,
learning_rate=0.001,
val_split=0.2,
verbose=True,
)
# Train U-Net model
geoai.train_segmentation_model(
images_dir=f"{out_folder}/images",
labels_dir=f"{out_folder}/labels",
output_dir=f"{out_folder}/unet_models",
architecture="unet",
encoder_name="resnet34",
encoder_weights="imagenet",
num_channels=4,
num_classes=num_classes, # background and wetlands classes
batch_size=8,
num_epochs=50,
learning_rate=0.001,
val_split=0.2,
verbose=True,
)
Evaluate the model¶
In [ ]:
Copied!
geoai.plot_performance_metrics(
history_path=f"{out_folder}/unet_models/training_history.pth",
figsize=(15, 5),
verbose=True,
)
geoai.plot_performance_metrics(
history_path=f"{out_folder}/unet_models/training_history.pth",
figsize=(15, 5),
verbose=True,
)
Run inference on a single image¶
In [ ]:
Copied!
# Define paths
masks_path = second_image.replace("naip", "prediction")
model_path = f"{out_folder}/unet_models/best_model.pth"
# Define paths
masks_path = second_image.replace("naip", "prediction")
model_path = f"{out_folder}/unet_models/best_model.pth"
In [ ]:
Copied!
geoai.semantic_segmentation(
input_path=test_raster_path,
output_path=masks_path,
model_path=model_path,
architecture="unet",
encoder_name="resnet34",
num_channels=4,
num_classes=6,
window_size=1024,
overlap=256,
batch_size=4,
)
geoai.semantic_segmentation(
input_path=test_raster_path,
output_path=masks_path,
model_path=model_path,
architecture="unet",
encoder_name="resnet34",
num_channels=4,
num_classes=6,
window_size=1024,
overlap=256,
batch_size=4,
)
Vectorize the results¶
In [ ]:
Copied!
output_path = masks_path.replace(".tif", "_mask.geojson")
gdf = geoai.raster_to_vector(
masks_path, output_path, min_area=300, simplify_tolerance=1
)
output_path = masks_path.replace(".tif", "_mask.geojson")
gdf = geoai.raster_to_vector(
masks_path, output_path, min_area=300, simplify_tolerance=1
)
In [ ]:
Copied!
geoai.view_vector_interactive(output_path, tiles=test_raster_path)
geoai.view_vector_interactive(output_path, tiles=test_raster_path)
Download more images¶
In [ ]:
Copied!
items = geoai.pc_stac_search(
collection="naip",
bbox=bbox,
)
items
items = geoai.pc_stac_search(
collection="naip",
bbox=bbox,
)
items
In [ ]:
Copied!
images = geoai.pc_stac_download(items, output_dir="naip", assets=["image"])
images
images = geoai.pc_stac_download(items, output_dir="naip", assets=["image"])
images
Run inference on multiple images¶
In [ ]:
Copied!
geoai.semantic_segmentation_batch(
input_dir="naip",
output_dir="prediction",
model_path=model_path,
architecture="unet",
encoder_name="resnet34",
num_channels=4,
num_classes=6,
window_size=1024,
overlap=256,
batch_size=4,
)
geoai.semantic_segmentation_batch(
input_dir="naip",
output_dir="prediction",
model_path=model_path,
architecture="unet",
encoder_name="resnet34",
num_channels=4,
num_classes=6,
window_size=1024,
overlap=256,
batch_size=4,
)