File size: 3,297 Bytes
fadb92b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Utilities for polygon manipulation.
"""

import numpy as np
import torch


def is_clockwise(points):
    """Check whether a sequence of points is clockwise ordered"""
    # points is a list of 2d points.
    assert len(points) > 0
    s = 0.0
    for p1, p2 in zip(points, points[1:] + [points[0]]):
        s += (p2[0] - p1[0]) * (p2[1] + p1[1])
    return s > 0.0


def resort_corners(corners):
    """Resort a sequence of corners so that the first corner starts
    from upper-left and counterclockwise ordered in image
    """
    corners = corners.reshape(-1, 2)
    x_y_square_sum = corners[:, 0] ** 2 + corners[:, 1] ** 2
    start_corner_idx = np.argmin(x_y_square_sum)

    corners_sorted = np.concatenate([corners[start_corner_idx:], corners[:start_corner_idx]])

    ## sort points clockwise (counterclockwise in image)
    if not is_clockwise(corners_sorted[:, :2].tolist()):
        corners_sorted[1:] = np.flip(corners_sorted[1:], 0)

    return corners_sorted.reshape(-1)


def get_all_order_corners(corners):
    """Get all possible permutation of a polygon"""
    length = int(len(corners) / 2)
    all_corners = torch.stack([corners.roll(i * 2) for i in range(length)])
    return all_corners


def pad_gt_polys(gt_instances, num_queries_per_poly, image_size, drop_rate, device=None):
    """Pad the ground truth polygons so that they have a uniform length"""

    thr_length = num_queries_per_poly * 2
    room_targets = []
    # padding ground truth on-fly
    for gt_inst in gt_instances:
        room_dict = {}
        room_corners = []
        corner_labels = []
        corner_lengths = []

        for i, poly in enumerate(gt_inst.gt_masks.polygons):
            corners = torch.from_numpy(poly[0]).to(device)
            corners = torch.clip(corners, 0, image_size - 1) / (image_size - 1)

            # automatically skip the polygon if it is too long
            if len(corners) > thr_length:
                continue

            corner_lengths.append(len(corners))

            corners_pad = torch.zeros(num_queries_per_poly * 2, device=device)
            corners_pad[: len(corners)] = corners

            labels = torch.ones(int(len(corners) / 2), dtype=torch.int64).to(device)
            labels_pad = torch.zeros(num_queries_per_poly, device=device)
            labels_pad[: len(labels)] = labels
            room_corners.append(corners_pad)
            corner_labels.append(labels_pad)

        room_classes = gt_inst.gt_classes
        if drop_rate > 0.0:
            keep_indices = np.where(np.random.rand(len(room_corners)) >= drop_rate)[0].tolist()
            if len(keep_indices) > 0:  # Only apply drop if we have something left
                room_corners = [room_corners[i] for i in keep_indices]
                corner_labels = [corner_labels[i] for i in keep_indices]
                corner_lengths = [corner_lengths[i] for i in keep_indices]
                room_classes = gt_inst.gt_classes[keep_indices]

        room_dict = {
            "coords": torch.stack(room_corners).to(device),
            "labels": torch.stack(corner_labels).to(device),
            "lengths": torch.tensor(corner_lengths, device=device),
            "room_labels": room_classes.to(device),
        }
        room_targets.append(room_dict)

    return room_targets