edge_indices.py 3.09 KB
Newer Older
1
# Copyright (c) OpenMMLab. All rights reserved.
2
3
from typing import List

4
5
import numpy as np
import torch
6
from torch import Tensor
7
8


9
10
11
12
13
14
def get_edge_indices(img_metas: List[dict],
                     downsample_ratio: int,
                     step: int = 1,
                     pad_mode: str = 'default',
                     dtype: type = np.float32,
                     device: str = 'cpu') -> List[Tensor]:
15
16
17
18
19
20
21
    """Function to filter the objects label outside the image.
    The edge_indices are generated using numpy on cpu rather
    than on CUDA due to the latency issue. When batch size = 8,
    this function with numpy array is ~8 times faster than that
    with CUDA tensor (0.09s and 0.72s in 100 runs).

    Args:
22
        img_metas (List[dict]): Meta information of each image, e.g.,
23
            image size, scaling factor, etc.
ChaimZhu's avatar
ChaimZhu committed
24
        downsample_ratio (int): Downsample ratio of output feature,
25
26
27
28
29
30
31
32
        step (int): Step size used for generateing
            edge indices. Defaults to 1.
        pad_mode (str): Padding mode during data pipeline.
            Defaults to 'default'.
        dtype (type): Dtype of edge indices tensor.
            Defaults to np.float32.
        device (str): Device of edge indices tensor.
            Defaults to 'cpu'.
33
34

    Returns:
35
        List[Tensor]: Edge indices for each image in batch data.
36
37
38
39
    """
    edge_indices_list = []
    for i in range(len(img_metas)):
        img_shape = img_metas[i]['img_shape']
ChaimZhu's avatar
ChaimZhu committed
40
        pad_shape = img_metas[i]['pad_shape']
41
        h, w = img_shape[:2]
ChaimZhu's avatar
ChaimZhu committed
42
        pad_h, pad_w = pad_shape
43
44
45
46
47
        edge_indices = []

        if pad_mode == 'default':
            x_min = 0
            y_min = 0
ChaimZhu's avatar
ChaimZhu committed
48
49
50
51
52
53
54
            x_max = (w - 1) // downsample_ratio
            y_max = (h - 1) // downsample_ratio
        elif pad_mode == 'center':
            x_min = np.ceil((pad_w - w) / 2 * downsample_ratio)
            y_min = np.ceil((pad_h - h) / 2 * downsample_ratio)
            x_max = x_min + w // downsample_ratio
            y_max = y_min + h // downsample_ratio
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
        else:
            raise NotImplementedError

        # left
        y = np.arange(y_min, y_max, step, dtype=dtype)
        x = np.ones(len(y)) * x_min

        edge_indices_edge = np.stack((x, y), axis=1)
        edge_indices.append(edge_indices_edge)

        # bottom
        x = np.arange(x_min, x_max, step, dtype=dtype)
        y = np.ones(len(x)) * y_max

        edge_indices_edge = np.stack((x, y), axis=1)
        edge_indices.append(edge_indices_edge)

        # right
        y = np.arange(y_max, y_min, -step, dtype=dtype)
        x = np.ones(len(y)) * x_max

        edge_indices_edge = np.stack((x, y), axis=1)
        edge_indices.append(edge_indices_edge)

        # top
        x = np.arange(x_max, x_min, -step, dtype=dtype)
        y = np.ones(len(x)) * y_min

        edge_indices_edge = np.stack((x, y), axis=1)
        edge_indices.append(edge_indices_edge)

        edge_indices = \
            np.concatenate([index for index in edge_indices], axis=0)
        edge_indices = torch.from_numpy(edge_indices).to(device).long()
        edge_indices_list.append(edge_indices)

    return edge_indices_list