DenseSR / utils /misc.py
VanLinLin's picture
birth
3f7c489
import numpy as np
import torchvision.utils as vutils
def get_np_imgrid(array, nrow=3, padding=0, pad_value=0):
'''
achieves the same function of torchvision.utils.make_grid for
numpy array
'''
# assume every image has smae size
n, h, w, c = array.shape
row_num = n // nrow + (n % nrow != 0)
gh, gw = row_num*h + padding*(row_num-1), nrow*w + padding*(nrow - 1)
grid = np.ones((gh, gw, c), dtype=array.dtype) * pad_value
for i in range(n):
grow, gcol = i // nrow, i % nrow
off_y, off_x = grow * (h + padding), gcol * (w + padding)
grid[off_y : off_y + h, off_x : off_x + w] = array[i]
return grid
def split_np_imgrid(imgrid, nimg, nrow, padding=0):
'''
reverse operation of make_grid.
args:
imgrid: HWC image grid
nimg: number of images in the grid
nrow: number of columns in image grid
return:
images: list, contains splitted images
'''
row_num = nimg // nrow + (nimg % nrow != 0)
gh, gw, _ = imgrid.shape
h, w = (gh - (row_num-1)*padding)//row_num, (gw - (nrow-1)*padding)//nrow
images = []
for gid in range(nimg):
grow, gcol = gid // nrow, gid % nrow
off_i, off_j = grow * (h + padding), gcol * (w + padding)
images.append(imgrid[off_i:off_i+h, off_j:off_j+w])
return images
class MDTableConvertor:
def __init__(self, col_num):
self.col_num = col_num
def _get_table_row(self, items):
row = ''
for item in items:
row += '| {:s} '.format(item)
row += '|\n'
return row
def convert(self, item_list, title=None):
'''
args:
item_list: a list of items (str or can be converted to str)
that want to be presented in table.
title: None, or a list of strings. When set to None, empty title
row is used and column number is determined by col_num; Otherwise,
it will be used as title row, its length will override col_num.
return:
table: markdown table string.
'''
table = ''
if title: # not None or not [] both equal to true
col_num = len(title)
table += self._get_table_row(title)
else:
col_num=self.col_num
table += self._get_table_row([' ']*col_num) # empty title row
table += self._get_table_row(['-'] * col_num) # header spliter
for i in range(0, len(item_list), col_num):
table += self._get_table_row(item_list[i:i+col_num])
return table
def visual_dict_to_imgrid(visual_dict, col_num=4, padding=0):
'''
args:
visual_dict: a dictionary of images of the same size
col_num: number of columns in image grid
padding: number of padding pixels to seperate images
'''
im_names = []
im_tensors = []
for name, visual in visual_dict.items():
im_names.append(name)
im_tensors.append(visual)
im_grid = vutils.make_grid(im_tensors,
nrow=col_num ,
padding=0,
pad_value=1.0)
layout = MDTableConvertor(col_num).convert(im_names)
return im_grid, layout
def count_parameters(model, trainable_only=False):
return sum(p.numel() for p in model.parameters())
class WarmupExpLRScheduler(object):
def __init__(self, lr_start=1e-4, lr_max=4e-4, lr_min=5e-6, rampup_epochs=4, sustain_epochs=0, exp_decay=0.75):
self.lr_start = lr_start
self.lr_max = lr_max
self.lr_min = lr_min
self.rampup_epochs = rampup_epochs
self.sustain_epochs = sustain_epochs
self.exp_decay = exp_decay
def __call__(self, epoch):
if epoch < self.rampup_epochs:
lr = (self.lr_max - self.lr_start) / self.rampup_epochs * epoch + self.lr_start
elif epoch < self.rampup_epochs + self.sustain_epochs:
lr = self.lr_max
else:
lr = (self.lr_max - self.lr_min) * self.exp_decay**(epoch - self.rampup_epochs - self.sustain_epochs) + self.lr_min
# print(lr)
return lr