|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|
exterior = list(np.round(contour.reshape(-1), 2)) |
|
segmentation = [exterior] |
|
annotation = { |
|
"category_id": 100, |
|
"bbox": list(bbox), |
|
"segmentation": segmentation, |
|
"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) |
|
|