indoor_augment.py 3.56 KB
Newer Older
liyinhao's avatar
liyinhao committed
1
2
3
4
5
import numpy as np

from mmdet.datasets.registry import PIPELINES


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
def _rotz(t):
    """Rotate About Z.

    Rotation about the z-axis.

    Args:
        t (float): Angle of rotation.

    Returns:
        rot_mat (ndarray): Matrix of rotation.
    """
    c = np.cos(t)
    s = np.sin(t)
    rot_mat = np.array([[c, -s, 0], [s, c, 0], [0, 0, 1]])
    return rot_mat


def _rotate_aligned_boxes(input_boxes, rot_mat):
    centers, lengths = input_boxes[:, 0:3], input_boxes[:, 3:6]
    new_centers = np.dot(centers, np.transpose(rot_mat))

    dx, dy = lengths[:, 0] / 2.0, lengths[:, 1] / 2.0
    new_x = np.zeros((dx.shape[0], 4))
    new_y = np.zeros((dx.shape[0], 4))

    for i, crnr in enumerate([(-1, -1), (1, -1), (1, 1), (-1, 1)]):
        crnrs = np.zeros((dx.shape[0], 3))
        crnrs[:, 0] = crnr[0] * dx
        crnrs[:, 1] = crnr[1] * dy
        crnrs = np.dot(crnrs, np.transpose(rot_mat))
        new_x[:, i] = crnrs[:, 0]
        new_y[:, i] = crnrs[:, 1]

    new_dx = 2.0 * np.max(new_x, 1)
    new_dy = 2.0 * np.max(new_y, 1)
    new_lengths = np.stack((new_dx, new_dy, lengths[:, 2]), axis=1)

    return np.concatenate([new_centers, new_lengths], axis=1)


liyinhao's avatar
liyinhao committed
46
47
48
49
@PIPELINES.register_module()
class IndoorFlipData(object):
    """Indoor Flip Data

liyinhao's avatar
liyinhao committed
50
    Flip point_cloud and groundtruth boxes.
liyinhao's avatar
liyinhao committed
51
52
53
54
55
56
57
58
59
60

    Args:
        name (str): name of the dataset.
    """

    def __init__(self, name):
        assert name in ['scannet', 'sunrgbd']
        self.name = name

    def __call__(self, results):
liyinhao's avatar
liyinhao committed
61
        point_cloud = results.get('point_cloud', None)
liyinhao's avatar
liyinhao committed
62
        gt_boxes = results.get('gt_boxes', None)
liyinhao's avatar
liyinhao committed
63

liyinhao's avatar
liyinhao committed
64
65
        if np.random.random() > 0.5:
            # Flipping along the YZ plane
liyinhao's avatar
liyinhao committed
66
            point_cloud[:, 0] = -1 * point_cloud[:, 0]
liyinhao's avatar
liyinhao committed
67
68
69
70
            gt_boxes[:, 0] = -1 * gt_boxes[:, 0]
            if self.name == 'sunrgbd':
                gt_boxes[:, 6] = np.pi - gt_boxes[:, 6]
            results['gt_boxes'] = gt_boxes
liyinhao's avatar
liyinhao committed
71

liyinhao's avatar
liyinhao committed
72
73
        if self.name == 'scannet' and np.random.random() > 0.5:
            # Flipping along the XZ plane
liyinhao's avatar
liyinhao committed
74
            point_cloud[:, 1] = -1 * point_cloud[:, 1]
liyinhao's avatar
liyinhao committed
75
76
            gt_boxes[:, 1] = -1 * gt_boxes[:, 1]
            results['gt_boxes'] = gt_boxes
liyinhao's avatar
liyinhao committed
77
        results['point_cloud'] = point_cloud
liyinhao's avatar
liyinhao committed
78
79
80
81
82
83
84

        return results

    def __repr__(self):
        repr_str = self.__class__.__name__
        repr_str += '(dataset_name={})'.format(self.name)
        return repr_str
85
86
87
88
89
90


@PIPELINES.register_module()
class IndoorRotateData(object):
    """Indoor Rotate Data

liyinhao's avatar
liyinhao committed
91
    Rotate point_cloud and groundtruth boxes.
92
93
94
95
96
97
98
99

    Args:
        name (str): name of the dataset.
    """

    def __init__(self, name):
        assert name in ['scannet', 'sunrgbd']
        self.name = name
100
        self.rot_range = np.pi / 3
101
102

    def __call__(self, results):
liyinhao's avatar
liyinhao committed
103
        point_cloud = results.get('point_cloud', None)
104
        gt_boxes = results.get('gt_boxes', None)
105
106
        rot_angle = (np.random.random() *
                     self.rot_range) - self.rot_range / 2  # -30 ~ +30 degree
107
        rot_mat = _rotz(rot_angle)
liyinhao's avatar
liyinhao committed
108
109
        point_cloud[:, 0:3] = np.dot(point_cloud[:, 0:3],
                                     np.transpose(rot_mat))
liyinhao's avatar
liyinhao committed
110

111
112
113
114
115
        if self.name == 'scannet':
            gt_boxes = _rotate_aligned_boxes(gt_boxes, rot_mat)
        else:
            gt_boxes[:, 0:3] = np.dot(gt_boxes[:, 0:3], np.transpose(rot_mat))
            gt_boxes[:, 6] -= rot_angle
liyinhao's avatar
liyinhao committed
116

liyinhao's avatar
liyinhao committed
117
        results['point_cloud'] = point_cloud
118
119
120
121
122
123
124
        results['gt_boxes'] = gt_boxes
        return results

    def __repr__(self):
        repr_str = self.__class__.__name__
        repr_str += '(dataset_name={})'.format(self.name)
        return repr_str