-
Notifications
You must be signed in to change notification settings - Fork 0
/
vis.py
140 lines (115 loc) · 4.01 KB
/
vis.py
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import os
import sys
import argparse
import cv2
import random
import colorsys
import requests
from io import BytesIO
import skimage.io
from skimage.measure import find_contours
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import torch
import torch.nn as nn
import torchvision
from torchvision import transforms as pth_transforms
import numpy as np
from PIL import Image
import utils
def magnitude2heatmap(mag, log=True, scale=200.):
if log:
mag = np.log10(mag + 1.)
mag *= scale
mag[mag > 255] = 255
mag = mag.astype(np.uint8)
mag_color = cv2.applyColorMap(mag, cv2.COLORMAP_JET)
mag_color = mag_color[:, :, ::-1]
return mag_color
class HTMLVisualizer():
def __init__(self, fn_html):
self.fn_html = fn_html
self.content = '<table>'
self.content += '<style> table, th, td {border: 1px solid black;} </style>'
def add_header(self, elements):
self.content += '<tr>'
for element in elements:
self.content += '<th>{}</th>'.format(element)
self.content += '</tr>'
def add_rows(self, rows):
for row in rows:
self.add_row(row)
def add_row(self, elements):
self.content += '<tr>'
# a list of cells
for element in elements:
self.content += '<td>'
# fill a cell
for key, val in element.items():
if key == 'text':
self.content += val
elif key == 'image':
self.content += '<img src="{}" style="max-height:480px;max-width:480px;">'.format(val)
elif key == 'audio':
self.content += '<audio controls><source src="{}"></audio>'.format(val)
elif key == 'video':
self.content += '<video src="{}" controls="controls" style="max-height:256px;max-width:256px;">'.format(val)
self.content += '</td>'
self.content += '</tr>'
def write_html(self):
self.content += '</table>'
with open(self.fn_html, 'w') as f:
f.write(self.content)
def apply_mask(image, mask, color, alpha=0.5):
for c in range(3):
image[:, :, c] = image[:, :, c] * (1 - alpha * mask) + alpha * mask * color[c] * 255
return image
def random_colors(N, bright=True):
"""
Generate random colors.
"""
brightness = 1.0 if bright else 0.7
hsv = [(i / N, 1, brightness) for i in range(N)]
colors = list(map(lambda c: colorsys.hsv_to_rgb(*c), hsv))
random.shuffle(colors)
return colors
def display_instances(image, mask, fname="test", figsize=(5, 5), blur=False, contour=True, alpha=0.5):
height, width = image.shape[:2]
fig = plt.figure(frameon=False)
dpi = fig.dpi
fig.set_size_inches(height/dpi, width/dpi)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
ax = plt.gca()
N = 1
mask = mask[None, :, :]
# Generate random colors
colors = random_colors(N)
# Show area outside image boundaries.
margin = 0
ax.set_ylim(height + margin, -margin)
ax.set_xlim(-margin, width + margin)
ax.axis('off')
masked_image = image.astype(np.uint32).copy()
for i in range(N):
color = colors[i]
_mask = mask[i]
if blur:
_mask = cv2.blur(_mask,(10,10))
# Mask
masked_image = apply_mask(masked_image, _mask, color, alpha)
# Mask Polygon
# Pad to ensure proper polygons for masks that touch image edges.
if contour:
padded_mask = np.zeros((_mask.shape[0] + 2, _mask.shape[1] + 2))
padded_mask[1:-1, 1:-1] = _mask
contours = find_contours(padded_mask, 0.5)
for verts in contours:
# Subtract the padding and flip (y, x) to (x, y)
verts = np.fliplr(verts) - 1
p = Polygon(verts, facecolor="none", edgecolor=color)
ax.add_patch(p)
ax.imshow(masked_image.astype(np.uint8), aspect='auto')
fig.savefig(fname)
return