File size: 3,191 Bytes
abd2a81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import numpy as np
import matplotlib.pyplot as plt

import shapely.geometry

import torch_lydorn.torchvision
from numpy.core._multiarray_umath import ndarray
from scipy import ndimage

import vectorization_ambiguities


def create_polygons():
    polygons = [
        np.array([
            [25, 25],
            [75, 25],
            [75, 50],
            [50, 50],
            [50, 75],
            [25, 75],
            [25, 25],
        ])
    ]
    return polygons


def displace_polygons(polygons, max_global, max_polygon, max_vertex, max_rot_deg):
    new_polygons = []
    global_disp = np.random.uniform(-1, 1, 2) * max_global
    for polygon in polygons:
        polygon_disp = np.random.uniform(-1, 1, 2) * max_polygon
        vertex_disp = np.random.uniform(-1, 1, polygon.shape) * max_vertex
        new_polygon = polygon + global_disp + polygon_disp + vertex_disp

        # Rotation
        geom = shapely.geometry.Polygon(new_polygon)
        angle = np.random.uniform(-1, 1, 1) * max_rot_deg
        geom = shapely.affinity.rotate(geom, angle, origin='center', use_radians=False)
        new_polygon = geom.exterior.coords[:]

        new_polygons.append(new_polygon)
    return new_polygons


def rasterize(image, polygons):
    polygons = [shapely.geometry.Polygon(polygon) for polygon in polygons]
    raster = torch_lydorn.torchvision.transforms.Rasterize(fill=True, edges=False, vertices=False, line_width=4, antialiasing=True)(image, polygons)
    raster = raster[:, :, 0]
    raster = ndimage.gaussian_filter(raster, sigma=1)  # Simulates blurriness of overhead image, which leads to blurriness of segmentation
    return raster


def plot(image, out_filepath, dpi=300):
    height = image.shape[0]
    width = image.shape[1]
    f, axis = plt.subplots(1, 1, figsize=(width, height), dpi=dpi)

    # Plot image
    axis.imshow(image, cmap="gray")

    axis.autoscale(False)
    axis.axis('equal')
    axis.axis('off')
    plt.subplots_adjust(left=0, right=1, top=1, bottom=0)  # Plot without margins
    plt.savefig(out_filepath, transparent=True, dpi=dpi)
    plt.close()


def main():
    shape = (100, 100)
    samples = 10
    all_rasters: ndarray = np.empty((*shape, samples))
    methods = [
        "marching_squares",
        "border_following",
        "rasterio"
    ]

    for s in range(samples):
        polygons = create_polygons()
        polygons = displace_polygons(polygons, max_global=0, max_polygon=3, max_vertex=0.5, max_rot_deg=1)  # Simulates imperfect ground truth annotations
        raster = rasterize(np.zeros(shape), polygons) / 255
        all_rasters[:, :, s] = raster
        plot(raster, f"rounded_corners_sample_{s:02d}.png", dpi=1)

        mean_raster_s = np.mean(all_rasters[:, :, :(s+1)], axis=-1)  # Simulates training to reduce average loss over all (noisy) ground truth
        plot(mean_raster_s, f"rounded_corners_avg_{s:02d}.png", dpi=1)

    for m in methods:
        contours = vectorization_ambiguities.detect_contours(mean_raster_s, method=m)
        vectorization_ambiguities.plot(mean_raster_s, contours, f"rounded_corners_avg_contour_{m}.pdf", linewidth=60, dpi=1, grid=False)


if __name__ == "__main__":
    main()