Open source annotations tools for aerial imagery. Part of https://github.com/Sydney-Informatics-Hub/PIPE-3956-aerial-segmentation
Download the SA1 file from Australian Bureau of Statistics or similar.
Images and annotations stored in COCO JSON format.
To prepare the environment, run the following commands:
conda create --name aerial-annotation python=3.9
conda activate aerial-annotation
pip install -r requirements.txt
The script make_mask.py
in the scripts
directory can be used to create tree annotations for a set of .tiff
format aerial images. It uses a modified form of the
LangSAM
model that is part of the segment-geospatial package. This leverages both GroundingDINO and the Segment Anything Model with a
text prompt tree
to detect trees in aerial imagery: see here for an example of using segment-geospatial to detect
trees.
The method used here has some important modifications from the vanilla segment-geospatial package:
It adds a new box size threshold called box-reject
that rejects GroundingDINO boxes that are larger than a given fraction of the input image.
For boxes larger than box-reject
a secondary box-threshold
is used to allow for large boxes containg trees at high confidence.
Tree annotation masks from overlapping tiles are merged without a call to gdal.warp
. Instead they are merged by accepting only pixels in the merged mask that are annotated in more than 50% of the individual tiles.
make_mask.py /path/to/tiff/images \
--output /path/to/output/directory \
--tile-size=600 \
--tile-overlap=30 \
--box-reject=0.9 \
--high-box-threshold=0.35 \
--box-threshold=0.23
In the above example the options are:
--tile-size=600
: The size in pixels of tiles to split the input images into.
--tile-overlap=30
: Overlap size (as a percentage of tile-size
) and padding of the tiles. With the options --tile-size=600
and --tile-overlap=30
roughly 30 tiles of size 1400x1400 are created for an input image of 3000x3000 pixels.
--box-reject=0.9
: Reject GroundingDINO boxes larger than 90% of the tile size with value below --high-box-threshold
.
--high-box-threshold=0.35
: Box threshold for rejecting GroundingDINO boxes larger than box-reject.
--box-threshold=0.23
: Box threshold for boxes smaller the box-reject=0.9
.
A toy dataset has been uploaded to Roboflow. It is a small subset, containing Chatswood region, available here.
There are multiple versions of this dataset. Please ignore the first version. Version 2 and later versions are the ones that are being used. The main difference of version 2 and 3 is that version 2 contains 90 degree augmentaions, while version 3 does not.
For implementing this in your code, you can use the following code snippet:
from roboflow import Roboflow
rf = Roboflow(api_key= 'your_roboflow_api_key' )
workspace_name = "sih-vpfnf"
dataset_version = 3
project_name = "gis-hd-200x200"
dataset_download_name = "coco-segmentation"
project = rf.workspace(workspace_name).project(project_name)
dataset = project.version(dataset_version).download(dataset_download_name)
Building data from OSM can be cleaned and prepared for level categorisation using the following code snippet:
python scripts/osm_cleaner.py --osm_path /path/to/tiles/osm_building_annotations_by_10_percent_grid/ --columns /data/osm_columns.csv
Where osm_columns.csv
is a CSV file containing the columns we are interested to keep from the OSM data. OSM columns of interest are located in data/osm_columns.csv
.