util.py 2.38 KB
Newer Older
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

import torch as T
import torch.nn.functional as F
import numpy as NP
import os

USE_CUDA = os.getenv('USE_CUDA', None)

def cuda(x, device=None, async_=False):
    return x.cuda() if USE_CUDA else x

def tovar(x, *args, dtype='float32', **kwargs):
    if not T.is_tensor(x):
        x = T.from_numpy(NP.array(x, dtype=dtype))
    return T.autograd.Variable(cuda(x), *args, **kwargs)

def tonumpy(x):
    if isinstance(x, T.autograd.Variable):
        x = x.data
    if T.is_tensor(x):
        x = x.cpu().numpy()
    return x

def create_onehot(idx, size):
    onehot = tovar(T.zeros(*size))
    onehot = onehot.scatter(1, idx.unsqueeze(1), 1)
    return onehot

def reverse(x, dim):
    idx = T.arange(x.size()[dim] - 1, -1, -1).long().to(x.device)
    return x.index_select(dim, idx)

def addbox(ax, b, ec, lw=1):
    import matplotlib.patches as PA
    ax.add_patch(PA.Rectangle((b[0] - b[2] / 2, b[1] - b[3] / 2), b[2], b[3],
                 ec=ec, fill=False, lw=lw))

def overlay(fore, fore_bbox, back):
    batch_size = fore.size()[0]
    crows, ccols = fore.size()[-2:]
    cx, cy, w, h = T.unbind(fore_bbox, -1)
    x1 = -2 * cx / w
    x2 = 2 * (1 - cx) / w
    y1 = -2 * cy / h
    y2 = 2 * (1 - cy) / h

    x1 = x1[:, None]
    x2 = x2[:, None]
    y1 = y1[:, None]
    y2 = y2[:, None]

    nrows, ncols = back.size()[-2:]
    grid_x = x1 + (x2 - x1) * tovar(T.arange(ncols))[None, :] / (ncols - 1)
    grid_y = y1 + (y2 - y1) * tovar(T.arange(nrows))[None, :] / (nrows - 1)
    grid = T.stack([
        grid_x[:, None, :].expand(batch_size, nrows, ncols),
        grid_y[:, :, None].expand(batch_size, nrows, ncols),
        ], -1)

    fore = T.cat([fore, tovar(T.ones(batch_size, 1, crows, ccols))], 1)

    fore = F.grid_sample(fore, grid)
    fore_rgb = fore[:, :3]
    fore_alpha = fore[:, 3:4]
    result = fore_rgb * fore_alpha + back * (1 - fore_alpha)

    return result

def intersection(a, b):
    x1 = T.max(a[..., 0] - a[..., 2] / 2, b[..., 0] - b[..., 2] / 2)
    y1 = T.max(a[..., 1] - a[..., 3] / 2, b[..., 1] - b[..., 3] / 2)
    x2 = T.min(a[..., 0] + a[..., 2] / 2, b[..., 0] + b[..., 2] / 2)
    y2 = T.min(a[..., 1] + a[..., 3] / 2, b[..., 1] + b[..., 3] / 2)
    w = (x2 - x1).clamp(min=0)
    h = (y2 - y1).clamp(min=0)
    return w * h

def iou(a, b):
    i_area = intersection(a, b)
    a_area = a[..., 2] * a[..., 3]
    b_area = b[..., 2] * b[..., 3]
    return i_area / (a_area + b_area - i_area)