I have .tif raster files from the SpaceNet dataset, along with corresponding object descriptions in geojson files. I want to be able to generate Darknet style bounding box information ([object_class, x_center, y_center, width, height]) from this data. Note that the class is same for all objects in one geojson file.

I am unable to find any suitable tutorial or guide to perform this transformation. The spacenet utilities guide on GitHub is old and doesn't work. Could anybody please help me with this transformation? I am not sure if rasterio can be used to do this.

Download sample .geojson file here: https://ufile.io/drcjt
Download sample .tif file here: https://ufile.io/wsq92

Edit: Please note that the Darknet style bounding box ([object_class, x_center, y_center, width, height]) assumes a rectangle in output, rather than a polygon.

  • x_center and y_center have to be in geographic coordinates or in array coordinates? width and height in degrees or number of pixels? – Loïc Dutrieux Jul 21 '18 at 5:07

Assuming Darknet is not spatially aware and that you need bounding box in array coordinates, you could use the following. It uses shapely to compute centroid and bounding box of each geometry and affine to convert from geo coordinates to array coordinates

import json
from shapely import geometry
import rasterio
from math import floor

filename = '/path/to/buildings_aoi_2_vegas_img12.geojson'
raster_file = '/path/to/rgb-pansharpen_aoi_2_vegas_img12.tif'

# Read geojson file
with open(filename) as src:
    fc = json.load(src)

# Get affine transform from raster file
with rasterio.open(raster_file) as src:
    aff = src.transform

ffa = ~aff

# Define fuction to build bbox
def darknet_bb_from_feature(feature):
    """Build a Darknet style bounding box from a geojson style feature
    poly = geometry.shape(feature['geometry'])
    center = poly.centroid
    x_center, y_center = ffa * (center.x, center.y)
    bbox = poly.bounds
    width = (bbox[2] - bbox[0]) // aff[0]
    height = (bbox[3] - bbox[1]) // -aff[4]
    out = ('obj_class', floor(x_center), floor(y_center), width, height)
    return out

# Apply function to all features of feature collection
bb_list = [darknet_bb_from_feature(feat) for feat in fc['features']]
  • This is very well written and self-explanatory code. Thank you for sharing this! – sircasms Jul 21 '18 at 15:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.