yolo utilities

Conversion between geospatial data and yolo-format

Specifications of yolo format:


source

YOLOProcessor

 YOLOProcessor (data_path:str, outpath:str, names:list)

Handles transformations from GIS-polygons to YOLOv8-format and backwards

YOLOProcessor converts data from either shp or geojson to YOLOv5 format.

First bounding boxes.

cats = ['Standing', 'Fallen']

outpath = Path('example_data/tiles/')
yolo_proc = YOLOProcessor(outpath, outpath, cats)
yolo_proc.from_shp('label', ann_format='box')
def plot_bounding_box(image, annotation_list, classes):
    annotations = np.array(annotation_list)
    w, h = image.size
    plotted_image = ImageDraw.Draw(image)

    transformed_annotations = np.copy(annotations)
    transformed_annotations[:,[1,3]] = annotations[:,[1,3]] * w
    transformed_annotations[:,[2,4]] = annotations[:,[2,4]] * h 
    
    transformed_annotations[:,1] = transformed_annotations[:,1] - (transformed_annotations[:,3] / 2)
    transformed_annotations[:,2] = transformed_annotations[:,2] - (transformed_annotations[:,4] / 2)
    transformed_annotations[:,3] = transformed_annotations[:,1] + transformed_annotations[:,3]
    transformed_annotations[:,4] = transformed_annotations[:,2] + transformed_annotations[:,4]
        
    for ann in transformed_annotations:
        obj_cls, x0, y0, x1, y1 = ann
        plotted_image.rectangle(((x0,y0), (x1,y1)))
        
        plotted_image.text((x0, y0 - 10), classes[int(obj_cls)])
    
    plt.imshow(np.array(image))
    plt.show()

    
# Get any random annotation file 
annotation_file = random.choice(os.listdir(outpath/'labels'))
with open(outpath/'labels'/annotation_file, "r") as file:
    annotation_list = file.read().split("\n")[:-1]
    annotation_list = [x.split(" ") for x in annotation_list]
    annotation_list = [[float(y) for y in x ] for x in annotation_list]

#Get the corresponding image file
image_file = annotation_file.replace("txt", "tif")
assert os.path.exists(outpath/'images'/image_file)

#Load the image
image = Image.open(outpath/'images'/image_file)

#Plot the Bounding Box
plot_bounding_box(image, annotation_list, {0:'Standing', 1:'Fallen'})

Then to polygon.

cats = ['Standing', 'Fallen']

outpath = Path('example_data/tiles/')
yolo_proc = YOLOProcessor(outpath, outpath, cats)
yolo_proc.from_shp('label', ann_format='polygon')
def plot_polygon(image, annotation_list, classes):
    w, h = image.size
    plotted_image = ImageDraw.Draw(image)
        
    for ann in annotation_list:
        obj_cls = ann[0]
        xcoords = [ann[i]*w for i in range(1, len(ann), 2)]
        ycoords = [ann[i]*h for i in range(2, len(ann)+1, 2)]
        xcoords.append(xcoords[0])
        ycoords.append(ycoords[0])
        plotted_image.polygon(list(zip(xcoords, ycoords)))
        
        plotted_image.text((xcoords[0], ycoords[0] - 10), classes[int(obj_cls)])
    
    plt.imshow(np.array(image))
    plt.show()
# Get any random annotation file 
annotation_file = random.choice(os.listdir(outpath/'labels'))
with open(outpath/'labels'/annotation_file, "r") as file:
    annotation_list = file.read().split("\n")[:-1]
    annotation_list = [x.split(" ") for x in annotation_list]
    annotation_list = [[float(y) for y in x ] for x in annotation_list]

#Get the corresponding image file
image_file = annotation_file.replace("txt", "tif")
assert os.path.exists(outpath/'images'/image_file)

#Load the image
image = Image.open(outpath/'images'/image_file)

#Plot the Bounding Box
plot_polygon(image, annotation_list, {0:'Standing', 1:'Fallen'})

Rotated bounding boxes are saved as polygon-style annotations.

cats = ['Standing', 'Fallen']

outpath = Path('example_data/tiles/')
yolo_proc = YOLOProcessor(outpath, outpath, cats)
yolo_proc.from_shp('label', ann_format='rotated box')
# Get any random annotation file 
annotation_file = random.choice(os.listdir(outpath/'labels'))
with open(outpath/'labels'/annotation_file, "r") as file:
    annotation_list = file.read().split("\n")[:-1]
    annotation_list = [x.split(" ") for x in annotation_list]
    annotation_list = [[float(y) for y in x ] for x in annotation_list]

#Get the corresponding image file
image_file = annotation_file.replace("txt", "tif")
assert os.path.exists(outpath/'images'/image_file)

#Load the image
image = Image.open(outpath/'images'/image_file)

#Plot the Bounding Box
plot_polygon(image, annotation_list, {0:'Standing', 1:'Fallen'})