Luuu / scripts /shp_to_json.py
็™ฝ้นญๅ…ˆ็”Ÿ
init
abd2a81
raw
history blame
3.61 kB
#!/usr/bin/env python3
###################################################################
# Use this script to convert shapefiles to the COCO .json format.
###################################################################
import fnmatch
import os
import argparse
import fiona
import shapely.geometry
import skimage.io
import skimage.morphology
import pycocotools.mask
import numpy as np
from tqdm import tqdm
import json
import skimage.measure
def get_args():
argparser = argparse.ArgumentParser(description=__doc__)
argparser.add_argument(
'--shp_dirpath',
required=True,
type=str,
help='Path to the directory where the shapefiles are.')
argparser.add_argument(
'--output_filepath',
required=True,
type=str,
help='Filepath of the final .json.')
args = argparser.parse_args()
return args
def shp_to_json(shp_dirpath, output_filepath):
filenames = fnmatch.filter(os.listdir(shp_dirpath), "*.shp")
filenames = sorted(filenames)
annotations = []
for filename in tqdm(filenames, desc="Process shapefiles:"):
shapefile = fiona.open(os.path.join(shp_dirpath, filename))
polygons = []
for feature in shapefile:
geometry = shapely.geometry.shape(feature["geometry"])
if geometry.type == "MultiPolygon":
for polygon in geometry.geoms:
polygons.append(polygon)
elif geometry.type == "Polygon":
polygons.append(geometry)
else:
raise TypeError(f"geometry.type should be either Polygon or MultiPolygon, not {geometry.type}.")
image_id = int(filename.split(".")[0])
for polygon in polygons:
bbox = np.round([polygon.bounds[0], polygon.bounds[1],
polygon.bounds[2] - polygon.bounds[0], polygon.bounds[3] - polygon.bounds[1]], 2)
contour = np.array(polygon.exterior.coords)
contour[:, 1] *= -1 # Shapefiles have inverted y axis...
exterior = list(np.round(contour.reshape(-1), 2))
segmentation = [exterior]
annotation = {
"category_id": 100, # Building
"bbox": list(bbox),
"segmentation": segmentation,
"score": 1.0,
"image_id": image_id}
annotations.append(annotation)
# seg = skimage.io.imread()
# labels = skimage.morphology.label(seg)
# properties = skimage.measure.regionprops(labels, cache=True)
# for i, contour_props in enumerate(properties):
# skimage_bbox = contour_props["bbox"]
# coco_bbox = [skimage_bbox[1], skimage_bbox[0],
# skimage_bbox[3] - skimage_bbox[1], skimage_bbox[2] - skimage_bbox[0]]
#
# image_mask = labels == (i + 1) # The mask has to span the whole image
# rle = pycocotools.mask.encode(np.asfortranarray(image_mask))
# rle["counts"] = rle["counts"].decode("utf-8")
# annotation = {
# "category_id": 100, # Building
# "bbox": coco_bbox,
# "segmentation": rle,
# "score": 1.0,
# "image_id": image_id}
# annotations.append(annotation)
with open(output_filepath, 'w') as outfile:
json.dump(annotations, outfile)
if __name__ == "__main__":
args = get_args()
shp_dirpath = args.shp_dirpath
output_filepath = args.output_filepath
shp_to_json(shp_dirpath, output_filepath)