{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "# Segment Anything Model for Geospatial Data \n", "\n", "[](https://demo.leafmap.org/lab/index.html?path=notebooks/75_segment_anything.ipynb)\n", "[](https://colab.research.google.com/github/opengeos/leafmap/blob/master/docs/notebooks/75_segment_anything.ipynb)\n", "[](https://mybinder.org/v2/gh/opengeos/leafmap/HEAD)\n", "\n", "This notebook shows how to use segment satellite imagery using the Segment Anything Model (SAM) with a few lines of code. \n", "\n", "Make sure you use GPU runtime for this notebook. For Google Colab, go to `Runtime` -> `Change runtime type` and select `GPU` as the hardware accelerator." ] }, { "cell_type": "markdown", "id": "1", "metadata": {}, "source": [ "## Install dependencies\n", "\n", "Uncomment and run the following cell to install the required dependencies." ] }, { "cell_type": "code", "execution_count": null, "id": "2", "metadata": {}, "outputs": [], "source": [ "# %pip install leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "3", "metadata": {}, "outputs": [], "source": [ "# %pip install segment-geospatial localtileserver" ] }, { "cell_type": "markdown", "id": "4", "metadata": {}, "source": [ "## Import libraries" ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": {}, "outputs": [], "source": [ "import os\n", "import leafmap\n", "from samgeo import SamGeo, tms_to_geotiff, get_basemaps" ] }, { "cell_type": "markdown", "id": "6", "metadata": {}, "source": [ "## Create an interactive map" ] }, { "cell_type": "code", "execution_count": null, "id": "7", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(center=[29.676840, -95.369222], zoom=19)\n", "m.add_basemap(\"SATELLITE\")\n", "m" ] }, { "cell_type": "markdown", "id": "8", "metadata": {}, "source": [ "Pan and zoom the map to select the area of interest. Use the draw tools to draw a polygon or rectangle on the map" ] }, { "cell_type": "code", "execution_count": null, "id": "9", "metadata": {}, "outputs": [], "source": [ "if m.user_roi_bounds() is not None:\n", " bbox = m.user_roi_bounds()\n", "else:\n", " bbox = [-95.3704, 29.6762, -95.368, 29.6775]" ] }, { "cell_type": "markdown", "id": "10", "metadata": {}, "source": [ "## Download map tiles\n", "\n", "Download maps tiles and mosaic them into a single GeoTIFF file" ] }, { "cell_type": "code", "execution_count": null, "id": "11", "metadata": {}, "outputs": [], "source": [ "image = \"satellite.tif\"" ] }, { "cell_type": "markdown", "id": "12", "metadata": {}, "source": [ "Besides the `satellite` basemap, you can use any of the following basemaps returned by the `get_basemaps()` function:" ] }, { "cell_type": "code", "execution_count": null, "id": "13", "metadata": {}, "outputs": [], "source": [ "# get_basemaps().keys()" ] }, { "cell_type": "markdown", "id": "14", "metadata": {}, "source": [ "Specify the basemap as the source." ] }, { "cell_type": "code", "execution_count": null, "id": "15", "metadata": {}, "outputs": [], "source": [ "tms_to_geotiff(output=image, bbox=bbox, zoom=20, source=\"Satellite\", overwrite=True)" ] }, { "cell_type": "markdown", "id": "16", "metadata": {}, "source": [ "You can also use your own image. Uncomment and run the following cell to use your own image." ] }, { "cell_type": "code", "execution_count": null, "id": "17", "metadata": {}, "outputs": [], "source": [ "# image = '/path/to/your/own/image.tif'" ] }, { "cell_type": "markdown", "id": "18", "metadata": {}, "source": [ "Display the downloaded image on the map." ] }, { "cell_type": "code", "execution_count": null, "id": "19", "metadata": {}, "outputs": [], "source": [ "m.layers[-1].visible = False # turn off the basemap\n", "m.add_raster(image, layer_name=\"Image\")\n", "m" ] }, { "cell_type": "markdown", "id": "20", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "21", "metadata": {}, "source": [ "## Initialize SAM class" ] }, { "cell_type": "code", "execution_count": null, "id": "22", "metadata": {}, "outputs": [], "source": [ "sam = SamGeo(\n", " model_type=\"vit_h\",\n", " checkpoint=\"sam_vit_h_4b8939.pth\",\n", " sam_kwargs=None,\n", ")" ] }, { "cell_type": "markdown", "id": "23", "metadata": {}, "source": [ "## Segment the image\n", "\n", "Set `batch=True` to segment the image in batches. This is useful for large images that cannot fit in memory." ] }, { "cell_type": "code", "execution_count": null, "id": "24", "metadata": {}, "outputs": [], "source": [ "mask = \"segment.tif\"\n", "sam.generate(\n", " image, mask, batch=True, foreground=True, erosion_kernel=(3, 3), mask_multiplier=255\n", ")" ] }, { "cell_type": "markdown", "id": "25", "metadata": {}, "source": [ "## Polygonize the raster data\n", "\n", "Save the segmentation results as a GeoPackage file." ] }, { "cell_type": "code", "execution_count": null, "id": "26", "metadata": {}, "outputs": [], "source": [ "vector = \"segment.gpkg\"\n", "sam.tiff_to_gpkg(mask, vector, simplify_tolerance=None)" ] }, { "cell_type": "markdown", "id": "27", "metadata": {}, "source": [ "You can also save the segmentation results as any vector data format supported by GeoPandas." ] }, { "cell_type": "code", "execution_count": null, "id": "28", "metadata": {}, "outputs": [], "source": [ "shapefile = \"segment.shp\"\n", "sam.tiff_to_vector(mask, shapefile)" ] }, { "cell_type": "markdown", "id": "29", "metadata": {}, "source": [ "## Visualize the results" ] }, { "cell_type": "code", "execution_count": null, "id": "30", "metadata": {}, "outputs": [], "source": [ "style = {\n", " \"color\": \"#3388ff\",\n", " \"weight\": 2,\n", " \"fillColor\": \"#7c4185\",\n", " \"fillOpacity\": 0.5,\n", "}\n", "m.add_vector(vector, layer_name=\"Vector\", style=style)\n", "m" ] }, { "cell_type": "markdown", "id": "31", "metadata": {}, "source": [ "" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }