Ejemplo n.º 1
0
 def test_pairwise_iou_many_boxes(self):
     for device in ["cpu"
                    ] + (["cuda"] if torch.cuda.is_available() else []):
         num_boxes1 = 100
         num_boxes2 = 200
         boxes1 = torch.stack([
             torch.tensor(
                 [5 + 20 * i, 5 + 20 * i, 10, 10, 0],
                 dtype=torch.float32,
                 device=device,
             ) for i in range(num_boxes1)
         ])
         boxes2 = torch.stack([
             torch.tensor(
                 [5 + 20 * i, 5 + 20 * i, 10, 1 + 9 * i / num_boxes2, 0],
                 dtype=torch.float32,
                 device=device,
             ) for i in range(num_boxes2)
         ])
         expected_ious = torch.zeros(num_boxes1,
                                     num_boxes2,
                                     dtype=torch.float32,
                                     device=device)
         for i in range(min(num_boxes1, num_boxes2)):
             expected_ious[i][i] = (1 + 9 * i / num_boxes2) / 10.0
         ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
         self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 2
0
 def test_pairwise_iou_0_degree_cuda(self):
     device = torch.device("cuda")
     boxes1 = torch.tensor(
         [[0.5, 0.5, 1.0, 1.0, 0.0], [0.5, 0.5, 1.0, 1.0, 0.0]],
         dtype=torch.float32,
         device=device,
     )
     boxes2 = torch.tensor(
         [
             [0.5, 0.5, 1.0, 1.0, 0.0],
             [0.25, 0.5, 0.5, 1.0, 0.0],
             [0.5, 0.25, 1.0, 0.5, 0.0],
             [0.25, 0.25, 0.5, 0.5, 0.0],
             [0.75, 0.75, 0.5, 0.5, 0.0],
             [1.0, 1.0, 1.0, 1.0, 0.0],
         ],
         dtype=torch.float32,
         device=device,
     )
     expected_ious = torch.tensor(
         [
             [1.0, 0.5, 0.5, 0.25, 0.25, 0.25 / (2 - 0.25)],
             [1.0, 0.5, 0.5, 0.25, 0.25, 0.25 / (2 - 0.25)],
         ],
         dtype=torch.float32,
         device=device,
     )
     ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
     self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 3
0
    def test_normalize_angles(self):
        # torch.manual_seed(0)
        for _ in range(50):
            num_boxes = 100
            boxes_5d = torch.zeros(num_boxes, 5)
            boxes_5d[:, 0] = torch.FloatTensor(num_boxes).uniform_(-100, 500)
            boxes_5d[:, 1] = torch.FloatTensor(num_boxes).uniform_(-100, 500)
            boxes_5d[:, 2] = torch.FloatTensor(num_boxes).uniform_(0, 500)
            boxes_5d[:, 3] = torch.FloatTensor(num_boxes).uniform_(0, 500)
            boxes_5d[:, 4] = torch.FloatTensor(num_boxes).uniform_(-1800, 1800)
            rotated_boxes = RotatedBoxes(boxes_5d)
            normalized_boxes = rotated_boxes.clone()
            normalized_boxes.normalize_angles()
            self.assertTrue(torch.all(normalized_boxes.tensor[:, 4] >= -180))
            self.assertTrue(torch.all(normalized_boxes.tensor[:, 4] < 180))
            # x, y, w, h should not change
            self.assertTrue(torch.allclose(boxes_5d[:, :4], normalized_boxes.tensor[:, :4]))
            # the cos/sin values of the angles should stay the same

            self.assertTrue(
                torch.allclose(
                    torch.cos(boxes_5d[:, 4] * math.pi / 180),
                    torch.cos(normalized_boxes.tensor[:, 4] * math.pi / 180),
                    atol=1e-5,
                )
            )

            self.assertTrue(
                torch.allclose(
                    torch.sin(boxes_5d[:, 4] * math.pi / 180),
                    torch.sin(normalized_boxes.tensor[:, 4] * math.pi / 180),
                    atol=1e-5,
                )
            )
Ejemplo n.º 4
0
 def test_pairwise_iou_0_degree(self):
     for device in ["cpu"
                    ] + (["cuda"] if torch.cuda.is_available() else []):
         boxes1 = torch.tensor(
             [[0.5, 0.5, 1.0, 1.0, 0.0], [0.5, 0.5, 1.0, 1.0, 0.0]],
             dtype=torch.float32,
             device=device,
         )
         boxes2 = torch.tensor(
             [
                 [0.5, 0.5, 1.0, 1.0, 0.0],
                 [0.25, 0.5, 0.5, 1.0, 0.0],
                 [0.5, 0.25, 1.0, 0.5, 0.0],
                 [0.25, 0.25, 0.5, 0.5, 0.0],
                 [0.75, 0.75, 0.5, 0.5, 0.0],
                 [1.0, 1.0, 1.0, 1.0, 0.0],
             ],
             dtype=torch.float32,
             device=device,
         )
         expected_ious = torch.tensor(
             [
                 [1.0, 0.5, 0.5, 0.25, 0.25, 0.25 / (2 - 0.25)],
                 [1.0, 0.5, 0.5, 0.25, 0.25, 0.25 / (2 - 0.25)],
             ],
             dtype=torch.float32,
             device=device,
         )
         ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
         self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 5
0
 def func_cat(x: torch.Tensor):
     boxes1 = RotatedBoxes(x)
     boxes2 = RotatedBoxes(x)
     # this is not supported by torchscript for now.
     # boxes3 = RotatedBoxes.cat([boxes1, boxes2])
     boxes3 = boxes1.cat([boxes1, boxes2])
     return boxes3
Ejemplo n.º 6
0
 def test_pairwise_iou_many_boxes_cuda(self):
     device = torch.device("cuda")
     num_boxes1 = 100
     num_boxes2 = 200
     boxes1 = torch.stack(
         [
             torch.tensor(
                 [5 + 20 * i, 5 + 20 * i, 10, 10, 0], dtype=torch.float32, device=device
             )
             for i in range(num_boxes1)
         ]
     )
     boxes2 = torch.stack(
         [
             torch.tensor(
                 [5 + 20 * i, 5 + 20 * i, 10, 1 + 9 * i / num_boxes2, 0],
                 dtype=torch.float32,
                 device=device,
             )
             for i in range(num_boxes2)
         ]
     )
     expected_ious = torch.zeros(num_boxes1, num_boxes2, dtype=torch.float32, device=device)
     for i in range(min(num_boxes1, num_boxes2)):
         expected_ious[i][i] = (1 + 9 * i / num_boxes2) / 10.0
     ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
     self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 7
0
 def test_pairwise_iou_orthogonal_cuda(self):
     device = torch.device("cuda")
     boxes1 = torch.tensor([[5, 5, 10, 6, 55]], dtype=torch.float32, device=device)
     boxes2 = torch.tensor([[5, 5, 10, 6, -35]], dtype=torch.float32, device=device)
     iou = (6.0 * 6.0) / (6.0 * 6.0 + 4.0 * 6.0 + 4.0 * 6.0)
     expected_ious = torch.tensor([[iou]], dtype=torch.float32, device=device)
     ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
     self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 8
0
    def test_pairwise_iou_issue1207_simplified(self):
        for device in ["cpu"] + ["cuda"] if torch.cuda.is_available() else []:
            # Simplified test case of D2-issue-1207
            boxes1 = torch.tensor([[3, 3, 8, 2, -45.0]], device=device)
            boxes2 = torch.tensor([[6, 0, 8, 2, -45.0]], device=device)
            iou = 0.0
            expected_ious = torch.tensor([[iou]],
                                         dtype=torch.float32,
                                         device=device)

            ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
            self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 9
0
    def test_pairwise_iou_issue1207_simplified_cuda(self):
        device = torch.device("cuda")

        # Simplified test case of D2-issue-1207
        boxes1 = torch.tensor([[3, 3, 8, 2, -45.0]], device=device)
        boxes2 = torch.tensor([[6, 0, 8, 2, -45.0]], device=device)
        iou = 0.0
        expected_ious = torch.tensor([[iou]],
                                     dtype=torch.float32,
                                     device=device)

        ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
        self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 10
0
 def test_pairwise_iou_45_degrees_cuda(self):
     device = torch.device("cuda")
     boxes1 = torch.tensor(
         [
             [1, 1, math.sqrt(2), math.sqrt(2), 45],
             [1, 1, 2 * math.sqrt(2), 2 * math.sqrt(2), -45],
         ],
         dtype=torch.float32,
         device=device,
     )
     boxes2 = torch.tensor([[1, 1, 2, 2, 0]], dtype=torch.float32, device=device)
     expected_ious = torch.tensor([[0.5], [0.5]], dtype=torch.float32, device=device)
     ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
     self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 11
0
 def test_pairwise_iou_orthogonal(self):
     for device in ["cpu"] + ["cuda"] if torch.cuda.is_available() else []:
         boxes1 = torch.tensor([[5, 5, 10, 6, 55]],
                               dtype=torch.float32,
                               device=device)
         boxes2 = torch.tensor([[5, 5, 10, 6, -35]],
                               dtype=torch.float32,
                               device=device)
         iou = (6.0 * 6.0) / (6.0 * 6.0 + 4.0 * 6.0 + 4.0 * 6.0)
         expected_ious = torch.tensor([[iou]],
                                      dtype=torch.float32,
                                      device=device)
         ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
         self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 12
0
    def test_pairwise_iou_issue1207(self):
        for device in ["cpu"] + ["cuda"] if torch.cuda.is_available() else []:
            # The original test case in D2-issue-1207
            boxes1 = torch.tensor([[160.0, 153.0, 230.0, 23.0, -37.0]],
                                  device=device)
            boxes2 = torch.tensor([[190.0, 127.0, 80.0, 21.0, -46.0]],
                                  device=device)

            iou = 0.0
            expected_ious = torch.tensor([[iou]],
                                         dtype=torch.float32,
                                         device=device)

            ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
            self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 13
0
    def test_pairwise_iou_issue1207_cuda(self):
        device = torch.device("cuda")

        # The original test case in D2-issue-1207
        boxes1 = torch.tensor([[160.0, 153.0, 230.0, 23.0, -37.0]],
                              device=device)
        boxes2 = torch.tensor([[190.0, 127.0, 80.0, 21.0, -46.0]],
                              device=device)

        iou = 0.0
        expected_ious = torch.tensor([[iou]],
                                     dtype=torch.float32,
                                     device=device)

        ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
        self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 14
0
 def test_pairwise_iou_large_close_boxes_cuda(self):
     device = torch.device("cuda")
     boxes1 = torch.tensor(
         [[299.500000, 417.370422, 600.000000, 364.259186, 27.1828]],
         dtype=torch.float32,
         device=device,
     )
     boxes2 = torch.tensor(
         [[299.500000, 417.370422, 600.000000, 364.259155, 27.1828]],
         dtype=torch.float32,
         device=device,
     )
     iou = 364.259155 / 364.259186
     expected_ious = torch.tensor([[iou]], dtype=torch.float32, device=device)
     ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
     self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 15
0
 def test_pairwise_iou_large_close_boxes(self):
     for device in ["cpu"] + ["cuda"] if torch.cuda.is_available() else []:
         boxes1 = torch.tensor(
             [[299.500000, 417.370422, 600.000000, 364.259186, 27.1828]],
             dtype=torch.float32,
             device=device,
         )
         boxes2 = torch.tensor(
             [[299.500000, 417.370422, 600.000000, 364.259155, 27.1828]],
             dtype=torch.float32,
             device=device,
         )
         iou = 364.259155 / 364.259186
         expected_ious = torch.tensor([[iou]],
                                      dtype=torch.float32,
                                      device=device)
         ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
         self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 16
0
 def test_pairwise_iou_45_degrees(self):
     for device in ["cpu"] + ["cuda"] if torch.cuda.is_available() else []:
         boxes1 = torch.tensor(
             [
                 [1, 1, math.sqrt(2), math.sqrt(2), 45],
                 [1, 1, 2 * math.sqrt(2), 2 * math.sqrt(2), -45],
             ],
             dtype=torch.float32,
             device=device,
         )
         boxes2 = torch.tensor([[1, 1, 2, 2, 0]],
                               dtype=torch.float32,
                               device=device)
         expected_ious = torch.tensor([[0.5], [0.5]],
                                      dtype=torch.float32,
                                      device=device)
         ious = pairwise_iou(RotatedBoxes(boxes1), RotatedBoxes(boxes2))
         self.assertTrue(torch.allclose(ious, expected_ious))
Ejemplo n.º 17
0
    def test_clip_area_0_degree(self):
        for _ in range(50):
            num_boxes = 100
            boxes_5d = torch.zeros(num_boxes, 5)
            boxes_5d[:, 0] = torch.FloatTensor(num_boxes).uniform_(-100, 500)
            boxes_5d[:, 1] = torch.FloatTensor(num_boxes).uniform_(-100, 500)
            boxes_5d[:, 2] = torch.FloatTensor(num_boxes).uniform_(0, 500)
            boxes_5d[:, 3] = torch.FloatTensor(num_boxes).uniform_(0, 500)
            # Convert from (x_ctr, y_ctr, w, h, 0) to  (x1, y1, x2, y2)
            boxes_4d = torch.zeros(num_boxes, 4)
            boxes_4d[:, 0] = boxes_5d[:, 0] - boxes_5d[:, 2] / 2.0
            boxes_4d[:, 1] = boxes_5d[:, 1] - boxes_5d[:, 3] / 2.0
            boxes_4d[:, 2] = boxes_5d[:, 0] + boxes_5d[:, 2] / 2.0
            boxes_4d[:, 3] = boxes_5d[:, 1] + boxes_5d[:, 3] / 2.0

            image_size = (500, 600)
            test_boxes_4d = Boxes(boxes_4d)
            test_boxes_5d = RotatedBoxes(boxes_5d)
            # Before clip
            areas_4d = test_boxes_4d.area()
            areas_5d = test_boxes_5d.area()
            self.assertTrue(torch.allclose(areas_4d, areas_5d, atol=1e-1, rtol=1e-5))
            # After clip
            test_boxes_4d.clip(image_size)
            test_boxes_5d.clip(image_size)
            areas_4d = test_boxes_4d.area()
            areas_5d = test_boxes_5d.area()
            self.assertTrue(torch.allclose(areas_4d, areas_5d, atol=1e-1, rtol=1e-5))
Ejemplo n.º 18
0
    def test_clip_area_arbitrary_angle(self):
        num_boxes = 100
        boxes_5d = torch.zeros(num_boxes, 5)
        boxes_5d[:, 0] = torch.FloatTensor(num_boxes).uniform_(-100, 500)
        boxes_5d[:, 1] = torch.FloatTensor(num_boxes).uniform_(-100, 500)
        boxes_5d[:, 2] = torch.FloatTensor(num_boxes).uniform_(0, 500)
        boxes_5d[:, 3] = torch.FloatTensor(num_boxes).uniform_(0, 500)
        boxes_5d[:, 4] = torch.FloatTensor(num_boxes).uniform_(-1800, 1800)
        clip_angle_threshold = random.uniform(0, 180)

        image_size = (500, 600)
        test_boxes_5d = RotatedBoxes(boxes_5d)
        # Before clip
        areas_before = test_boxes_5d.area()
        # After clip
        test_boxes_5d.clip(image_size, clip_angle_threshold)
        areas_diff = test_boxes_5d.area() - areas_before

        # the areas should only decrease after clipping
        self.assertTrue(torch.all(areas_diff <= 0))
        # whenever the box is clipped (thus the area shrinks),
        # the angle for the box must be within the clip_angle_threshold
        # Note that the clip function will normalize the angle range
        # to be within (-180, 180]
        self.assertTrue(
            torch.all(torch.abs(boxes_5d[:, 4][torch.where(areas_diff < 0)]) < clip_angle_threshold)
        )
Ejemplo n.º 19
0
 def test_empty_cat(self):
     x = RotatedBoxes.cat([])
     self.assertTrue(x.tensor.shape, (0, 5))
Ejemplo n.º 20
0
 def func(x):
     boxes = RotatedBoxes(x)
     test = boxes.to(torch.device("cpu")).tensor
     return boxes.area(), test
def rotated_mapper(original_dataset_dict):
    # Implement a mapper, similar to the default DatasetMapper, but with our own customizations

    dataset_dict = copy.deepcopy(
        original_dataset_dict)  # it will be modified by code below
    original_gsd = dataset_dict["gsd"]
    target_gsd = np.random.uniform(0.09, 0.13)  # randomize target gsd
    scale = original_gsd / target_gsd

    target_size = 400
    target_crop = int(target_size / scale)
    target_crop = (target_crop, target_crop)

    image_np = detection_utils.read_image(dataset_dict["file_name"],
                                          format="BGR")

    boxes = np.asarray([anno['bbox'] for anno in dataset_dict['annotations']])

    # select anno at random
    # draw random center

    # h, w = image_np.shape[:2]
    # rand_box = boxes[np.random.randint(len(boxes))]
    # ch, cw = rand_box[:2]
    # xmin = np.min()
    # xmax = np.max()
    # ymin = 3
    # ymax = 4

    # h0 = np.random.randint(min(h, ymin), min(h, ymax) + 1)
    # w0 = np.random.randint(min(w, xmin), min(w, xmax) + 1)
    # assert h >= target_crop[1] and w >= target_crop[0], "Shape computation has bugs."

    # crop = T.CropTransform(w0, h0, target_crop)

    # make sure random crop contains annotations
    i = 0
    while True:
        random_crop = T.RandomCrop('absolute',
                                   target_crop).get_transform(image_np)
        cropped_boxes = RotatedBoxes(
            random_crop.apply_coords(copy.deepcopy(boxes)))
        inside_ind = cropped_boxes.inside_box(target_crop)
        if 1 < sum(inside_ind) <= 100:
            break
        i += 1
        if i > 150:
            return None

    image, transforms = T.apply_transform_gens([
        random_crop,
        T.Resize((target_size, target_size)),
    ], image_np)
    dataset_dict["image"] = torch.as_tensor(
        image.transpose(2, 0, 1).astype("float32"))

    annos = [
        rotated_transform_instance_annotations(obj, transforms,
                                               image.shape[:2])
        for obj in dataset_dict.pop("annotations")
        if obj.get("iscrowd", 0) == 0
    ]
    instances = detection_utils.annotations_to_instances_rotated(
        annos, image.shape[:2])
    instances = detection_utils.filter_empty_instances(instances)
    inside_ind = instances.gt_boxes.inside_box(image.shape[:2])
    instances = instances[inside_ind]

    assert ((instances.gt_boxes.tensor.numpy()[:, 2] > 0).all().item()
            ), "width not > 0\n\n" + str(instances.gt_boxes.tensor.numpy())

    dataset_dict["instances"] = instances
    return dataset_dict