Spaces:
Running
Running
File size: 7,886 Bytes
a80d6bb |
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 138 139 140 141 142 143 144 |
import numpy as np
import torch
import torch.utils.data as data
import cv2
import os
import h5py
import random
import sys
ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
sys.path.insert(0, ROOT_DIR)
from utils import train_utils,evaluation_utils
torch.multiprocessing.set_sharing_strategy('file_system')
class Offline_Dataset(data.Dataset):
def __init__(self,config,mode):
assert mode=='train' or mode=='valid'
self.config = config
self.mode = mode
metadir=os.path.join(config.dataset_path,'valid') if mode=='valid' else os.path.join(config.dataset_path,'train')
pair_num_list=np.loadtxt(os.path.join(metadir,'pair_num.txt'),dtype=str)
self.total_pairs=int(pair_num_list[0,1])
self.pair_seq_list,self.accu_pair_num=train_utils.parse_pair_seq(pair_num_list)
def collate_fn(self, batch):
batch_size, num_pts = len(batch), batch[0]['x1'].shape[0]
data = {}
dtype=['x1','x2','kpt1','kpt2','desc1','desc2','num_corr','num_incorr1','num_incorr2','e_gt','pscore1','pscore2','img_path1','img_path2']
for key in dtype:
data[key]=[]
for sample in batch:
for key in dtype:
data[key].append(sample[key])
for key in ['x1', 'x2','kpt1','kpt2', 'desc1', 'desc2','e_gt','pscore1','pscore2']:
data[key] = torch.from_numpy(np.stack(data[key])).float()
for key in ['num_corr', 'num_incorr1', 'num_incorr2']:
data[key] = torch.from_numpy(np.stack(data[key])).int()
# kpt augmentation with random homography
if (self.mode == 'train' and self.config.data_aug):
homo_mat = torch.from_numpy(train_utils.get_rnd_homography(batch_size)).unsqueeze(1)
aug_seed=random.random()
if aug_seed<0.5:
x1_homo = torch.cat([data['x1'], torch.ones([batch_size, num_pts, 1])], dim=-1).unsqueeze(-1)
x1_homo = torch.matmul(homo_mat.float(), x1_homo.float()).squeeze(-1)
data['aug_x1'] = x1_homo[:, :, :2] / x1_homo[:, :, 2].unsqueeze(-1)
data['aug_x2']=data['x2']
else:
x2_homo = torch.cat([data['x2'], torch.ones([batch_size, num_pts, 1])], dim=-1).unsqueeze(-1)
x2_homo = torch.matmul(homo_mat.float(), x2_homo.float()).squeeze(-1)
data['aug_x2'] = x2_homo[:, :, :2] / x2_homo[:, :, 2].unsqueeze(-1)
data['aug_x1']=data['x1']
else:
data['aug_x1'],data['aug_x2']=data['x1'],data['x2']
return data
def __getitem__(self, index):
seq=self.pair_seq_list[index]
index_within_seq=index-self.accu_pair_num[seq]
with h5py.File(os.path.join(self.config.dataset_path,seq,'info.h5py'),'r') as data:
R,t = data['dR'][str(index_within_seq)][()], data['dt'][str(index_within_seq)][()]
egt = np.reshape(np.matmul(np.reshape(evaluation_utils.np_skew_symmetric(t.astype('float64').reshape(1, 3)), (3, 3)),np.reshape(R.astype('float64'), (3, 3))), (3, 3))
egt = egt / np.linalg.norm(egt)
K1, K2 = data['K1'][str(index_within_seq)][()],data['K2'][str(index_within_seq)][()]
size1,size2=data['size1'][str(index_within_seq)][()],data['size2'][str(index_within_seq)][()]
img_path1,img_path2=data['img_path1'][str(index_within_seq)][()][0].decode(),data['img_path2'][str(index_within_seq)][()][0].decode()
img_name1,img_name2=img_path1.split('/')[-1],img_path2.split('/')[-1]
img_path1,img_path2=os.path.join(self.config.rawdata_path,img_path1),os.path.join(self.config.rawdata_path,img_path2)
fea_path1,fea_path2=os.path.join(self.config.desc_path,seq,img_name1+self.config.desc_suffix),\
os.path.join(self.config.desc_path,seq,img_name2+self.config.desc_suffix)
with h5py.File(fea_path1,'r') as fea1, h5py.File(fea_path2,'r') as fea2:
desc1,kpt1,pscore1=fea1['descriptors'][()],fea1['keypoints'][()][:,:2],fea1['keypoints'][()][:,2]
desc2,kpt2,pscore2=fea2['descriptors'][()],fea2['keypoints'][()][:,:2],fea2['keypoints'][()][:,2]
kpt1,kpt2,desc1,desc2=kpt1[:self.config.num_kpt],kpt2[:self.config.num_kpt],desc1[:self.config.num_kpt],desc2[:self.config.num_kpt]
# normalize kpt
if self.config.input_normalize=='intrinsic':
x1, x2 = np.concatenate([kpt1, np.ones([kpt1.shape[0], 1])], axis=-1), np.concatenate(
[kpt2, np.ones([kpt2.shape[0], 1])], axis=-1)
x1, x2 = np.matmul(np.linalg.inv(K1), x1.T).T[:, :2], np.matmul(np.linalg.inv(K2), x2.T).T[:, :2]
elif self.config.input_normalize=='img' :
x1,x2=(kpt1-size1/2)/size1,(kpt2-size2/2)/size2
S1_inv,S2_inv=np.asarray([[size1[0],0,0.5*size1[0]],[0,size1[1],0.5*size1[1]],[0,0,1]]),\
np.asarray([[size2[0],0,0.5*size2[0]],[0,size2[1],0.5*size2[1]],[0,0,1]])
M1,M2=np.matmul(np.linalg.inv(K1),S1_inv),np.matmul(np.linalg.inv(K2),S2_inv)
egt=np.matmul(np.matmul(M2.transpose(),egt),M1)
egt = egt / np.linalg.norm(egt)
else:
raise NotImplementedError
corr=data['corr'][str(index_within_seq)][()]
incorr1,incorr2=data['incorr1'][str(index_within_seq)][()],data['incorr2'][str(index_within_seq)][()]
#permute kpt
valid_corr=corr[corr.max(axis=-1)<self.config.num_kpt]
valid_incorr1,valid_incorr2=incorr1[incorr1<self.config.num_kpt],incorr2[incorr2<self.config.num_kpt]
num_corr, num_incorr1, num_incorr2 = len(valid_corr), len(valid_incorr1), len(valid_incorr2)
mask1_invlaid, mask2_invalid = np.ones(x1.shape[0]).astype(bool), np.ones(x2.shape[0]).astype(bool)
mask1_invlaid[valid_corr[:, 0]] = False
mask2_invalid[valid_corr[:, 1]] = False
mask1_invlaid[valid_incorr1] = False
mask2_invalid[valid_incorr2] = False
invalid_index1,invalid_index2=np.nonzero(mask1_invlaid)[0],np.nonzero(mask2_invalid)[0]
#random sample from point w/o valid annotation
cur_kpt1 = self.config.num_kpt - num_corr - num_incorr1
cur_kpt2 = self.config.num_kpt - num_corr - num_incorr2
if (invalid_index1.shape[0] < cur_kpt1):
sub_idx1 = np.concatenate([np.arange(len(invalid_index1)),np.random.randint(len(invalid_index1),size=cur_kpt1-len(invalid_index1))])
if (invalid_index1.shape[0] >= cur_kpt1):
sub_idx1 =np.random.choice(len(invalid_index1), cur_kpt1,replace=False)
if (invalid_index2.shape[0] < cur_kpt2):
sub_idx2 = np.concatenate([np.arange(len(invalid_index2)),np.random.randint(len(invalid_index2),size=cur_kpt2-len(invalid_index2))])
if (invalid_index2.shape[0] >= cur_kpt2):
sub_idx2 = np.random.choice(len(invalid_index2), cur_kpt2,replace=False)
per_idx1,per_idx2=np.concatenate([valid_corr[:,0],valid_incorr1,invalid_index1[sub_idx1]]),\
np.concatenate([valid_corr[:,1],valid_incorr2,invalid_index2[sub_idx2]])
pscore1,pscore2=pscore1[per_idx1][:,np.newaxis],pscore2[per_idx2][:,np.newaxis]
x1,x2=x1[per_idx1][:,:2],x2[per_idx2][:,:2]
desc1,desc2=desc1[per_idx1],desc2[per_idx2]
kpt1,kpt2=kpt1[per_idx1],kpt2[per_idx2]
return {'x1': x1, 'x2': x2, 'kpt1':kpt1,'kpt2':kpt2,'desc1': desc1, 'desc2': desc2, 'num_corr': num_corr, 'num_incorr1': num_incorr1,'num_incorr2': num_incorr2,'e_gt':egt,\
'pscore1':pscore1,'pscore2':pscore2,'img_path1':img_path1,'img_path2':img_path2}
def __len__(self):
return self.total_pairs
|