init commit of samurai
This commit is contained in:
1
lib/test/utils/__init__.py
Normal file
1
lib/test/utils/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .params import TrackerParams, FeatureParams, Choice
|
17
lib/test/utils/_init_paths.py
Normal file
17
lib/test/utils/_init_paths.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os.path as osp
|
||||
import sys
|
||||
|
||||
|
||||
def add_path(path):
|
||||
if path not in sys.path:
|
||||
sys.path.insert(0, path)
|
||||
|
||||
|
||||
this_dir = osp.dirname(__file__)
|
||||
|
||||
prj_path = osp.join(this_dir, '..', '..', '..')
|
||||
add_path(prj_path)
|
93
lib/test/utils/hann.py
Normal file
93
lib/test/utils/hann.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import torch
|
||||
import math
|
||||
import torch.nn.functional as F
|
||||
|
||||
|
||||
def hann1d(sz: int, centered = True) -> torch.Tensor:
|
||||
"""1D cosine window."""
|
||||
if centered:
|
||||
return 0.5 * (1 - torch.cos((2 * math.pi / (sz + 1)) * torch.arange(1, sz + 1).float()))
|
||||
w = 0.5 * (1 + torch.cos((2 * math.pi / (sz + 2)) * torch.arange(0, sz//2 + 1).float()))
|
||||
return torch.cat([w, w[1:sz-sz//2].flip((0,))])
|
||||
|
||||
|
||||
def hann2d(sz: torch.Tensor, centered = True) -> torch.Tensor:
|
||||
"""2D cosine window."""
|
||||
return hann1d(sz[0].item(), centered).reshape(1, 1, -1, 1) * hann1d(sz[1].item(), centered).reshape(1, 1, 1, -1)
|
||||
|
||||
|
||||
def hann2d_bias(sz: torch.Tensor, ctr_point: torch.Tensor, centered = True) -> torch.Tensor:
|
||||
"""2D cosine window."""
|
||||
distance = torch.stack([ctr_point, sz-ctr_point], dim=0)
|
||||
max_distance, _ = distance.max(dim=0)
|
||||
|
||||
hann1d_x = hann1d(max_distance[0].item() * 2, centered)
|
||||
hann1d_x = hann1d_x[max_distance[0] - distance[0, 0]: max_distance[0] + distance[1, 0]]
|
||||
hann1d_y = hann1d(max_distance[1].item() * 2, centered)
|
||||
hann1d_y = hann1d_y[max_distance[1] - distance[0, 1]: max_distance[1] + distance[1, 1]]
|
||||
|
||||
return hann1d_y.reshape(1, 1, -1, 1) * hann1d_x.reshape(1, 1, 1, -1)
|
||||
|
||||
|
||||
|
||||
def hann2d_clipped(sz: torch.Tensor, effective_sz: torch.Tensor, centered = True) -> torch.Tensor:
|
||||
"""1D clipped cosine window."""
|
||||
|
||||
# Ensure that the difference is even
|
||||
effective_sz += (effective_sz - sz) % 2
|
||||
effective_window = hann1d(effective_sz[0].item(), True).reshape(1, 1, -1, 1) * hann1d(effective_sz[1].item(), True).reshape(1, 1, 1, -1)
|
||||
|
||||
pad = (sz - effective_sz) // 2
|
||||
|
||||
window = F.pad(effective_window, (pad[1].item(), pad[1].item(), pad[0].item(), pad[0].item()), 'replicate')
|
||||
|
||||
if centered:
|
||||
return window
|
||||
else:
|
||||
mid = (sz / 2).int()
|
||||
window_shift_lr = torch.cat((window[:, :, :, mid[1]:], window[:, :, :, :mid[1]]), 3)
|
||||
return torch.cat((window_shift_lr[:, :, mid[0]:, :], window_shift_lr[:, :, :mid[0], :]), 2)
|
||||
|
||||
|
||||
def gauss_fourier(sz: int, sigma: float, half: bool = False) -> torch.Tensor:
|
||||
if half:
|
||||
k = torch.arange(0, int(sz/2+1))
|
||||
else:
|
||||
k = torch.arange(-int((sz-1)/2), int(sz/2+1))
|
||||
return (math.sqrt(2*math.pi) * sigma / sz) * torch.exp(-2 * (math.pi * sigma * k.float() / sz)**2)
|
||||
|
||||
|
||||
def gauss_spatial(sz, sigma, center=0, end_pad=0):
|
||||
k = torch.arange(-(sz-1)/2, (sz+1)/2+end_pad)
|
||||
return torch.exp(-1.0/(2*sigma**2) * (k - center)**2)
|
||||
|
||||
|
||||
def label_function(sz: torch.Tensor, sigma: torch.Tensor):
|
||||
return gauss_fourier(sz[0].item(), sigma[0].item()).reshape(1, 1, -1, 1) * gauss_fourier(sz[1].item(), sigma[1].item(), True).reshape(1, 1, 1, -1)
|
||||
|
||||
def label_function_spatial(sz: torch.Tensor, sigma: torch.Tensor, center: torch.Tensor = torch.zeros(2), end_pad: torch.Tensor = torch.zeros(2)):
|
||||
"""The origin is in the middle of the image."""
|
||||
return gauss_spatial(sz[0].item(), sigma[0].item(), center[0], end_pad[0].item()).reshape(1, 1, -1, 1) * \
|
||||
gauss_spatial(sz[1].item(), sigma[1].item(), center[1], end_pad[1].item()).reshape(1, 1, 1, -1)
|
||||
|
||||
|
||||
def cubic_spline_fourier(f, a):
|
||||
"""The continuous Fourier transform of a cubic spline kernel."""
|
||||
|
||||
bf = (6*(1 - torch.cos(2 * math.pi * f)) + 3*a*(1 - torch.cos(4 * math.pi * f))
|
||||
- (6 + 8*a)*math.pi*f*torch.sin(2 * math.pi * f) - 2*a*math.pi*f*torch.sin(4 * math.pi * f)) \
|
||||
/ (4 * math.pi**4 * f**4)
|
||||
|
||||
bf[f == 0] = 1
|
||||
|
||||
return bf
|
||||
|
||||
def max2d(a: torch.Tensor) -> (torch.Tensor, torch.Tensor):
|
||||
"""Computes maximum and argmax in the last two dimensions."""
|
||||
|
||||
max_val_row, argmax_row = torch.max(a, dim=-2)
|
||||
max_val, argmax_col = torch.max(max_val_row, dim=-1)
|
||||
argmax_row = argmax_row.view(argmax_col.numel(),-1)[torch.arange(argmax_col.numel()), argmax_col.view(-1)]
|
||||
argmax_row = argmax_row.reshape(argmax_col.shape)
|
||||
argmax = torch.cat((argmax_row.unsqueeze(-1), argmax_col.unsqueeze(-1)), -1)
|
||||
return max_val, argmax
|
47
lib/test/utils/load_text.py
Normal file
47
lib/test/utils/load_text.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def load_text_numpy(path, delimiter, dtype):
|
||||
if isinstance(delimiter, (tuple, list)):
|
||||
for d in delimiter:
|
||||
try:
|
||||
ground_truth_rect = np.loadtxt(path, delimiter=d, dtype=dtype)
|
||||
return ground_truth_rect
|
||||
except:
|
||||
pass
|
||||
|
||||
raise Exception('Could not read file {}'.format(path))
|
||||
else:
|
||||
ground_truth_rect = np.loadtxt(path, delimiter=delimiter, dtype=dtype)
|
||||
return ground_truth_rect
|
||||
|
||||
|
||||
def load_text_pandas(path, delimiter, dtype):
|
||||
if isinstance(delimiter, (tuple, list)):
|
||||
for d in delimiter:
|
||||
try:
|
||||
ground_truth_rect = pd.read_csv(path, delimiter=d, header=None, dtype=dtype, na_filter=False,
|
||||
low_memory=False).values
|
||||
return ground_truth_rect
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
raise Exception('Could not read file {}'.format(path))
|
||||
else:
|
||||
ground_truth_rect = pd.read_csv(path, delimiter=delimiter, header=None, dtype=dtype, na_filter=False,
|
||||
low_memory=False).values
|
||||
return ground_truth_rect
|
||||
|
||||
|
||||
def load_text(path, delimiter=' ', dtype=np.float32, backend='numpy'):
|
||||
if backend == 'numpy':
|
||||
return load_text_numpy(path, delimiter, dtype)
|
||||
elif backend == 'pandas':
|
||||
return load_text_pandas(path, delimiter, dtype)
|
||||
|
||||
|
||||
def load_str(path):
|
||||
with open(path, "r") as f:
|
||||
text_str = f.readline().strip().lower()
|
||||
return text_str
|
43
lib/test/utils/params.py
Normal file
43
lib/test/utils/params.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from lib.utils import TensorList
|
||||
import random
|
||||
|
||||
|
||||
class TrackerParams:
|
||||
"""Class for tracker parameters."""
|
||||
def set_default_values(self, default_vals: dict):
|
||||
for name, val in default_vals.items():
|
||||
if not hasattr(self, name):
|
||||
setattr(self, name, val)
|
||||
|
||||
def get(self, name: str, *default):
|
||||
"""Get a parameter value with the given name. If it does not exists, it return the default value given as a
|
||||
second argument or returns an error if no default value is given."""
|
||||
if len(default) > 1:
|
||||
raise ValueError('Can only give one default value.')
|
||||
|
||||
if not default:
|
||||
return getattr(self, name)
|
||||
|
||||
return getattr(self, name, default[0])
|
||||
|
||||
def has(self, name: str):
|
||||
"""Check if there exist a parameter with the given name."""
|
||||
return hasattr(self, name)
|
||||
|
||||
|
||||
class FeatureParams:
|
||||
"""Class for feature specific parameters"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
if len(args) > 0:
|
||||
raise ValueError
|
||||
|
||||
for name, val in kwargs.items():
|
||||
if isinstance(val, list):
|
||||
setattr(self, name, TensorList(val))
|
||||
else:
|
||||
setattr(self, name, val)
|
||||
|
||||
|
||||
def Choice(*args):
|
||||
"""Can be used to sample random parameter values."""
|
||||
return random.choice(args)
|
52
lib/test/utils/transform_got10k.py
Normal file
52
lib/test/utils/transform_got10k.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import numpy as np
|
||||
import os
|
||||
import shutil
|
||||
import argparse
|
||||
import _init_paths
|
||||
from lib.test.evaluation.environment import env_settings
|
||||
|
||||
|
||||
def transform_got10k(tracker_name, cfg_name):
|
||||
env = env_settings()
|
||||
result_dir = env.results_path
|
||||
src_dir = os.path.join(result_dir, "%s/%s/got10k/" % (tracker_name, cfg_name))
|
||||
dest_dir = os.path.join(result_dir, "%s/%s/got10k_submit/" % (tracker_name, cfg_name))
|
||||
if not os.path.exists(dest_dir):
|
||||
os.makedirs(dest_dir)
|
||||
items = os.listdir(src_dir)
|
||||
for item in items:
|
||||
if "all" in item:
|
||||
continue
|
||||
src_path = os.path.join(src_dir, item)
|
||||
if "time" not in item:
|
||||
seq_name = item.replace(".txt", '')
|
||||
seq_dir = os.path.join(dest_dir, seq_name)
|
||||
if not os.path.exists(seq_dir):
|
||||
os.makedirs(seq_dir)
|
||||
new_item = item.replace(".txt", '_001.txt')
|
||||
dest_path = os.path.join(seq_dir, new_item)
|
||||
bbox_arr = np.loadtxt(src_path, dtype=np.int, delimiter='\t')
|
||||
np.savetxt(dest_path, bbox_arr, fmt='%d', delimiter=',')
|
||||
else:
|
||||
seq_name = item.replace("_time.txt", '')
|
||||
seq_dir = os.path.join(dest_dir, seq_name)
|
||||
if not os.path.exists(seq_dir):
|
||||
os.makedirs(seq_dir)
|
||||
dest_path = os.path.join(seq_dir, item)
|
||||
os.system("cp %s %s" % (src_path, dest_path))
|
||||
# make zip archive
|
||||
shutil.make_archive(src_dir, "zip", src_dir)
|
||||
shutil.make_archive(dest_dir, "zip", dest_dir)
|
||||
# Remove the original files
|
||||
shutil.rmtree(src_dir)
|
||||
shutil.rmtree(dest_dir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='transform got10k results.')
|
||||
parser.add_argument('--tracker_name', type=str, help='Name of tracking method.')
|
||||
parser.add_argument('--cfg_name', type=str, help='Name of config file.')
|
||||
|
||||
args = parser.parse_args()
|
||||
transform_got10k(args.tracker_name, args.cfg_name)
|
||||
|
39
lib/test/utils/transform_trackingnet.py
Normal file
39
lib/test/utils/transform_trackingnet.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import numpy as np
|
||||
import os
|
||||
import shutil
|
||||
import argparse
|
||||
import _init_paths
|
||||
from lib.test.evaluation.environment import env_settings
|
||||
|
||||
|
||||
def transform_trackingnet(tracker_name, cfg_name):
|
||||
env = env_settings()
|
||||
result_dir = env.results_path
|
||||
src_dir = os.path.join(result_dir, "%s/%s/trackingnet/" % (tracker_name, cfg_name))
|
||||
dest_dir = os.path.join(result_dir, "%s/%s/trackingnet_submit/" % (tracker_name, cfg_name))
|
||||
if not os.path.exists(dest_dir):
|
||||
os.makedirs(dest_dir)
|
||||
items = os.listdir(src_dir)
|
||||
for item in items:
|
||||
if "all" in item:
|
||||
continue
|
||||
if "time" not in item:
|
||||
src_path = os.path.join(src_dir, item)
|
||||
dest_path = os.path.join(dest_dir, item)
|
||||
bbox_arr = np.loadtxt(src_path, dtype=np.int, delimiter='\t')
|
||||
np.savetxt(dest_path, bbox_arr, fmt='%d', delimiter=',')
|
||||
# make zip archive
|
||||
shutil.make_archive(src_dir, "zip", src_dir)
|
||||
shutil.make_archive(dest_dir, "zip", dest_dir)
|
||||
# Remove the original files
|
||||
shutil.rmtree(src_dir)
|
||||
shutil.rmtree(dest_dir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='transform trackingnet results.')
|
||||
parser.add_argument('--tracker_name', type=str, help='Name of tracking method.')
|
||||
parser.add_argument('--cfg_name', type=str, help='Name of config file.')
|
||||
|
||||
args = parser.parse_args()
|
||||
transform_trackingnet(args.tracker_name, args.cfg_name)
|
Reference in New Issue
Block a user