Spaces:
Runtime error
Runtime error
| import copy | |
| import itertools | |
| import math | |
| import numpy as np | |
| import torch | |
| from torch import nn | |
| class _Registry: | |
| """Minimal replacement for detectron2.utils.registry.Registry.""" | |
| def __init__(self, name): | |
| self._name = name | |
| self._obj_map = {} | |
| def register(self, obj=None): | |
| if obj is None: | |
| def decorator(func_or_class): | |
| self._obj_map[func_or_class.__name__] = func_or_class | |
| return func_or_class | |
| return decorator | |
| self._obj_map[obj.__name__] = obj | |
| return obj | |
| def get(self, name): | |
| return self._obj_map[name] | |
| POLY_LOSS_REGISTRY = _Registry("POLY_LOSS") | |
| def box_cxcywh_to_xyxy(x): | |
| x_c, y_c, w, h = x.unbind(-1) | |
| b = [(x_c - 0.5 * w), (y_c - 0.5 * h), (x_c + 0.5 * w), (y_c + 0.5 * h)] | |
| return torch.stack(b, dim=-1) | |
| def box_xyxy_to_cxcywh(x): | |
| x0, y0, x1, y1 = x.unbind(-1) | |
| b = [(x0 + x1) / 2, (y0 + y1) / 2, (x1 - x0), (y1 - y0)] | |
| return torch.stack(b, dim=-1) | |
| def clip_and_normalize_polygons(polys, inf_value=2.01): | |
| min_x, _ = polys[:, :, 0].min(dim=-1) | |
| min_y, _ = polys[:, :, 1].min(dim=-1) | |
| polys[torch.isinf(polys)] = -np.inf | |
| max_x, _ = polys[:, :, 0].max(dim=-1) | |
| max_y, _ = polys[:, :, 1].max(dim=-1) | |
| polys[torch.isinf(polys)] = inf_value | |
| min_xy = torch.stack((min_x, min_y), dim=-1) | |
| max_xy = torch.stack((max_x, max_y), dim=-1) - min_xy | |
| polys = (polys - min_xy.unsqueeze(1)) / max_xy.unsqueeze(1) | |
| return polys | |
| def pad_polygons(polys): | |
| count = len(polys) | |
| max_vertices = max([len(p) for p in polys]) | |
| pad_count = [max_vertices - len(p) for p in polys] | |
| # add between the first and second vertices. | |
| xs = [np.linspace(polys[i][0][0] + 0.00001, polys[i][1][0] - 0.00001, num=pad_count[i]) for i in range(count)] | |
| ys = [np.linspace(polys[i][0][1] + 0.00001, polys[i][1][1] - 0.00001, num=pad_count[i]) for i in range(count)] | |
| xys = [np.stack((xs[i], ys[i]), axis=-1) for i in range(count)] | |
| polys = [np.concatenate((polys[i][:1], xys[i], polys[i][1:])) for i in range(count)] | |
| return np.stack(polys) | |
| def rasterize_instances(rasterizer, instances, shape, offset=0.0): | |
| if shape[0] != shape[1]: | |
| raise ValueError("expected square") | |
| device = instances[0].gt_boxes.device | |
| all_polygons = clip_and_normalize_polygons( | |
| torch.from_numpy( | |
| pad_polygons( | |
| list( | |
| itertools.chain.from_iterable( | |
| [[p[0].reshape(-1, 2) for p in inst.gt_masks.polygons] for inst in instances] | |
| ) | |
| ) | |
| ) | |
| ) | |
| .float() | |
| .to(device) | |
| ) | |
| # to me it seems the offset would need to be in _pixel_ space? | |
| return rasterizer(all_polygons * float(shape[1].item()) + offset, shape[1].item(), shape[0].item(), 1.0) | |
| def get_union_box(p, box): | |
| # compute the enclosing box. | |
| all_points = torch.cat((p, box.view(-1, 2, 2)), dim=-2) | |
| min_xy = torch.min(all_points, dim=-2)[0] | |
| max_xy = torch.max(all_points, dim=-2)[0] | |
| return torch.cat((min_xy, max_xy), dim=-1) | |
| def sample_ellipse_fast(x, y, r1, r2, count=32, dt=0.01): | |
| batch_size, num_el = r1.shape | |
| device = r1.device | |
| num_integrals = int(round(2 * math.pi / dt)) | |
| thetas = dt * torch.arange(num_integrals, device=device).unsqueeze(0).unsqueeze(0).repeat(batch_size, num_el, 1) | |
| thetas_c = torch.cumsum(thetas, dim=-1) | |
| dpt = torch.sqrt((r1.unsqueeze(-1) * torch.sin(thetas_c)) ** 2 + (r2.unsqueeze(-1) * torch.cos(thetas_c)) ** 2) | |
| circumference = dpt.sum(dim=-1) | |
| run = torch.cumsum( | |
| torch.sqrt( | |
| (r1.unsqueeze(-1) * torch.sin(thetas + dt)) ** 2 + (r2.unsqueeze(-1) * torch.cos(thetas + dt)) ** 2 | |
| ), | |
| dim=-1, | |
| ) | |
| sub = (count * run) / circumference.unsqueeze(-1) | |
| # OK, now find the smallest point >= 0..count-1 | |
| counts = ( | |
| torch.arange(count, device=device) | |
| .unsqueeze(0) | |
| .unsqueeze(0) | |
| .unsqueeze(0) | |
| .repeat(batch_size, num_el, num_integrals, 1) | |
| ) | |
| diff = sub.unsqueeze(dim=-1) - counts | |
| diff[diff < 0] = 10000.0 | |
| idx = diff.argmin(dim=2) | |
| thetas = torch.gather(thetas + dt, -1, idx) | |
| xy = torch.stack( | |
| ( | |
| x.unsqueeze(-1) + r1.unsqueeze(-1) * torch.cos(thetas), | |
| y.unsqueeze(-1) + r2.unsqueeze(-1) * torch.sin(thetas), | |
| ), | |
| dim=-1, | |
| ) | |
| return xy | |
| def inverse_sigmoid(x, eps=1e-5): | |
| x = x.clamp(min=0, max=1) | |
| x1 = x.clamp(min=eps) | |
| x2 = (1 - x).clamp(min=eps) | |
| return torch.log(x1 / x2) | |
| def _get_clones(module, N): | |
| return nn.ModuleList([copy.deepcopy(module) for i in range(N)]) | |