saptak21 commited on
Commit
bcebb15
·
verified ·
1 Parent(s): d595be7

Upload 73 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. data/face_model.txt +50 -0
  3. datasets/__init__.py +0 -0
  4. datasets/eyediap.py +103 -0
  5. datasets/gaze360.py +106 -0
  6. datasets/gazecapture.py +132 -0
  7. datasets/helper/image_transform.py +81 -0
  8. datasets/mpiigaze.py +109 -0
  9. datasets/xgaze.py +137 -0
  10. examples/De_Nachtwacht.png +3 -0
  11. examples/The_Night_Watch_Frans_Banninck_Cocq.png +3 -0
  12. gazelib/__init__.py +1 -0
  13. gazelib/draw/__init__.py +0 -0
  14. gazelib/draw/draw_image.py +69 -0
  15. gazelib/gaze/__init__.py +1 -0
  16. gazelib/gaze/gaze_utils.py +166 -0
  17. gazelib/gaze/normalize.py +266 -0
  18. gazelib/label_transform.py +195 -0
  19. gazelib/utils/__init__.py +4 -0
  20. gazelib/utils/color_text.py +85 -0
  21. gazelib/utils/h5_utils.py +53 -0
  22. models/hybrid_tr.py +570 -0
  23. models/resnet.py +366 -0
  24. models/vit/mae.py +429 -0
  25. models/vit/mae_gaze.py +69 -0
  26. models/vit/vit_gaze.py +103 -0
  27. unigaze/__init__.py +0 -0
  28. unigaze/configs/config.yaml +38 -0
  29. unigaze/configs/data/eyediap_cs.yaml +22 -0
  30. unigaze/configs/data/eyediap_cs_test.yaml +22 -0
  31. unigaze/configs/data/eyediap_cs_train.yaml +22 -0
  32. unigaze/configs/data/eyediap_ft.yaml +24 -0
  33. unigaze/configs/data/eyediap_ft_test.yaml +24 -0
  34. unigaze/configs/data/eyediap_ft_train.yaml +24 -0
  35. unigaze/configs/data/gaze360_test.yaml +74 -0
  36. unigaze/configs/data/gaze360_train.yaml +252 -0
  37. unigaze/configs/data/gazecapture_test.yaml +15 -0
  38. unigaze/configs/data/gazecapture_test_ds15.yaml +16 -0
  39. unigaze/configs/data/gazecapture_train.yaml +1189 -0
  40. unigaze/configs/data/gazecapture_train_ds15.yaml +1189 -0
  41. unigaze/configs/data/mpiigaze.yaml +24 -0
  42. unigaze/configs/data/mpiigaze_test.yaml +24 -0
  43. unigaze/configs/data/mpiigaze_train.yaml +24 -0
  44. unigaze/configs/data/xgaze_0_60sub.yaml +76 -0
  45. unigaze/configs/data/xgaze_0_60sub_d3.yaml +80 -0
  46. unigaze/configs/data/xgaze_0_80sub.yaml +97 -0
  47. unigaze/configs/data/xgaze_0_80sub_d3.yaml +97 -0
  48. unigaze/configs/data/xgaze_60_80sub.yaml +31 -0
  49. unigaze/configs/exp/blank.yaml +22 -0
  50. unigaze/configs/exp/cross/train_ED.yaml +27 -0
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ examples/De_Nachtwacht.png filter=lfs diff=lfs merge=lfs -text
37
+ examples/The_Night_Watch_Frans_Banninck_Cocq.png filter=lfs diff=lfs merge=lfs -text
data/face_model.txt ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 5.862468481063842773e-01 7.872964477539062500e+01 2.317634201049804688e+01
2
+ -5.711375045776367188e+01 -5.130039978027343750e+01 4.678271484375000000e+01
3
+ -5.021675109863281250e+01 -5.602691268920898438e+01 3.416214370727539062e+01
4
+ -3.879566955566406250e+01 -5.690497207641601562e+01 2.192905616760253906e+01
5
+ -2.962696456909179688e+01 -5.768646621704101562e+01 1.585745716094970703e+01
6
+ -1.556392288208007812e+01 -5.381772232055664062e+01 1.200321197509765625e+01
7
+ 1.493891811370849609e+01 -5.252636718750000000e+01 1.241601753234863281e+01
8
+ 2.762125968933105469e+01 -5.633798599243164062e+01 1.620070838928222656e+01
9
+ 3.687218856811523438e+01 -5.588240051269531250e+01 2.234012985229492188e+01
10
+ 4.801872634887695312e+01 -5.413969039916992188e+01 3.287670516967773438e+01
11
+ 5.493420410156250000e+01 -4.876091766357421875e+01 4.391139984130859375e+01
12
+ 9.755885004997253418e-01 -3.599571609497070312e+01 1.533371734619140625e+01
13
+ 1.295488834381103516e+00 -1.837105178833007812e+01 1.295253086090087891e+01
14
+ 1.169039964675903320e+00 -5.502729415893554688e+00 6.933759689331054688e+00
15
+ 1.324353933334350586e+00 5.223155975341796875e+00 3.281763553619384766e+00
16
+ -1.061166477203369141e+01 1.295834922790527344e+01 2.162276458740234375e+01
17
+ -5.147602558135986328e+00 1.608338356018066406e+01 1.863278388977050781e+01
18
+ 7.948544025421142578e-01 1.780137062072753906e+01 1.740065383911132812e+01
19
+ 6.404633045196533203e+00 1.649684906005859375e+01 1.887524223327636719e+01
20
+ 1.128962993621826172e+01 1.386424446105957031e+01 2.183790016174316406e+01
21
+ -4.650949859619140625e+01 -3.832709503173828125e+01 3.641600418090820312e+01
22
+ -3.662562179565429688e+01 -4.003409194946289062e+01 2.697853851318359375e+01
23
+ -2.613725852966308594e+01 -4.035707473754882812e+01 2.568147850036621094e+01
24
+ -1.776072120666503906e+01 -3.258519744873046875e+01 2.907615661621093750e+01
25
+ -2.857307624816894531e+01 -3.133931159973144531e+01 2.851314163208007812e+01
26
+ -3.531597518920898438e+01 -3.336409759521484375e+01 2.953546142578125000e+01
27
+ 1.804391098022460938e+01 -3.095682334899902344e+01 2.906296730041503906e+01
28
+ 2.545973777770996094e+01 -3.785017395019531250e+01 2.660374259948730469e+01
29
+ 3.494161224365234375e+01 -3.641166687011718750e+01 2.815935897827148438e+01
30
+ 4.473758697509765625e+01 -3.410787200927734375e+01 3.673243713378906250e+01
31
+ 3.460580825805664062e+01 -2.936051368713378906e+01 3.002419853210449219e+01
32
+ 2.828340530395507812e+01 -2.810362434387207031e+01 2.857681274414062500e+01
33
+ -2.000109672546386719e+01 3.587311935424804688e+01 2.467940139770507812e+01
34
+ -1.517112541198730469e+01 3.055978584289550781e+01 2.077887535095214844e+01
35
+ -4.272953987121582031e+00 2.849174499511718750e+01 1.563890647888183594e+01
36
+ 9.129478931427001953e-01 2.940682983398437500e+01 1.530903434753417969e+01
37
+ 5.915512084960937500e+00 2.886590385437011719e+01 1.577433967590332031e+01
38
+ 1.609077262878417969e+01 3.112099075317382812e+01 2.045352745056152344e+01
39
+ 2.146691894531250000e+01 3.712250137329101562e+01 2.439267730712890625e+01
40
+ 1.636684226989746094e+01 4.110508346557617188e+01 2.019831085205078125e+01
41
+ 8.093836784362792969e+00 4.461882400512695312e+01 1.674007606506347656e+01
42
+ 6.376140713691711426e-01 4.504141998291015625e+01 1.691001510620117188e+01
43
+ -6.237400531768798828e+00 4.375403594970703125e+01 1.704776954650878906e+01
44
+ -1.439151859283447266e+01 4.025728225708007812e+01 2.136468315124511719e+01
45
+ -9.422926902770996094e+00 3.452179336547851562e+01 2.028252601623535156e+01
46
+ 1.115690827369689941e+00 3.555863952636718750e+01 1.827753639221191406e+01
47
+ 1.108111095428466797e+01 3.538360214233398438e+01 2.027869033813476562e+01
48
+ 1.114828586578369141e+01 3.651076889038085938e+01 2.039755630493164062e+01
49
+ 9.804738759994506836e-01 3.681156921386718750e+01 1.785094261169433594e+01
50
+ -9.598259925842285156e+00 3.567073822021484375e+01 2.036244964599609375e+01
datasets/__init__.py ADDED
File without changes
datasets/eyediap.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import h5py
4
+ import cv2
5
+ from torch.utils.data import Dataset
6
+ from typing import List
7
+ from omegaconf import OmegaConf, listconfig
8
+ from .helper.image_transform import wrap_transforms
9
+
10
+
11
+ class EYEDIAPDataset(Dataset):
12
+ def __init__(self,
13
+ dataset_path: str,
14
+ color_type,
15
+ keys_to_use: List[str] = None,
16
+ data_name=None,
17
+ image_size:int=224, ## <---
18
+ transform_type='basic_imagenet', ## <--- modified
19
+ image_key='face_patch',
20
+ gaze_key='face_gaze',
21
+ ):
22
+
23
+ self.path = dataset_path
24
+ self.hdfs = {}
25
+ self.data_name = data_name
26
+ self.image_key = image_key
27
+ self.gaze_key = gaze_key
28
+
29
+ self.image_size = (image_size, image_size)
30
+
31
+ assert color_type in ['rgb', 'bgr']
32
+ self.color_type = color_type
33
+ self.selected_keys = [k for k in keys_to_use]
34
+ assert len(self.selected_keys) > 0
35
+
36
+ self.file_paths = [os.path.join(self.path, k) for k in self.selected_keys]
37
+
38
+ for num_i in range(0, len(self.selected_keys)):
39
+ file_path = os.path.join(self.path, self.selected_keys[num_i]) # the subdirectories: train, test are not used in MPIIFaceGaze and MPII_Rotate
40
+ self.hdfs[num_i] = h5py.File(file_path, 'r', swmr=True)
41
+ print('read file: ', os.path.join(self.path, self.selected_keys[num_i]))
42
+ assert self.hdfs[num_i].swmr_mode
43
+
44
+ self.build_idx_to_kv()
45
+
46
+ for num_i in range(0, len(self.hdfs)):
47
+ if self.hdfs[num_i]:
48
+ self.hdfs[num_i].close()
49
+ self.hdfs[num_i] = None
50
+ self.transform = wrap_transforms(transform_type, image_size=image_size)
51
+ self.__hdfs = None
52
+ self.hdf = None
53
+
54
+ def __len__(self):
55
+ return len(self.idx_to_kv)
56
+
57
+ def __del__(self):
58
+ for num_i in range(0, len(self.hdfs)):
59
+ if self.hdfs[num_i]:
60
+ self.hdfs[num_i].close()
61
+ self.hdfs[num_i] = None
62
+
63
+ def build_idx_to_kv(self):
64
+ self.idx_to_kv = []
65
+ self.key_idx_dict = {}
66
+ for num_i in range(0, len(self.selected_keys)):
67
+ this_sub = self.selected_keys[num_i].split('.')[0]
68
+ n = self.hdfs[num_i][self.image_key].shape[0]
69
+ self.idx_to_kv += [(num_i, i) for i in range(n)]
70
+ self.key_idx_dict[this_sub] = [ i for i in range(n)]
71
+
72
+ @property
73
+ def archives(self):
74
+ if self.__hdfs is None: # lazy loading here!
75
+ self.__hdfs = [h5py.File(h5_path, "r", swmr=True) for h5_path in self.file_paths]
76
+ return self.__hdfs
77
+
78
+
79
+ def preprocess_image(self, image):
80
+ image = image.astype(np.float32)
81
+ if self.color_type == 'bgr':
82
+ image = image[..., ::-1]
83
+ image = cv2.resize(image, self.image_size, interpolation=cv2.INTER_AREA)
84
+ image = self.transform(image.astype(np.uint8) )
85
+ return image
86
+
87
+ def __getitem__(self, index):
88
+ key, idx = self.idx_to_kv[index]
89
+ self.hdf = self.archives[key]
90
+ assert self.hdf.swmr_mode
91
+
92
+ image = self.hdf[self.image_key][idx, :]
93
+ gaze_label = self.hdf[self.gaze_key][idx].astype('float') if self.gaze_key in self.hdf else np.array([0,0]).astype('float')
94
+ head_label = self.hdf['face_head_pose'][idx].astype('float') if 'face_head_pose' in self.hdf else np.array([0,0]).astype('float')
95
+
96
+ entry = {
97
+ 'image': self.preprocess_image(image),
98
+ 'gaze': gaze_label,
99
+ 'head': head_label,
100
+ 'key': key,
101
+ 'index':index
102
+ }
103
+ return entry
datasets/gaze360.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import h5py, cv2
4
+ from torch.utils.data import Dataset
5
+ from typing import List
6
+ from .helper.image_transform import wrap_transforms
7
+
8
+
9
+ class Gaze360Dataset(Dataset):
10
+ def __init__(self,
11
+ dataset_path: str,
12
+ color_type,
13
+ keys_to_use: List[str] = None,
14
+ data_name=None,
15
+ image_size:int=224,
16
+ transform_type='basic_imagenet',
17
+ image_key='face_patch',
18
+ gaze_key='face_gaze',
19
+ sample_rate_use=1,
20
+ ):
21
+ super().__init__()
22
+ self.dataset_path = dataset_path
23
+ self.hdfs = {}
24
+ self.data_name = data_name
25
+ self.image_key = image_key
26
+ self.gaze_key = gaze_key
27
+ self.image_size = (image_size, image_size)
28
+
29
+ assert color_type in ['rgb', 'bgr']
30
+ self.color_type = color_type
31
+ self.transform = wrap_transforms(transform_type, image_size=image_size)
32
+
33
+ self.sample_rate_use = sample_rate_use
34
+ #### -------------------------------------------------------- read the h5 files -------------------------------------------------------
35
+ self.selected_keys = [k for k in keys_to_use]
36
+ assert len(self.selected_keys) > 0
37
+ self.file_paths = [os.path.join(self.dataset_path, k) for k in self.selected_keys]
38
+ for num_i in range(0, len(self.selected_keys)):
39
+ file_path = os.path.join(self.dataset_path, self.selected_keys[num_i]) # the subdirectories: train, test are not used in MPIIFaceGaze and MPII_Rotate
40
+ self.hdfs[num_i] = h5py.File(file_path, 'r', swmr=True)
41
+ print('read file: ', os.path.join(self.dataset_path, self.selected_keys[num_i]))
42
+ assert self.hdfs[num_i].swmr_mode
43
+ ####-----------------------------------------------------------------------------------------------------------------------------------
44
+
45
+ self.build_idx_to_kv()
46
+ for num_i in range(0, len(self.hdfs)):
47
+ if self.hdfs[num_i]:
48
+ self.hdfs[num_i].close()
49
+ self.hdfs[num_i] = None
50
+
51
+ self.__hdfs = None
52
+ self.hdf = None
53
+
54
+ def build_idx_to_kv(self):
55
+ self.idx_to_kv = []
56
+ self.key_idx_dict = {}
57
+ for num_i in range(0, len(self.selected_keys)):
58
+ p_key = self.selected_keys[num_i].split('.')[0] ##p00
59
+ n = self.hdfs[num_i][self.image_key].shape[0]
60
+ if self.sample_rate_use > 1:
61
+ indices = np.arange(0, n, self.sample_rate_use)
62
+ else:
63
+ indices = np.arange(0, n)
64
+ self.idx_to_kv += [(num_i, i) for i in indices]
65
+ self.key_idx_dict[p_key] = [i for i in indices]
66
+
67
+
68
+ def __len__(self):
69
+ return len(self.idx_to_kv)
70
+
71
+ def __del__(self):
72
+ for num_i in range(0, len(self.hdfs)):
73
+ if self.hdfs[num_i]:
74
+ self.hdfs[num_i].close()
75
+ self.hdfs[num_i] = None
76
+
77
+ @property
78
+ def archives(self):
79
+ if self.__hdfs is None: # lazy loading here!
80
+ self.__hdfs = [h5py.File(h5_path, "r", swmr=True) for h5_path in self.file_paths]
81
+ return self.__hdfs
82
+
83
+ def preprocess_image(self, image):
84
+ image = image.astype(np.float32)
85
+ if self.color_type == 'bgr':
86
+ image = image[..., ::-1]
87
+ if image.shape[0] != self.image_size[0] or image.shape[1] != self.image_size[1]:
88
+ image = cv2.resize(image, self.image_size, interpolation=cv2.INTER_AREA)
89
+ image = self.transform(image.astype(np.uint8) )
90
+ return image
91
+
92
+ def __getitem__(self, index):
93
+ key, idx = self.idx_to_kv[index]
94
+ self.hdf = self.archives[key]
95
+ image = self.hdf[self.image_key][idx]
96
+ gaze_label = self.hdf[self.gaze_key][idx].astype('float') if self.gaze_key in self.hdf else np.array([0,0]).astype('float')
97
+ head_label = self.hdf['face_head_pose'][idx].astype('float') if 'face_head_pose' in self.hdf else np.array([0,0]).astype('float')
98
+ entry = {
99
+ 'image': self.preprocess_image(image),
100
+ 'gaze': gaze_label,
101
+ 'head': head_label,
102
+ 'key': idx,
103
+ 'index':index
104
+ }
105
+ return entry
106
+
datasets/gazecapture.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import h5py
4
+ import cv2
5
+ from torch.utils.data import Dataset
6
+ from typing import List
7
+ from omegaconf import OmegaConf, listconfig
8
+ from .helper.image_transform import wrap_transforms
9
+
10
+
11
+ class GazeCaptureDataset(Dataset):
12
+ def __init__(self,
13
+ dataset_path: str,
14
+ color_type,
15
+ keys_to_use: List[str] = None,
16
+ data_name=None,
17
+ image_size:int=224, ## <---
18
+ transform_type='basic_imagenet', ## <--- modified
19
+ image_key='face_patch',
20
+ gaze_key='face_gaze',
21
+ sample_rate_use=1,
22
+ ):
23
+
24
+ self.transform = wrap_transforms(transform_type, image_size=image_size)
25
+
26
+ self.path = dataset_path
27
+ self.hdfs = {}
28
+ self.data_name = data_name
29
+ self.image_key = image_key
30
+ self.gaze_key = gaze_key
31
+
32
+ self.image_size = (image_size, image_size)
33
+
34
+ self.sample_rate_use = sample_rate_use
35
+
36
+ assert color_type in ['rgb', 'bgr']
37
+ self.color_type = color_type
38
+ self.selected_keys = [ k for k in keys_to_use]
39
+ assert len(self.selected_keys) > 0
40
+
41
+ self.file_paths = [os.path.join(self.path, k) for k in self.selected_keys]
42
+ for num_i in range(0, len(self.selected_keys)):
43
+ file_path = os.path.join(self.path, self.selected_keys[num_i]) # the subdirectories: train, test are not used in MPIIFaceGaze and MPII_Rotate
44
+ self.hdfs[num_i] = h5py.File(file_path, 'r', swmr=True)
45
+ print('read file: ', os.path.join(self.path, self.selected_keys[num_i]))
46
+ assert self.hdfs[num_i].swmr_mode
47
+
48
+
49
+ self.build_idx_to_kv()
50
+
51
+
52
+ for num_i in range(0, len(self.hdfs)):
53
+ if self.hdfs[num_i]:
54
+ self.hdfs[num_i].close()
55
+ self.hdfs[num_i] = None
56
+
57
+ self.__hdfs = None
58
+ self.hdf = None
59
+
60
+ def __len__(self):
61
+ return len(self.idx_to_kv)
62
+
63
+ def __del__(self):
64
+ for num_i in range(0, len(self.hdfs)):
65
+ if self.hdfs[num_i]:
66
+ self.hdfs[num_i].close()
67
+ self.hdfs[num_i] = None
68
+
69
+ def build_idx_to_kv(self):
70
+ self.idx_to_kv = []
71
+ self.key_idx_dict = {}
72
+ for num_i in range(0, len(self.selected_keys)):
73
+ this_sub = self.selected_keys[num_i].split('.')[0]
74
+ n = self.hdfs[num_i][self.image_key].shape[0]
75
+ if self.sample_rate_use > 1:
76
+ indices = np.arange(0, n, self.sample_rate_use)
77
+ else:
78
+ indices = np.arange(0, n)
79
+ self.idx_to_kv += [(num_i, i) for i in indices ]
80
+ self.key_idx_dict[this_sub] = [ i for i in indices ]
81
+
82
+ @property
83
+ def archives(self):
84
+ if self.__hdfs is None: # lazy loading here!
85
+ self.__hdfs = [h5py.File(h5_path, "r", swmr=True) for h5_path in self.file_paths]
86
+ return self.__hdfs
87
+
88
+
89
+ def preprocess_image(self, image):
90
+ image = image.astype(np.float32)
91
+ if self.color_type == 'bgr':
92
+ image = image[..., ::-1]
93
+ image = cv2.resize(image, self.image_size, interpolation=cv2.INTER_AREA)
94
+ image = self.transform(image.astype(np.uint8) )
95
+ return image
96
+
97
+ def __getitem__(self, index):
98
+
99
+ key, idx = self.idx_to_kv[index]
100
+ self.hdf = self.archives[key]
101
+
102
+ # self.hdf = h5py.File(os.path.join(self.path, self.selected_keys[key]), 'r', swmr=True)
103
+ assert self.hdf.swmr_mode
104
+
105
+ image = self.hdf[self.image_key][idx, :]
106
+ gaze_label = self.hdf[self.gaze_key][idx].astype('float') if self.gaze_key in self.hdf else np.array([0,0]).astype('float')
107
+ head_label = self.hdf['face_head_pose'][idx].astype('float') if 'face_head_pose' in self.hdf else np.array([0,0]).astype('float')
108
+
109
+ entry = {
110
+ 'image': self.preprocess_image(image),
111
+ 'gaze': gaze_label,
112
+ 'head': head_label,
113
+ 'key': key,
114
+ 'index':index
115
+ }
116
+ return entry
117
+
118
+ # class GazeCaptureDatasetSubset(GazeCaptureDataset):
119
+ # def __init__(self, images_per_person=None, **kwargs):
120
+ # self.images_per_person = images_per_person
121
+ # super().__init__(**kwargs)
122
+
123
+ # def build_idx_to_kv(self):
124
+ # self.idx_to_kv = []
125
+ # self.key_idx_dict = {}
126
+ # for num_i in range(0, len(self.selected_keys)):
127
+ # this_sub = self.selected_keys[num_i].split('.')[0]
128
+ # n = self.hdfs[num_i][self.image_key].shape[0]
129
+ # if self.images_per_person is not None:
130
+ # n = min(n, self.images_per_person)
131
+ # self.idx_to_kv += [(num_i, i) for i in range(n)]
132
+ # self.key_idx_dict[this_sub] = [ i for i in range(n)]
datasets/helper/image_transform.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import cv2
3
+ from torchvision import transforms
4
+ import numpy as np
5
+ import torch
6
+
7
+ def re_normalize(image_tensor, old='[-1,1]', new='imagenet'):
8
+ """
9
+ Re-normalizes an image tensor from one normalization scheme to another.
10
+ Args:
11
+ image_tensor (torch.Tensor): Image tensor to be re-normalized.
12
+ old (str): Old normalization scheme. Options: '[-1,1]', 'imagenet'.
13
+ new (str): New normalization scheme. Options: '[-1,1]', 'imagenet'.
14
+ Returns:
15
+ torch.Tensor: Re-normalized image tensor.
16
+ """
17
+ # Old normalization parameters
18
+ device = image_tensor.device
19
+ if old == '[-1,1]':
20
+ old_mean = torch.tensor([0.5, 0.5, 0.5]).view(1, 3, 1, 1).to(device)
21
+ old_std = torch.tensor([0.5, 0.5, 0.5]).view(1, 3, 1, 1).to(device)
22
+ elif old == 'imagenet':
23
+ old_mean = torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1).to(device)
24
+ old_std = torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1).to(device)
25
+ elif old == '[0,1]':
26
+ old_mean = torch.tensor([0.0, 0.0, 0.0]).view(1, 3, 1, 1).to(device)
27
+ old_std = torch.tensor([1.0, 1.0, 1.0]).view(1, 3, 1, 1).to(device)
28
+ else:
29
+ print('old normalization not implemented')
30
+ raise NotImplementedError
31
+ # New normalization parameters
32
+ if new == '[-1,1]':
33
+ new_mean = torch.tensor([0.5, 0.5, 0.5]).view(1, 3, 1, 1).to(device)
34
+ new_std = torch.tensor([0.5, 0.5, 0.5]).view(1, 3, 1, 1).to(device)
35
+ elif new == 'imagenet':
36
+ new_mean = torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1).to(device)
37
+ new_std = torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1).to(device)
38
+ elif new == '[0,1]':
39
+ new_mean = torch.tensor([0.0, 0.0, 0.0]).view(1, 3, 1, 1).to(device)
40
+ new_std = torch.tensor([1.0, 1.0, 1.0]).view(1, 3, 1, 1).to(device)
41
+ else:
42
+ print('new normalization not implemented')
43
+ raise NotImplementedError
44
+ # Step 1: Denormalize the image tensor using the old mean and std
45
+ denormalized_image = image_tensor * old_std + old_mean
46
+ # Step 2: Normalize the image tensor using the new mean and std
47
+ normalized_image = (denormalized_image - new_mean) / new_std
48
+
49
+ return normalized_image
50
+
51
+
52
+
53
+
54
+
55
+
56
+ def wrap_transforms(image_transforms_type, image_size):
57
+
58
+
59
+ if image_transforms_type == 'basic_imagenet':
60
+ MEAN = [0.485, 0.456, 0.406]
61
+ STD = [0.229, 0.224, 0.225]
62
+ return transforms.Compose([
63
+ transforms.ToPILImage(),
64
+ transforms.ToTensor(),
65
+ transforms.Normalize(mean=MEAN, std=STD)
66
+ ])
67
+
68
+
69
+ else:
70
+ raise NotImplementedError
71
+
72
+
73
+
74
+ # def enhance_contrast_clahe(image):
75
+ # clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
76
+ # lab = cv2.cvtColor(image, cv2.COLOR_RGB2LAB)
77
+ # lab_planes = list( cv2.split(lab) )
78
+ # lab_planes[0] = clahe.apply(lab_planes[0])
79
+ # lab = cv2.merge(lab_planes)
80
+ # image = cv2.cvtColor(lab, cv2.COLOR_LAB2RGB)
81
+ # return image
datasets/mpiigaze.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import h5py
4
+ import cv2
5
+ from torch.utils.data import Dataset
6
+ from typing import List
7
+ from omegaconf import OmegaConf, listconfig
8
+ from .helper.image_transform import wrap_transforms
9
+
10
+
11
+ class MPIIGazeDataset(Dataset):
12
+ def __init__(self,
13
+ dataset_path: str,
14
+ color_type,
15
+ keys_to_use: List[str] = None,
16
+ data_name=None,
17
+ image_size:int=224, ## <---
18
+ transform_type='basic_imagenet', ## <--- modified
19
+ image_key='face_patch',
20
+ gaze_key='face_gaze',
21
+ ):
22
+
23
+ self.dataset_path = dataset_path
24
+ self.hdfs = {}
25
+ self.data_name = data_name
26
+ self.image_key = image_key
27
+ self.gaze_key = gaze_key
28
+ self.image_size = (image_size, image_size)
29
+
30
+ assert color_type in ['rgb', 'bgr']
31
+ self.color_type = color_type
32
+ self.transform = wrap_transforms(transform_type, image_size=image_size)
33
+
34
+
35
+ self.selected_keys = [k for k in keys_to_use]
36
+ assert len(self.selected_keys) > 0
37
+
38
+ self.file_paths = [os.path.join(self.dataset_path, k) for k in self.selected_keys]
39
+
40
+ for num_i in range(0, len(self.selected_keys)):
41
+ file_path = os.path.join(self.dataset_path, self.selected_keys[num_i]) # the subdirectories: train, test are not used in MPIIFaceGaze and MPII_Rotate
42
+ self.hdfs[num_i] = h5py.File(file_path, 'r', swmr=True)
43
+ print('read file: ', os.path.join(self.dataset_path, self.selected_keys[num_i]))
44
+ assert self.hdfs[num_i].swmr_mode
45
+
46
+ self.build_idx_to_kv()
47
+
48
+ for num_i in range(0, len(self.hdfs)):
49
+ if self.hdfs[num_i]:
50
+ self.hdfs[num_i].close()
51
+ self.hdfs[num_i] = None
52
+
53
+
54
+
55
+ self.__hdfs = None
56
+ self.hdf = None
57
+
58
+ def __len__(self):
59
+ return len(self.idx_to_kv)
60
+
61
+ def __del__(self):
62
+ for num_i in range(0, len(self.hdfs)):
63
+ if self.hdfs[num_i]:
64
+ self.hdfs[num_i].close()
65
+ self.hdfs[num_i] = None
66
+
67
+ def build_idx_to_kv(self):
68
+
69
+ self.idx_to_kv = []
70
+ self.key_idx_dict = {}
71
+ for num_i in range(0, len(self.selected_keys)):
72
+ p_key = self.selected_keys[num_i].split('.')[0] ##p00
73
+ n = self.hdfs[num_i][self.image_key].shape[0]
74
+ self.idx_to_kv += [(num_i, i) for i in range(n)]
75
+ self.key_idx_dict[p_key] = [i for i in range(n)]
76
+ @property
77
+ def archives(self):
78
+ if self.__hdfs is None: # lazy loading here!
79
+ self.__hdfs = [h5py.File(h5_path, "r", swmr=True) for h5_path in self.file_paths]
80
+ return self.__hdfs
81
+
82
+
83
+ def preprocess_image(self, image):
84
+ image = image.astype(np.float32)
85
+ if self.color_type == 'bgr':
86
+ image = image[..., ::-1]
87
+ if image.shape[0] != self.image_size[0] or image.shape[1] != self.image_size[1]:
88
+ image = cv2.resize(image, self.image_size, interpolation=cv2.INTER_AREA)
89
+ image = self.transform(image.astype(np.uint8) )
90
+ return image
91
+
92
+ def __getitem__(self, index):
93
+ key, idx = self.idx_to_kv[index]
94
+ self.hdf = self.archives[key]
95
+ # self.hdf = h5py.File(os.path.join(self.dataset_path, self.selected_keys[key]), 'r', swmr=True)
96
+ assert self.hdf.swmr_mode
97
+ image = self.hdf[self.image_key][idx, :]
98
+ gaze_label = self.hdf[self.gaze_key][idx].astype('float') if self.gaze_key in self.hdf else np.array([0,0]).astype('float')
99
+ head_label = self.hdf['face_head_pose'][idx].astype('float') if 'face_head_pose' in self.hdf else np.array([0,0]).astype('float')
100
+ entry = {
101
+ 'image': self.preprocess_image(image),
102
+ 'gaze': gaze_label,
103
+ 'head': head_label,
104
+ 'key': key,
105
+ 'index':index
106
+ }
107
+
108
+ return entry
109
+
datasets/xgaze.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os,random
2
+ import numpy as np
3
+ import h5py
4
+ import cv2
5
+ from typing import List
6
+ from torch.utils.data import Dataset
7
+ from .helper.image_transform import wrap_transforms
8
+
9
+ class XGazeDataset(Dataset):
10
+ def __init__(self,
11
+ dataset_path: str,
12
+ color_type,
13
+ images_per_frame,
14
+ keys_to_use: List[str] = None,
15
+ data_name=None,
16
+ image_size:int=224,
17
+ transform_type='basic_imagenet', ## <--- modified
18
+ image_key='face_patch',
19
+ gaze_key='face_gaze',
20
+ camera_random=None,
21
+ frame_tag=[0,1000],
22
+ seed=0,
23
+ ):
24
+
25
+ self.path = dataset_path
26
+ self.hdfs = {}
27
+ self.data_name = data_name
28
+ self.images_per_frame = images_per_frame
29
+
30
+ print('images_per_frame: ', images_per_frame)
31
+ self.image_key = image_key
32
+ self.gaze_key = gaze_key
33
+ self.image_size = (image_size, image_size)
34
+ random.seed(seed)
35
+
36
+ assert color_type in ['rgb', 'bgr']
37
+ self.color_type = color_type
38
+ self.cameras_idx = list(range(self.images_per_frame))
39
+ self.camera_random = camera_random
40
+
41
+ #### -------------------------------------------------------- read the h5 files -------------------------------------------------------
42
+ self.selected_keys = [k for k in keys_to_use]
43
+ assert len(self.selected_keys) > 0
44
+ self.file_paths = [os.path.join(self.path, k) for k in self.selected_keys]
45
+ for num_i in range(0, len(self.selected_keys)):
46
+ file_path = os.path.join(self.path, self.selected_keys[num_i]) # the subdirectories: train, test are not used in MPIIFaceGaze and MPII_Rotate
47
+ self.hdfs[num_i] = h5py.File(file_path, 'r', swmr=True)
48
+ print('read file: ', os.path.join(self.path, self.selected_keys[num_i]))
49
+ assert self.hdfs[num_i].swmr_mode
50
+ ####-----------------------------------------------------------------------------------------------------------------------------------
51
+
52
+
53
+ self.idx_to_kv = []
54
+ self.key_idx_dict = {} ## this is for reading the second sample from the same person
55
+ for num_i in range(0, len(self.selected_keys)):
56
+ this_sub = self.selected_keys[num_i].split('.')[0]
57
+ n = self.hdfs[num_i][image_key].shape[0]
58
+
59
+ if type(frame_tag) == list:
60
+ self.start_frame, self.end_frame = frame_tag
61
+ elif frame_tag == 'all':
62
+ self.start_frame, self.end_frame = 0, 10000
63
+ else:
64
+ raise ValueError("frame_tag should be either a list of integers or str 'all' ")
65
+ start_idx = min(n, self.start_frame * self.images_per_frame)
66
+ end_idx = min(n, self.end_frame * self.images_per_frame)
67
+
68
+ if self.camera_random is None:
69
+ self.idx_to_kv += [(num_i, i) for i in range(start_idx, end_idx) if (i % self.images_per_frame ) in self.cameras_idx ]
70
+ self.key_idx_dict[this_sub] = [ i for i in range(start_idx, end_idx) if (i % self.images_per_frame ) in self.cameras_idx ]
71
+ else:
72
+ for frame in range(start_idx // self.images_per_frame, end_idx // self.images_per_frame):
73
+ frame_start_idx = frame * self.images_per_frame
74
+ frame_end_idx = frame_start_idx + self.images_per_frame
75
+
76
+ # Randomly select self.images_per_frame camera indices for this frame
77
+ random_cameras_idx = random.sample(range(self.images_per_frame), self.camera_random)
78
+ self.idx_to_kv += [(num_i, i) for i in range(frame_start_idx, frame_end_idx) if (i % self.images_per_frame) in random_cameras_idx]
79
+ self.key_idx_dict.setdefault(this_sub, []).extend(
80
+ [i for i in range(frame_start_idx, frame_end_idx) if (i % self.images_per_frame) in random_cameras_idx]
81
+ )
82
+
83
+ for num_i in range(0, len(self.hdfs)):
84
+ if self.hdfs[num_i]:
85
+ self.hdfs[num_i].close()
86
+ self.hdfs[num_i] = None
87
+
88
+ self.transform = wrap_transforms(transform_type, image_size=image_size)
89
+ self.__hdfs = None
90
+ self.hdf = None
91
+
92
+
93
+ def __len__(self):
94
+ return len(self.idx_to_kv)
95
+
96
+ def __del__(self):
97
+ for num_i in range(0, len(self.hdfs)):
98
+ if self.hdfs[num_i]:
99
+ self.hdfs[num_i].close()
100
+ self.hdfs[num_i] = None
101
+
102
+
103
+ @property
104
+ def archives(self):
105
+ if self.__hdfs is None: # lazy loading here!
106
+ self.__hdfs = [h5py.File(h5_path, "r", swmr=True) for h5_path in self.file_paths]
107
+ return self.__hdfs
108
+
109
+ def preprocess_image(self, image):
110
+ image = image.astype(np.float32)
111
+ if self.color_type == 'bgr':
112
+ image = image[..., ::-1]
113
+ if image.shape[0] != self.image_size[0] or image.shape[1] != self.image_size[1]:
114
+ image = cv2.resize(image, self.image_size, interpolation=cv2.INTER_AREA)
115
+
116
+ image = self.transform( image.astype(np.uint8) )
117
+ return image
118
+
119
+ def __getitem__(self, index):
120
+ key, idx = self.idx_to_kv[index]
121
+ self.hdf = self.archives[key]
122
+ assert self.hdf.swmr_mode
123
+ image = self.hdf[self.image_key][idx, :]
124
+ gaze_label = self.hdf[self.gaze_key][idx].astype('float') if self.gaze_key in self.hdf else np.array([0,0]).astype('float')
125
+ head_label = self.hdf['face_head_pose'][idx].astype('float') if 'face_head_pose' in self.hdf else np.array([0,0]).astype('float')
126
+
127
+ entry = {
128
+ 'image': self.preprocess_image(image),
129
+ 'gaze': gaze_label,
130
+ 'head': head_label,
131
+ 'key': key,
132
+ 'index':index
133
+ }
134
+
135
+ return entry
136
+
137
+
examples/De_Nachtwacht.png ADDED

Git LFS Details

  • SHA256: f95e98d7e7a725599ae1b3f7f86978834aba8773806947a94378902540b07d58
  • Pointer size: 133 Bytes
  • Size of remote file: 12.2 MB
examples/The_Night_Watch_Frans_Banninck_Cocq.png ADDED

Git LFS Details

  • SHA256: 3468d4cf328e965a68e797cad000b7d3007a40fc1a5fb4d9b15620cea184ad7c
  • Pointer size: 131 Bytes
  • Size of remote file: 591 kB
gazelib/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+
gazelib/draw/__init__.py ADDED
File without changes
gazelib/draw/draw_image.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+
3
+
4
+ import torch
5
+ import numpy as np
6
+
7
+
8
+ def recover_image( image_tensor, MEAN=[0.5, 0.5, 0.5], STD=[0.5, 0.5, 0.5]):
9
+ """
10
+ read a tensor and recover it to image in cv2 format
11
+ args:
12
+ image_tensor: [C, H, W] or [B, C, H, W]
13
+ return:
14
+ image_save: [B, H, W, C]
15
+ """
16
+ if image_tensor.ndim == 3:
17
+ image_tensor = image_tensor.unsqueeze(0)
18
+
19
+ x = torch.mul(image_tensor, torch.FloatTensor(STD).view(3,1,1).to(image_tensor.device))
20
+ x = torch.add(x, torch.FloatTensor(MEAN).view(3,1,1).to(image_tensor.device) )
21
+ x = x.data.cpu().numpy()
22
+ # [C, H, W] -> [H, W, C]
23
+ image_rgb = np.transpose(x, (0, 2, 3, 1))
24
+ # RGB -> BGR
25
+ image_bgr = image_rgb[:, :, :, [2,1,0]]
26
+ # float -> int
27
+ image_save = np.clip(image_bgr*255, 0, 255).astype('uint8')
28
+
29
+ return image_save
30
+
31
+
32
+ def draw_lm(image, landmarks, color= (0, 0, 255), radius = 20, print_idx=False):
33
+ i = 0
34
+ image_out = image.copy()
35
+ for x,y in landmarks:
36
+ # Radius of circle
37
+ # Line thickness of 2 px
38
+ thickness = -1
39
+ image_out = cv2.circle(image_out, (int(x), int(y)), radius, color, thickness)
40
+
41
+ if print_idx:
42
+ image_out = cv2.putText(image_out,
43
+ text=str(i),
44
+ org=(int(x), int(y)),
45
+ fontFace=cv2.FONT_HERSHEY_SIMPLEX,
46
+ fontScale=2.0,
47
+ color=color,
48
+ thickness=2,
49
+ lineType=cv2.LINE_4)
50
+
51
+ i += 1
52
+
53
+ return image_out
54
+
55
+
56
+ def draw_gaze(image_in, pitchyaw, thickness=2, color=(0, 0, 255)):
57
+ """Draw gaze angle on given image with a given eye positions."""
58
+ image_out = image_in.copy()
59
+ (h, w) = image_in.shape[:2]
60
+ length = w / 2.0
61
+ pos = (int(h / 2.0), int(w / 2.0))
62
+ if len(image_out.shape) == 2 or image_out.shape[2] == 1:
63
+ image_out = cv2.cvtColor(image_out, cv2.COLOR_GRAY2BGR)
64
+ dx = -length * np.sin(pitchyaw[1]) * np.cos(pitchyaw[0])
65
+ dy = -length * np.sin(pitchyaw[0])
66
+ cv2.arrowedLine(image_out, tuple(np.round(pos).astype(np.int32)),
67
+ tuple(np.round([pos[0] + dx, pos[1] + dy]).astype(int)), color,
68
+ thickness, cv2.LINE_AA, tipLength=0.2)
69
+ return image_out
gazelib/gaze/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from .gaze_utils import pitchyaw_to_vector, vector_to_pitchyaw, angular_error
gazelib/gaze/gaze_utils.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import imageio
4
+ import cv2
5
+ import h5py
6
+ import math
7
+ import torch
8
+
9
+ def pitchyaw_to_vector(pitchyaws):
10
+ r"""Convert given yaw (:math:`\theta`) and pitch (:math:`\phi`) angles to unit gaze vectors.
11
+
12
+ Args:
13
+ pitchyaws: Input array of yaw and pitch angles, either numpy array or tensor.
14
+
15
+ Returns:
16
+ Output array of shape (n x 3) with 3D vectors per row, of the same type as the input.
17
+ """
18
+ if isinstance(pitchyaws, np.ndarray):
19
+ return pitchyaw_to_vector_numpy(pitchyaws)
20
+ elif isinstance(pitchyaws, torch.Tensor):
21
+ return pitchyaw_to_vector_torch(pitchyaws)
22
+ else:
23
+ raise ValueError("Unsupported input type. Only numpy arrays and torch tensors are supported.")
24
+
25
+ def pitchyaw_to_vector_numpy(pitchyaws):
26
+ n = pitchyaws.shape[0]
27
+ sin = np.sin(pitchyaws)
28
+ cos = np.cos(pitchyaws)
29
+ out = np.empty((n, 3))
30
+ out[:, 0] = np.multiply(cos[:, 0], sin[:, 1])
31
+ out[:, 1] = sin[:, 0]
32
+ out[:, 2] = np.multiply(cos[:, 0], cos[:, 1])
33
+ return out
34
+
35
+ def pitchyaw_to_vector_torch(pitchyaws):
36
+ n = pitchyaws.size()[0]
37
+ sin = torch.sin(pitchyaws)
38
+ cos = torch.cos(pitchyaws)
39
+ out = torch.empty((n, 3), device=pitchyaws.device)
40
+ out[:, 0] = torch.mul(cos[:, 0], sin[:, 1])
41
+ out[:, 1] = sin[:, 0]
42
+ out[:, 2] = torch.mul(cos[:, 0], cos[:, 1])
43
+ return out
44
+
45
+ def vector_to_pitchyaw(vectors):
46
+ """Convert given gaze vectors to pitch (theta) and yaw (phi) angles.
47
+
48
+ Args:
49
+ vectors: Input array of gaze vectors, either numpy array or tensor.
50
+
51
+ Returns:
52
+ Output array of shape (n x 2) with pitch and yaw angles, of the same type as the input.
53
+ """
54
+ if isinstance(vectors, np.ndarray):
55
+ return vector_to_pitchyaw_numpy(vectors)
56
+ elif isinstance(vectors, torch.Tensor):
57
+ return vector_to_pitchyaw_torch(vectors)
58
+ else:
59
+ raise ValueError("Unsupported input type. Only numpy arrays and torch tensors are supported.")
60
+
61
+ def vector_to_pitchyaw_numpy(vectors):
62
+ n = vectors.shape[0]
63
+ vectors = vectors / np.linalg.norm(vectors, axis=1).reshape(n, 1)
64
+ out = np.empty((n, 2))
65
+ out[:, 0] = np.arcsin(vectors[:, 1]) # theta
66
+ out[:, 1] = np.arctan2(vectors[:, 0], vectors[:, 2]) # phi
67
+ return out
68
+
69
+ def vector_to_pitchyaw_torch(vectors):
70
+ n = vectors.size()[0]
71
+ vectors = vectors / torch.norm(vectors, dim=1).reshape(n, 1)
72
+ out = torch.empty((n, 2), device=vectors.device)
73
+ out[:, 0] = torch.asin(vectors[:, 1]) # theta
74
+ out[:, 1] = torch.atan2(vectors[:, 0], vectors[:, 2]) # phi
75
+ return out
76
+
77
+
78
+ def angular_error(a, b):
79
+ """Calculate angular error (via cosine similarity)."""
80
+ if isinstance(a, np.ndarray) and isinstance(b, np.ndarray):
81
+ return angular_error_numpy(a, b)
82
+ elif isinstance(a, torch.Tensor) and isinstance(b, torch.Tensor):
83
+ return angular_error_torch(a, b)
84
+ else:
85
+ raise ValueError("Input type mismatch. Both inputs should be either numpy arrays or torch tensors.")
86
+
87
+ def angular_error_numpy(a, b):
88
+ """Calculate angular error for numpy arrays."""
89
+ a = pitchyaw_to_vector(a) if a.shape[1] == 2 else a
90
+ b = pitchyaw_to_vector(b) if b.shape[1] == 2 else b
91
+
92
+ ab = np.sum(np.multiply(a, b), axis=1)
93
+ a_norm = np.linalg.norm(a, axis=1)
94
+ b_norm = np.linalg.norm(b, axis=1)
95
+
96
+ # Avoid zero-values (to avoid NaNs)
97
+ a_norm = np.clip(a_norm, a_min=1e-7, a_max=None)
98
+ b_norm = np.clip(b_norm, a_min=1e-7, a_max=None)
99
+
100
+ similarity = np.divide(ab, np.multiply(a_norm, b_norm))
101
+
102
+ return np.arccos(similarity) * 180.0 / np.pi
103
+
104
+ def angular_error_torch(a, b):
105
+ """Calculate angular error for torch tensors."""
106
+ a = pitchyaw_to_vector(a) if a.size()[1] == 2 else a
107
+ b = pitchyaw_to_vector(b) if b.size()[1] == 2 else b
108
+
109
+ ab = torch.sum(a * b, dim=1)
110
+ a_norm = torch.norm(a, dim=1)
111
+ b_norm = torch.norm(b, dim=1)
112
+
113
+ # Avoid zero-values (to avoid NaNs)
114
+ a_norm = torch.clamp(a_norm, min=1e-7)
115
+ b_norm = torch.clamp(b_norm, min=1e-7)
116
+
117
+ similarity = ab / (a_norm * b_norm)
118
+
119
+ return torch.acos(similarity) * 180.0 / np.pi
120
+
121
+
122
+
123
+
124
+
125
+
126
+ def cos_similarity(a, b):
127
+ """Calculate angular error (via cosine similarity)."""
128
+ if isinstance(a, np.ndarray) and isinstance(b, np.ndarray):
129
+ return cos_similarity_numpy(a, b)
130
+ elif isinstance(a, torch.Tensor) and isinstance(b, torch.Tensor):
131
+ return cos_similarity_torch(a, b)
132
+ else:
133
+ raise ValueError("Input type mismatch. Both inputs should be either numpy arrays or torch tensors.")
134
+
135
+ def cos_similarity_numpy(a, b):
136
+ """Calculate angular error for numpy arrays."""
137
+ a = pitchyaw_to_vector(a) if a.shape[1] == 2 else a
138
+ b = pitchyaw_to_vector(b) if b.shape[1] == 2 else b
139
+
140
+ ab = np.sum(np.multiply(a, b), axis=1)
141
+ a_norm = np.linalg.norm(a, axis=1)
142
+ b_norm = np.linalg.norm(b, axis=1)
143
+ # Avoid zero-values (to avoid NaNs)
144
+ a_norm = np.clip(a_norm, a_min=1e-7, a_max=None)
145
+ b_norm = np.clip(b_norm, a_min=1e-7, a_max=None)
146
+ similarity = np.divide(ab, np.multiply(a_norm, b_norm))
147
+ similarity = np.clip(similarity, min=0., max=1.)
148
+ return similarity
149
+
150
+ def cos_similarity_torch(a, b):
151
+ """Calculate angular error for torch tensors."""
152
+ a = pitchyaw_to_vector(a) if a.size()[1] == 2 else a
153
+ b = pitchyaw_to_vector(b) if b.size()[1] == 2 else b
154
+
155
+ ab = torch.sum(a * b, dim=1)
156
+ a_norm = torch.norm(a, dim=1)
157
+ b_norm = torch.norm(b, dim=1)
158
+
159
+ # Avoid zero-values (to avoid NaNs)
160
+ a_norm = torch.clamp(a_norm, min=1e-7)
161
+ b_norm = torch.clamp(b_norm, min=1e-7)
162
+
163
+ similarity = ab / (a_norm * b_norm)
164
+ similarity = torch.clamp(similarity, min=0., max=1.)
165
+ return similarity
166
+
gazelib/gaze/normalize.py ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ ######################################################################################################################################
4
+ This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of this license,
5
+ visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
6
+
7
+ Any publications arising from the use of this software, including but
8
+ not limited to academic journal and conference publications, technical
9
+ reports and manuals, must cite at least one of the following works:
10
+
11
+ Revisiting Data Normalization for Appearance-Based Gaze Estimation
12
+ Xucong Zhang, Yusuke Sugano, Andreas Bulling
13
+ in Proc. International Symposium on Eye Tracking Research and Applications (ETRA), 2018
14
+ ######################################################################################################################################
15
+ """
16
+
17
+ import os
18
+ import cv2
19
+ import numpy as np
20
+ import csv
21
+ import argparse
22
+ # import dlib
23
+ import glob
24
+
25
+
26
+
27
+
28
+
29
+ def normalize_woimg(landmarks, focal_norm, distance_norm, roi_size, center, hr, ht, cam, gc=None):
30
+ center = center.reshape(3,1)
31
+ ## universal function for data normalization
32
+ hR = cv2.Rodrigues(hr)[0] # rotation matrix
33
+
34
+ ## ---------- normalize image ----------
35
+ distance = np.linalg.norm(center) # actual distance between eye and original camera
36
+
37
+ z_scale = distance_norm/distance
38
+ cam_norm = np.array([
39
+ [focal_norm, 0, roi_size[0]/2],
40
+ [0, focal_norm, roi_size[1]/2],
41
+ [0, 0, 1.0],
42
+ ])
43
+ S = np.array([ # scaling matrix
44
+ [1.0, 0.0, 0.0],
45
+ [0.0, 1.0, 0.0],
46
+ [0.0, 0.0, z_scale],
47
+ ])
48
+
49
+ hRx = hR[:,0]
50
+ forward = (center/distance).reshape(3)
51
+ down = np.cross(forward, hRx)
52
+ down /= np.linalg.norm(down)
53
+ right = np.cross(down, forward)
54
+ right /= np.linalg.norm(right)
55
+ R = np.c_[right, down, forward].T # rotation matrix R
56
+
57
+ W = np.dot(np.dot(cam_norm, S), np.dot(R, np.linalg.inv(cam))) # transformation matrix
58
+
59
+ ## ---------- normalize rotation ----------
60
+ hR_norm = np.dot(R, hR) # rotation matrix in normalized space
61
+ # hr_norm = cv2.Rodrigues(hR_norm)[0] # convert rotation matrix to rotation vectors
62
+
63
+ ## ---------- normalize gaze vector ----------
64
+ gc_normalized = None
65
+
66
+ num_point = landmarks.shape[0]
67
+ landmarks_warped = cv2.perspectiveTransform(landmarks.reshape(-1,1,2).astype('float32'), W)
68
+ landmarks_warped = landmarks_warped.reshape(num_point, 2)
69
+ if gc is not None:
70
+ gc_normalized = gc.reshape((3,1)) - center # gaze vector
71
+ # For modified data normalization, scaling is not applied to gaze direction (only R applied).
72
+ # For original data normalization, here should be:
73
+ # "M = np.dot(S,R)
74
+ # gc_normalized = np.dot(R, gc_normalized)"
75
+ gc_normalized = np.dot(R, gc_normalized)
76
+ gc_normalized = gc_normalized/np.linalg.norm(gc_normalized)
77
+
78
+ return [None, R, hR_norm, gc_normalized, landmarks_warped, W]
79
+
80
+
81
+ def normalize(img, landmarks, focal_norm, distance_norm, roi_size, center, hr, ht, cam, gc=None):
82
+ center = center.reshape(3,1)
83
+ ## universal function for data normalization
84
+ hR = cv2.Rodrigues(hr)[0] # rotation matrix
85
+
86
+ ## ---------- normalize image ----------
87
+ distance = np.linalg.norm(center) # actual distance between eye and original camera
88
+
89
+ z_scale = distance_norm/distance
90
+ cam_norm = np.array([
91
+ [focal_norm, 0, roi_size[0]/2],
92
+ [0, focal_norm, roi_size[1]/2],
93
+ [0, 0, 1.0],
94
+ ])
95
+ S = np.array([ # scaling matrix
96
+ [1.0, 0.0, 0.0],
97
+ [0.0, 1.0, 0.0],
98
+ [0.0, 0.0, z_scale],
99
+ ])
100
+
101
+ hRx = hR[:,0]
102
+ forward = (center/distance).reshape(3)
103
+ down = np.cross(forward, hRx)
104
+ down /= np.linalg.norm(down)
105
+ right = np.cross(down, forward)
106
+ right /= np.linalg.norm(right)
107
+ R = np.c_[right, down, forward].T # rotation matrix R
108
+ W = np.dot(np.dot(cam_norm, S), np.dot(R, np.linalg.inv(cam))) # transformation matrix
109
+
110
+ # if img is not None:
111
+ # img_warped = cv2.warpPerspective(img, W, roi_size) # image normalization
112
+ # else:
113
+ # img_warped = None
114
+
115
+ img_warped = cv2.warpPerspective(img, W, roi_size) # image normalization
116
+ ## ---------- normalize rotation ----------
117
+ hR_norm = np.dot(R, hR) # rotation matrix in normalized space
118
+ # hr_norm = cv2.Rodrigues(hR_norm)[0] # convert rotation matrix to rotation vectors
119
+
120
+ ## ---------- normalize gaze vector ----------
121
+ gc_normalized = None
122
+ num_point = landmarks.shape[0]
123
+ landmarks_warped = cv2.perspectiveTransform(landmarks.reshape(-1,1,2).astype('float32'), W)
124
+ landmarks_warped = landmarks_warped.reshape(num_point, 2)
125
+ if gc is not None:
126
+ gc_normalized = gc.reshape((3,1)) - center # gaze vector
127
+ # For modified data normalization, scaling is not applied to gaze direction (only R applied).
128
+ # For original data normalization, here should be:
129
+ # "M = np.dot(S,R)
130
+ # gc_normalized = np.dot(R, gc_normalized)"
131
+ gc_normalized = np.dot(R, gc_normalized)
132
+ gc_normalized = gc_normalized/np.linalg.norm(gc_normalized)
133
+
134
+ return [img_warped, R, hR_norm, gc_normalized, landmarks_warped, W]
135
+
136
+ def normalize_face(img, face, hr, ht, cam, gc=None):
137
+ ## normalized camera parameters
138
+ focal_norm = 960 # focal length of normalized camera
139
+ distance_norm = 600 # normalized distance between eye and camera
140
+ roi_size = (224, 224) # size of cropped eye image
141
+
142
+ ## compute estimated 3D positions of the landmarks
143
+ ht = ht.reshape((3,1))
144
+ hR = cv2.Rodrigues(hr)[0] # rotation matrix
145
+ Fc = np.dot(hR, face) + ht # 3D positions of facial landmarks
146
+ # fm = np.mean(Fc, axis=1).reshape((3,1)) # center of facial landmarks
147
+ two_eye_center = np.mean(Fc[:, 0:4], axis=1).reshape((3, 1))
148
+ nose_center = np.mean(Fc[:, 4:6], axis=1).reshape((3, 1))
149
+ # get the face center
150
+ face_center = np.mean(np.concatenate((two_eye_center, nose_center), axis=1), axis=1).reshape((3, 1))
151
+ # face_center = np.mean(Fc, axis=1).reshape((3,1))
152
+ return normalize(img, focal_norm, distance_norm, roi_size, face_center, hr, ht, cam, gc)
153
+
154
+ def normalize_eye(img, face, hr, ht, cam, gc=None):
155
+ ## normalized camera parameters
156
+ focal_norm = 960 # focal length of normalized camera
157
+ distance_norm = 600 # normalized distance between eye and camera
158
+ roi_size = (60, 36) # size of cropped eye image
159
+
160
+ ## compute estimated 3D positions of the landmarks
161
+ ht = ht.reshape((3,1))
162
+ hR = cv2.Rodrigues(hr)[0] # rotation matrix
163
+ Fc = np.dot(hR, face) + ht # 3D positions of facial landmarks
164
+ re = 0.5*(Fc[:,0] + Fc[:,1]).reshape((3,1)) # center of left eye
165
+ le = 0.5*(Fc[:,2] + Fc[:,3]).reshape((3,1)) # center of right eye
166
+
167
+ ## normalize each eye
168
+ data = [
169
+ normalize(img, focal_norm, distance_norm, roi_size, re, hr, ht, cam, gc),
170
+ normalize(img, focal_norm, distance_norm, roi_size, le, hr, ht, cam, gc)
171
+ ]
172
+ return data
173
+
174
+ def load_calibration(calib_path):
175
+ ## load calibration data, these paramters are expected to be obtained by camera calibration functions in OpenCV
176
+ fs = cv2.FileStorage(calib_path, cv2.FILE_STORAGE_READ)
177
+ camera_matrix = fs.getNode('camera_matrix').mat()
178
+ camera_distortion = fs.getNode('dist_coeffs').mat()
179
+ return camera_matrix, camera_distortion
180
+
181
+ def load_facemodel(model_path):
182
+ # load the generic face model, which includes 6 facial landmarks: four eye corners and two mouth corners
183
+ fs = cv2.FileStorage(model_path, cv2.FILE_STORAGE_READ)
184
+ face_model = fs.getNode('face_model').mat()
185
+ return face_model
186
+
187
+ def read_image(img_path, camera_matrix, camera_distortion):
188
+ # load input image and undistort
189
+ img_original = cv2.imread(img_path)
190
+ img = cv2.undistort(img_original, camera_matrix, camera_distortion)
191
+
192
+ return img
193
+
194
+ def estimateHeadPose(landmarks, face_model, camera, distortion, iterate=True):
195
+ ret, rvec, tvec = cv2.solvePnP(face_model, landmarks, camera, distortion, flags=cv2.SOLVEPNP_EPNP)
196
+
197
+ ## further optimize
198
+ if iterate:
199
+ ret, rvec, tvec = cv2.solvePnP(face_model, landmarks, camera, distortion, rvec, tvec, True)
200
+
201
+ return rvec, tvec
202
+
203
+ def detect_landmark(img, detector_path, predictor_path):
204
+ ## obtain facial landmarks using dlib
205
+ detector = dlib.cnn_face_detection_model_v1(detector_path)
206
+ dets = detector(img, 0)
207
+
208
+ if len(dets) == 0:
209
+ return None
210
+
211
+ predictor = dlib.shape_predictor(predictor_path)
212
+ shape = predictor(img, dets[0].rect)
213
+
214
+ ## extract required keypoints
215
+ landmarks = np.array([
216
+ [shape.part(36).x, shape.part(36).y],
217
+ [shape.part(39).x, shape.part(39).y],
218
+ [shape.part(42).x, shape.part(42).y],
219
+ [shape.part(45).x, shape.part(45).y],
220
+ [shape.part(48).x, shape.part(48).y],
221
+ [shape.part(54).x, shape.part(54).y]
222
+ ])
223
+
224
+ return landmarks
225
+
226
+
227
+ def read_landmark(img_path):
228
+ img_file = img_path.split(os.path.sep)[-1]
229
+ day = img_path.split(os.path.sep)[-2]
230
+ person = img_path.split(os.path.sep)[-3]
231
+ person_path = os.path.split(os.path.split(img_path)[0])[0]
232
+
233
+ person_txt = os.path.join(person_path, person+'.txt')
234
+ index = os.path.join(day,img_file)
235
+ print(person_txt)
236
+ print(index)
237
+
238
+ with open(person_txt) as f:
239
+ data = f.readlines()
240
+ reader = csv.reader(data)
241
+ p = {}
242
+ for row in reader:
243
+ words = row[0].split()
244
+ p[words[0]] = words[1:]
245
+ landmarks = np.array([int(i) for i in p[index][2:14]]).reshape((6,2))
246
+ return landmarks
247
+
248
+ # def process_image(img_path, detector_path, predictor_path, camera_matrix, camera_distortion, face_model, gc=None):
249
+ # # read input image
250
+ # img = read_image(img_path, camera_matrix, camera_distortion)
251
+
252
+ # # detect facial landmarks
253
+ # landmarks = detect_landmark(img, detector_path, predictor_path)
254
+
255
+ # if landmarks is not None:
256
+ # # estimate head pose
257
+ # hr, ht = estimateHeadPose(face_model, landmarks, camera_matrix, camera_distortion)
258
+
259
+ # # data normalization for left and right eye image
260
+ # normalized_eyes = normalize_eye(img, face_model, hr, ht, camera_matrix, gc)
261
+
262
+ # # data normalization for full face
263
+ # normalized_face = normalize_face(img, face_model, hr, ht, camera_matrix, gc)
264
+
265
+ # # return a list of [reye, leye, face]
266
+ # return normalized_eyes + [normalized_face]
gazelib/label_transform.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ import cv2
4
+
5
+ import numpy as np
6
+
7
+
8
+ def get_eye_nose_landmarks(landmarks):
9
+ assert landmarks.shape[0]==50 or landmarks.shape[0]==68
10
+ if landmarks.shape[0] == 50:
11
+ lm_6 = landmarks[[20, 23, 26, 29, 15, 19], :] # the eye and nose landmarks
12
+ elif landmarks.shape[0] == 68:
13
+ lm_6 = landmarks[[36, 39, 42, 45, 31, 35], :] # the eye and nose landmarks
14
+ return lm_6
15
+ def get_eye_mouth_landmarks(landmarks):
16
+ assert landmarks.shape[0]==50 or landmarks.shape[0]==68
17
+ if landmarks.shape[0] == 50:
18
+ lm_6 = landmarks[[20, 23, 26, 29, 32, 38], :] # the eye and nose landmarks
19
+ elif landmarks.shape[0] == 68:
20
+ lm_6 = landmarks[[36,39,42,45,48,54], :] # the eye and nose landmarks
21
+ return lm_6
22
+
23
+ def mean_eye_nose(landmarks):
24
+ assert landmarks.shape[0]==6
25
+ # get the face center
26
+ two_eye_center = np.mean(landmarks[0:4, :], axis=0).reshape(1,-1)
27
+ nose_center = np.mean(landmarks[4:6, :], axis=0).reshape(1,-1)
28
+ face_center = np.mean(np.concatenate((two_eye_center, nose_center), axis=0), axis=0).reshape(1,-1)
29
+ return face_center
30
+ def mean_eye_mouth(landmarks):
31
+ assert landmarks.shape[0]==6
32
+ face_center = np.mean(landmarks, axis=0).reshape(1,-1)
33
+ return face_center
34
+
35
+ def get_face_center_by_nose(hR, ht, face_model_load):
36
+ face_model = get_eye_nose_landmarks(face_model_load) # the eye and nose landmarks
37
+ Fc = np.dot(hR, face_model.T) + ht # 3D positions of facial landmarks
38
+ face_center = mean_eye_nose(Fc.T).reshape((3, 1)) # get the face center
39
+ return face_center, Fc
40
+
41
+ def get_face_center_by_mouth(hR, ht, face_model_load):
42
+ face_model = get_eye_mouth_landmarks(face_model_load) # the eye and nose landmarks
43
+ Fc = np.dot(hR, face_model.T) + ht # 3D positions of facial landmarks
44
+ face_center = mean_eye_mouth(Fc.T).reshape((3, 1)) # get the face center
45
+ return face_center, Fc
46
+
47
+ def lm68_to_50(lm_68):
48
+ '''
49
+ lm_68: (68,2)
50
+ '''
51
+ lm_50 = np.zeros((50,2))
52
+ lm_50[0] = lm_68[8]
53
+ lm_50[1:44] = lm_68[17:60]
54
+ lm_50[44:47] = lm_68[61:64]
55
+ lm_50[47:50] = lm_68[65:68]
56
+ return lm_50
57
+
58
+
59
+ def lm68_subset(lm_68, NUM_KPTS_TO_USE):
60
+ '''
61
+ lm_68: (68,2)
62
+ '''
63
+ if NUM_KPTS_TO_USE == 6:
64
+ lm_68 = np.array(lm_68, dtype=np.float32)
65
+ return lm_68[[36, 39, 42, 45, 31, 35], :]
66
+ elif NUM_KPTS_TO_USE ==50:
67
+ return lm68_to_50(lm_68)
68
+ else:
69
+ print('not supported yet')
70
+ exit(0)
71
+
72
+ def lm50_subset(lm_50, NUM_KPTS_TO_USE):
73
+ '''
74
+ lm_50: (50,2)
75
+ '''
76
+ lm_50 = lm_50.copy()
77
+ if NUM_KPTS_TO_USE == 6:
78
+ lm_50 = lm_50[[20, 23, 26, 29, 15, 19], :]
79
+ return lm_50
80
+ elif NUM_KPTS_TO_USE ==50:
81
+ return lm_50
82
+ else:
83
+ print('not supported yet')
84
+ exit(0)
85
+
86
+ def get_face_center(landmarks_3d):
87
+ '''
88
+ landmarks_3d: (3, 6)
89
+ -->
90
+ face_center: (3,1)
91
+ '''
92
+ two_eye_center = np.mean(landmarks_3d[:, 0:4], axis=1).reshape((3, 1))
93
+ nose_center = np.mean(landmarks_3d[:, 4:6], axis=1).reshape((3, 1))
94
+ face_center = np.mean(np.concatenate((two_eye_center, nose_center), axis=1), axis=1).reshape((3, 1))
95
+ return face_center
96
+
97
+
98
+
99
+ def compute_R(lm6, dataname):
100
+ '''
101
+ 6 landmarks in opencv coordinate
102
+ dataname: mpii or xgaze
103
+ the face center are computed differently
104
+ for mpii: the 6 landmarks are 4 eye + 2 mouth
105
+ for xgaze: the 6 landmarks are 4 eye + 2 nose
106
+ '''
107
+ if dataname=='mpii':
108
+ left_center = np.mean(lm6[2:4,:],axis=0)
109
+ right_center = np.mean(lm6[:2,:],axis=0)
110
+ face_center = np.mean(lm6,axis=0)
111
+ elif dataname=='xgaze':
112
+ left_center = np.mean(lm6[2:4,:],axis=0)
113
+ right_center = np.mean(lm6[:2,:],axis=0)
114
+ nose_center = np.mean(lm6[[4,5],:],axis=0)
115
+ face_center = ( (left_center + right_center)/2 + nose_center ) /2
116
+
117
+ distance = np.linalg.norm(face_center)
118
+
119
+ hRx = left_center - right_center
120
+ hRx /= np.linalg.norm(hRx)
121
+ forward = (face_center/distance).reshape(3)
122
+ down = np.cross(forward, hRx)
123
+ down /= np.linalg.norm(down)
124
+ right = np.cross(down, forward)
125
+ right /= np.linalg.norm(right)
126
+ R = np.c_[right, down, forward].T
127
+ return R
128
+
129
+ def rotation_matrix(x, y, z):
130
+ '''
131
+ x, y, z: roll, pitch, yaw, (radians)
132
+ '''
133
+ Rx = np.array([[1,0,0],
134
+ [0, np.cos(x), -np.sin(x)],
135
+ [0, np.sin(x), np.cos(x)]])
136
+
137
+ Ry = np.array([[ np.cos(y), 0, np.sin(y)],
138
+ [ 0, 1, 0],
139
+ [-np.sin(y), 0, np.cos(y)]])
140
+
141
+ Rz = np.array([[np.cos(z), -np.sin(z), 0],
142
+ [np.sin(z), np.cos(z), 0],
143
+ [0,0,1]])
144
+ return Rz@Ry@Rx
145
+ def get_rotation(from_pose, target_pose):
146
+
147
+ rotation1 = rotation_matrix( -from_pose[0], from_pose[1], 0)
148
+ rotation2 = rotation_matrix(-target_pose[0], target_pose[1], 0)
149
+ rotation = rotation2@np.linalg.inv(rotation1)
150
+ return rotation
151
+
152
+ def hR_2_hr(hR):
153
+ hr = np.array([np.arcsin(hR[1, 2]),
154
+ np.arctan2(hR[0, 2], hR[2, 2])])
155
+ return hr
156
+
157
+ def hr_2_hR(hr):
158
+ hR = rotation_matrix( -hr[0], hr[1], 0)
159
+ return hR
160
+
161
+
162
+
163
+ if __name__ == '__main__':
164
+ # hr_norm = np.array([0.15, 0.2])
165
+ # pose = np.array([-0.1, 0.3])
166
+ # rotation1 = rotation_matrix( -hr_norm[0], hr_norm[1], 0)
167
+ # rot = cv2.Rodrigues( np.array([hr_norm[0], hr_norm[1], 0]) )[0]
168
+ def to_hR(hr_norm):
169
+ hR_norm = rotation_matrix( -hr_norm[0], hr_norm[1], 0)
170
+ return hR_norm
171
+
172
+ hr1 = np.array([0.15, 0.2])
173
+ hr2 = np.array([0.10, 0.2])
174
+
175
+ hr_t = np.array([-0.1, 0.3])
176
+
177
+ hR1 = to_hR(hr1)
178
+ hR2 = to_hR(hr2)
179
+ print('hR1: ', hR1)
180
+ print('hR2: ', hR2)
181
+
182
+ R1t = get_rotation(hr1, hr_t)
183
+
184
+ hR1_ = np.dot(R1t, hR1)
185
+
186
+ print('rotated hR_: ', hR1_)
187
+ hr1_ = np.array([np.arcsin(hR1_[1, 2]),
188
+ np.arctan2(hR1_[0, 2], hR1_[2, 2])])
189
+ print('rotated hr1_: ', hr1_)
190
+ print('hR t: ', to_hR(hr_t))
191
+ hR2_ = np.dot(R1t, hR2)
192
+ print('rotated hR2_: ', hR2_)
193
+ # rotation2 = rotation_matrix( -pose[0], pose[1], 0)
194
+
195
+
gazelib/utils/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+
2
+
3
+ from .h5_utils import add, to_h5
4
+
gazelib/utils/color_text.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class ColorText:
2
+ """A simple text processor for printing colored text to the terminal."""
3
+
4
+ colors = {
5
+ 'black': '\033[30m',
6
+ 'red': '\033[31m',
7
+ 'green': '\033[32m',
8
+ 'yellow': '\033[33m',
9
+ 'blue': '\033[34m',
10
+ 'magenta': '\033[35m',
11
+ 'cyan': '\033[36m',
12
+ 'white': '\033[37m',
13
+ 'reset': '\033[0m'
14
+ }
15
+
16
+ @classmethod
17
+ def colorize(cls, text, color):
18
+ """Colorize the given text using the specified color."""
19
+ return f'{cls.colors[color]}{text}{cls.colors["reset"]}'
20
+
21
+ @classmethod
22
+ def black(cls, text):
23
+ """Colorize the given text with black."""
24
+ return cls.colorize(text, 'black')
25
+
26
+ @classmethod
27
+ def red(cls, text):
28
+ """Colorize the given text with red."""
29
+ return cls.colorize(text, 'red')
30
+
31
+ @classmethod
32
+ def green(cls, text):
33
+ """Colorize the given text with green."""
34
+ return cls.colorize(text, 'green')
35
+
36
+ @classmethod
37
+ def yellow(cls, text):
38
+ """Colorize the given text with yellow."""
39
+ return cls.colorize(text, 'yellow')
40
+
41
+ @classmethod
42
+ def blue(cls, text):
43
+ """Colorize the given text with blue."""
44
+ return cls.colorize(text, 'blue')
45
+
46
+ @classmethod
47
+ def magenta(cls, text):
48
+ """Colorize the given text with magenta."""
49
+ return cls.colorize(text, 'magenta')
50
+
51
+ @classmethod
52
+ def cyan(cls, text):
53
+ """Colorize the given text with cyan."""
54
+ return cls.colorize(text, 'cyan')
55
+
56
+ @classmethod
57
+ def white(cls, text):
58
+ """Colorize the given text with white."""
59
+ return cls.colorize(text, 'white')
60
+
61
+ def print_green(*args, **kwargs):
62
+ out = ' '.join([str(arg) for arg in args])
63
+ print(ColorText.green(out))
64
+ def print_yellow(*args, **kwargs):
65
+ out = ' '.join([str(arg) for arg in args])
66
+ print(ColorText.yellow(out))
67
+ def print_magenta(*args, **kwargs):
68
+ out = ' '.join([str(arg) for arg in args])
69
+ print(ColorText.magenta(out))
70
+ def print_cyan(*args, **kwargs):
71
+ out = ' '.join([str(arg) for arg in args])
72
+ print(ColorText.cyan(out))
73
+ def print_red(*args, **kwargs):
74
+ out = ' '.join([str(arg) for arg in args])
75
+ print(ColorText.red(out))
76
+
77
+ if __name__ == '__main__':
78
+ print(ColorText.red('red'))
79
+ print(ColorText.green('green'))
80
+ print(ColorText.yellow('yellow'))
81
+ print(ColorText.blue('blue'))
82
+ print(ColorText.magenta('magenta'))
83
+ print(ColorText.cyan('cyan'))
84
+ print(ColorText.white('white'))
85
+ print(ColorText.black('black'))
gazelib/utils/h5_utils.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import imageio
4
+ import cv2
5
+ import h5py
6
+ import math
7
+
8
+
9
+ def add(to_write, key, value): # noqa
10
+ if key not in to_write:
11
+ to_write[key] = [value]
12
+ else:
13
+ to_write[key].append(value)
14
+
15
+ def to_h5(to_write, output_path):
16
+ for key, values in to_write.items():
17
+ to_write[key] = np.asarray(values)
18
+ # print('%s: ' % key, to_write[key].shape)
19
+
20
+ if not os.path.isfile(output_path):
21
+ with h5py.File(output_path, 'w') as f:
22
+ for key, values in to_write.items():
23
+ print("values.shape: ", values.shape)
24
+ f.create_dataset(
25
+ key, data=values,
26
+ chunks=(
27
+ tuple([1] + list(values.shape[1:]))
28
+ if isinstance(values, np.ndarray)
29
+ else None
30
+ ),
31
+ compression='lzf',
32
+ maxshape=tuple([None] + list(values.shape[1:])),
33
+ )
34
+ print("chunks: ", f[key].chunks)
35
+ else:
36
+ with h5py.File(output_path, 'a') as f:
37
+ for key, values in to_write.items():
38
+ if key not in list(f.keys()):
39
+ print('write it to f {}'.format(output_path))
40
+ f.create_dataset(
41
+ key, data=values,
42
+ chunks=(
43
+ tuple([1] + list(values.shape[1:]))
44
+ if isinstance(values, np.ndarray)
45
+ else None
46
+ ),
47
+ compression='lzf',
48
+ maxshape=tuple([None] + list(values.shape[1:])),
49
+ )
50
+ else:
51
+ data = f[key]
52
+ data.resize(data.shape[0] + values.shape[0], axis=0)
53
+ data[-values.shape[0]:] = values
models/hybrid_tr.py ADDED
@@ -0,0 +1,570 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import torch
4
+ import torch.nn as nn
5
+ import torchvision.models as models
6
+ import numpy as np
7
+ import math
8
+ import copy
9
+ # from modules.resnet_v1 import resnet50
10
+ import torch.utils.model_zoo as model_zoo
11
+
12
+ from torch.utils.model_zoo import load_url as load_state_dict_from_url
13
+
14
+
15
+ __all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101',
16
+ 'resnet152', 'resnext50_32x4d', 'resnext101_32x8d',
17
+ 'wide_resnet50_2', 'wide_resnet101_2']
18
+
19
+
20
+ def _resnet(arch, block, layers, pretrained, progress, **kwargs):
21
+ model = ResFeature(block, layers, **kwargs)
22
+ if pretrained:
23
+ state_dict = load_state_dict_from_url(model_urls[arch],
24
+ progress=progress)
25
+ model.load_state_dict(state_dict, strict=False)
26
+ return model
27
+
28
+
29
+ def resnet18(pretrained=False, progress=True, **kwargs):
30
+ r"""ResNet-18 model from
31
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
32
+
33
+ Args:
34
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
35
+ progress (bool): If True, displays a progress bar of the download to stderr
36
+ """
37
+ return _resnet('resnet18', BasicBlock, [2, 2, 2, 2], pretrained, progress,
38
+ **kwargs)
39
+
40
+
41
+ def resnet34(pretrained=False, progress=True, **kwargs):
42
+ r"""ResNet-34 model from
43
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
44
+
45
+ Args:
46
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
47
+ progress (bool): If True, displays a progress bar of the download to stderr
48
+ """
49
+ return _resnet('resnet34', BasicBlock, [3, 4, 6, 3], pretrained, progress,
50
+ **kwargs)
51
+
52
+
53
+ def resnet50(pretrained=False, progress=True, **kwargs):
54
+ r"""ResNet-50 model from
55
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
56
+
57
+ Args:
58
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
59
+ progress (bool): If True, displays a progress bar of the download to stderr
60
+ """
61
+ return _resnet('resnet50', Bottleneck, [3, 4, 6, 3], pretrained, progress,
62
+ **kwargs)
63
+
64
+
65
+ def resnet101(pretrained=False, progress=True, **kwargs):
66
+ r"""ResNet-101 model from
67
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
68
+
69
+ Args:
70
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
71
+ progress (bool): If True, displays a progress bar of the download to stderr
72
+ """
73
+ return _resnet('resnet101', Bottleneck, [3, 4, 23, 3], pretrained, progress,
74
+ **kwargs)
75
+
76
+
77
+ def resnet152(pretrained=False, progress=True, **kwargs):
78
+ r"""ResNet-152 model from
79
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
80
+
81
+ Args:
82
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
83
+ progress (bool): If True, displays a progress bar of the download to stderr
84
+ """
85
+ return _resnet('resnet152', Bottleneck, [3, 8, 36, 3], pretrained, progress,
86
+ **kwargs)
87
+
88
+
89
+ def resnext50_32x4d(pretrained=False, progress=True, **kwargs):
90
+ r"""ResNeXt-50 32x4d model from
91
+ `"Aggregated Residual Transformation for Deep Neural Networks" <https://arxiv.org/pdf/1611.05431.pdf>`_
92
+
93
+ Args:
94
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
95
+ progress (bool): If True, displays a progress bar of the download to stderr
96
+ """
97
+ kwargs['groups'] = 32
98
+ kwargs['width_per_group'] = 4
99
+ return _resnet('resnext50_32x4d', Bottleneck, [3, 4, 6, 3],
100
+ pretrained, progress, **kwargs)
101
+
102
+
103
+ def resnext101_32x8d(pretrained=False, progress=True, **kwargs):
104
+ r"""ResNeXt-101 32x8d model from
105
+ `"Aggregated Residual Transformation for Deep Neural Networks" <https://arxiv.org/pdf/1611.05431.pdf>`_
106
+
107
+ Args:
108
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
109
+ progress (bool): If True, displays a progress bar of the download to stderr
110
+ """
111
+ kwargs['groups'] = 32
112
+ kwargs['width_per_group'] = 8
113
+ return _resnet('resnext101_32x8d', Bottleneck, [3, 4, 23, 3],
114
+ pretrained, progress, **kwargs)
115
+
116
+
117
+ def wide_resnet50_2(pretrained=False, progress=True, **kwargs):
118
+ r"""Wide ResNet-50-2 model from
119
+ `"Wide Residual Networks" <https://arxiv.org/pdf/1605.07146.pdf>`_
120
+
121
+ The model is the same as ResNet except for the bottleneck number of channels
122
+ which is twice larger in every block. The number of channels in outer 1x1
123
+ convolutions is the same, e.g. last block in ResNet-50 has 2048-512-2048
124
+ channels, and in Wide ResNet-50-2 has 2048-1024-2048.
125
+
126
+ Args:
127
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
128
+ progress (bool): If True, displays a progress bar of the download to stderr
129
+ """
130
+ kwargs['width_per_group'] = 64 * 2
131
+ return _resnet('wide_resnet50_2', Bottleneck, [3, 4, 6, 3],
132
+ pretrained, progress, **kwargs)
133
+
134
+
135
+ def wide_resnet101_2(pretrained=False, progress=True, **kwargs):
136
+ r"""Wide ResNet-101-2 model from
137
+ `"Wide Residual Networks" <https://arxiv.org/pdf/1605.07146.pdf>`_
138
+
139
+ The model is the same as ResNet except for the bottleneck number of channels
140
+ which is twice larger in every block. The number of channels in outer 1x1
141
+ convolutions is the same, e.g. last block in ResNet-50 has 2048-512-2048
142
+ channels, and in Wide ResNet-50-2 has 2048-1024-2048.
143
+
144
+ Args:
145
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
146
+ progress (bool): If True, displays a progress bar of the download to stderr
147
+ """
148
+ kwargs['width_per_group'] = 64 * 2
149
+ return _resnet('wide_resnet101_2', Bottleneck, [3, 4, 23, 3],
150
+ pretrained, progress, **kwargs)
151
+
152
+
153
+ model_urls = {
154
+ 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
155
+ 'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
156
+ 'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
157
+ 'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
158
+ 'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',
159
+ 'resnext50_32x4d': 'https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pth',
160
+ 'resnext101_32x8d': 'https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pth',
161
+ 'wide_resnet50_2': 'https://download.pytorch.org/models/wide_resnet50_2-95faca4d.pth',
162
+ 'wide_resnet101_2': 'https://download.pytorch.org/models/wide_resnet101_2-32ee1156.pth',
163
+ }
164
+
165
+
166
+ def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
167
+ """3x3 convolution with padding"""
168
+ return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
169
+ padding=dilation, groups=groups, bias=False, dilation=dilation)
170
+
171
+
172
+ def conv1x1(in_planes, out_planes, stride=1):
173
+ """1x1 convolution"""
174
+ return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)
175
+
176
+
177
+ class BasicBlock(nn.Module):
178
+ expansion = 1
179
+
180
+ def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
181
+ base_width=64, dilation=1, norm_layer=None):
182
+ super(BasicBlock, self).__init__()
183
+ if norm_layer is None:
184
+ norm_layer = nn.BatchNorm2d
185
+ if groups != 1 or base_width != 64:
186
+ raise ValueError('BasicBlock only supports groups=1 and base_width=64')
187
+ if dilation > 1:
188
+ raise NotImplementedError("Dilation > 1 not supported in BasicBlock")
189
+
190
+ # Both self.conv1 and self.downsample layers downsample the input when stride != 1
191
+ self.conv1 = conv3x3(inplanes, planes, stride)
192
+ self.bn1 = norm_layer(planes)
193
+ self.relu = nn.ReLU(inplace=True)
194
+ self.conv2 = conv3x3(planes, planes)
195
+ self.bn2 = norm_layer(planes)
196
+ self.downsample = downsample
197
+ self.stride = stride
198
+
199
+ def forward(self, x):
200
+ identity = x
201
+
202
+ out = self.conv1(x)
203
+ out = self.bn1(out)
204
+ out = self.relu(out)
205
+
206
+ out = self.conv2(out)
207
+ out = self.bn2(out)
208
+
209
+ if self.downsample is not None:
210
+ identity = self.downsample(x)
211
+
212
+ out += identity
213
+ out = self.relu(out)
214
+
215
+ return out
216
+
217
+
218
+ class Bottleneck(nn.Module):
219
+ expansion = 4
220
+
221
+ def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
222
+ base_width=64, dilation=1, norm_layer=None):
223
+ super(Bottleneck, self).__init__()
224
+ if norm_layer is None:
225
+ norm_layer = nn.BatchNorm2d
226
+ width = int(planes * (base_width / 64.)) * groups
227
+ # Both self.conv2 and self.downsample layers downsample the input when stride != 1
228
+ self.conv1 = conv1x1(inplanes, width)
229
+ self.bn1 = norm_layer(width)
230
+ self.conv2 = conv3x3(width, width, stride, groups, dilation)
231
+ self.bn2 = norm_layer(width)
232
+ self.conv3 = conv1x1(width, planes * self.expansion)
233
+ self.bn3 = norm_layer(planes * self.expansion)
234
+ self.relu = nn.ReLU(inplace=True)
235
+ self.downsample = downsample
236
+ self.stride = stride
237
+
238
+ def forward(self, x):
239
+ identity = x
240
+
241
+ out = self.conv1(x)
242
+ out = self.bn1(out)
243
+ out = self.relu(out)
244
+
245
+ out = self.conv2(out)
246
+ out = self.bn2(out)
247
+ out = self.relu(out)
248
+
249
+ out = self.conv3(out)
250
+ out = self.bn3(out)
251
+
252
+ if self.downsample is not None:
253
+ identity = self.downsample(x)
254
+
255
+ out += identity
256
+ out = self.relu(out)
257
+
258
+ return out
259
+
260
+ class ResFeature(nn.Module):
261
+
262
+ def __init__(self, block, layers, num_classes=1000, zero_init_residual=False,
263
+ groups=1, width_per_group=64, replace_stride_with_dilation=None,
264
+ norm_layer=None):
265
+ super(ResFeature, self).__init__()
266
+ if norm_layer is None:
267
+ norm_layer = nn.BatchNorm2d
268
+ self._norm_layer = norm_layer
269
+
270
+ self.inplanes = 64
271
+ self.dilation = 1
272
+ if replace_stride_with_dilation is None:
273
+ # each element in the tuple indicates if we should replace
274
+ # the 2x2 stride with a dilated convolution instead
275
+ replace_stride_with_dilation = [False, False, False]
276
+ if len(replace_stride_with_dilation) != 3:
277
+ raise ValueError("replace_stride_with_dilation should be None "
278
+ "or a 3-element tuple, got {}".format(replace_stride_with_dilation))
279
+ self.groups = groups
280
+ self.base_width = width_per_group
281
+ self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3,
282
+ bias=False)
283
+ self.bn1 = norm_layer(self.inplanes)
284
+ self.relu = nn.ReLU(inplace=True)
285
+ self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
286
+ self.layer1 = self._make_layer(block, 64, layers[0])
287
+ self.layer2 = self._make_layer(block, 128, layers[1], stride=2,
288
+ dilate=replace_stride_with_dilation[0])
289
+ self.layer3 = self._make_layer(block, 256, layers[2], stride=2,
290
+ dilate=replace_stride_with_dilation[1])
291
+ self.layer4 = self._make_layer(block, 512, layers[3], stride=2,
292
+ dilate=replace_stride_with_dilation[2])
293
+
294
+ for m in self.modules():
295
+ if isinstance(m, nn.Conv2d):
296
+ nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
297
+ elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
298
+ nn.init.constant_(m.weight, 1)
299
+ nn.init.constant_(m.bias, 0)
300
+
301
+ # Zero-initialize the last BN in each residual branch,
302
+ # so that the residual branch starts with zeros, and each residual block behaves like an identity.
303
+ # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677
304
+ if zero_init_residual:
305
+ for m in self.modules():
306
+ if isinstance(m, Bottleneck):
307
+ nn.init.constant_(m.bn3.weight, 0)
308
+ elif isinstance(m, BasicBlock):
309
+ nn.init.constant_(m.bn2.weight, 0)
310
+
311
+ def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
312
+ norm_layer = self._norm_layer
313
+ downsample = None
314
+ previous_dilation = self.dilation
315
+ if dilate:
316
+ self.dilation *= stride
317
+ stride = 1
318
+ if stride != 1 or self.inplanes != planes * block.expansion:
319
+ downsample = nn.Sequential(
320
+ conv1x1(self.inplanes, planes * block.expansion, stride),
321
+ norm_layer(planes * block.expansion),
322
+ )
323
+
324
+ layers = []
325
+ layers.append(block(self.inplanes, planes, stride, downsample, self.groups,
326
+ self.base_width, previous_dilation, norm_layer))
327
+ self.inplanes = planes * block.expansion
328
+ for _ in range(1, blocks):
329
+ layers.append(block(self.inplanes, planes, groups=self.groups,
330
+ base_width=self.base_width, dilation=self.dilation,
331
+ norm_layer=norm_layer))
332
+
333
+ return nn.Sequential(*layers)
334
+
335
+ def forward(self, x):
336
+ x = self.conv1(x)
337
+ x = self.bn1(x)
338
+ x = self.relu(x)
339
+ x = self.maxpool(x)
340
+
341
+ x = self.layer1(x)
342
+ x = self.layer2(x)
343
+ x = self.layer3(x)
344
+ x = self.layer4(x)
345
+ return x
346
+
347
+
348
+ class ResGazeEs(nn.Module):
349
+ def __init__(self, ):
350
+ super(ResGazeEs, self).__init__()
351
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
352
+ self.fc = nn.Linear(2048, 2)
353
+
354
+ for m in self.modules():
355
+ if isinstance(m, nn.Conv2d):
356
+ nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
357
+ elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
358
+ nn.init.constant_(m.weight, 1)
359
+ nn.init.constant_(m.bias, 0)
360
+
361
+ def forward(self, x):
362
+ x = self.avgpool(x)
363
+ x = x.view(x.size(0), -1)
364
+ x = self.fc(x)
365
+ return x
366
+
367
+ class CNN_Model(nn.Module):
368
+ def __init__(self):
369
+ super(CNN_Model, self).__init__()
370
+ self.feature = resnet50(pretrained=True)
371
+ # self.feature.load_state_dict(torch.load(pretrained_url), strict=False )
372
+ self.gazeEs = ResGazeEs()
373
+ # self.gazeEs.load_state_dict(torch.load(pretrained_url), strict=False )
374
+
375
+ def forward(self, x_in):
376
+ features = self.feature(x_in)
377
+ gaze = self.gazeEs(features)
378
+
379
+ return gaze, features
380
+
381
+
382
+
383
+
384
+ class TransformerEncoder(nn.Module):
385
+
386
+ def __init__(self, encoder_layer, num_layers, norm=None):
387
+ super().__init__()
388
+
389
+ self.layers = nn.ModuleList([copy.deepcopy(encoder_layer) for i in range(num_layers)])
390
+ self.num_layers = num_layers
391
+ self.norm = norm
392
+
393
+ def forward(self, src, pos):
394
+ output = src
395
+ for layer in self.layers:
396
+ output = layer(output, pos)
397
+
398
+ if self.norm is not None:
399
+ output = self.norm(output)
400
+
401
+ return output
402
+
403
+
404
+ class TransformerEncoderLayer(nn.Module):
405
+
406
+ def __init__(self, d_model, nhead, dim_feedforward=512, dropout=0.1):
407
+ super().__init__()
408
+ self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)
409
+ # Implementation of Feedforward model
410
+ self.linear1 = nn.Linear(d_model, dim_feedforward)
411
+ self.dropout = nn.Dropout(dropout)
412
+ self.linear2 = nn.Linear(dim_feedforward, d_model)
413
+
414
+ self.norm1 = nn.LayerNorm(d_model)
415
+ self.norm2 = nn.LayerNorm(d_model)
416
+
417
+ self.dropout1 = nn.Dropout(dropout)
418
+ self.dropout2 = nn.Dropout(dropout)
419
+
420
+ self.activation = nn.ReLU(inplace=True)
421
+
422
+ def pos_embed(self, src, pos):
423
+ batch_pos = pos.unsqueeze(1).repeat(1, src.size(1), 1)
424
+ return src + batch_pos
425
+
426
+
427
+ def forward(self, src, pos):
428
+ # src_mask: Optional[Tensor] = None,
429
+ # src_key_padding_mask: Optional[Tensor] = None):
430
+ # pos: Optional[Tensor] = None):
431
+
432
+ q = k = self.pos_embed(src, pos)
433
+ src2 = self.self_attn(q, k, value=src)[0]
434
+ src = src + self.dropout1(src2)
435
+ src = self.norm1(src)
436
+
437
+ src2 = self.linear2(self.dropout(self.activation(self.linear1(src))))
438
+ src = src + self.dropout2(src2)
439
+ src = self.norm2(src)
440
+ return src
441
+
442
+ class FeatureTransformer(nn.Module):
443
+ '''
444
+ This is the end head which is included in the resnet18 (in official code)
445
+ To avoid ambiguity, extract this part out of resnet18
446
+ '''
447
+ def __init__(self, in_channels=512, maps=32):
448
+ super(FeatureTransformer, self).__init__()
449
+ self.conv = nn.Sequential(
450
+ nn.Conv2d(in_channels, maps, 1),
451
+ nn.BatchNorm2d(maps),
452
+ nn.ReLU(inplace=True)
453
+ )
454
+ def forward(self, x):
455
+ x = self.conv(x)
456
+ return x
457
+
458
+ class HybridTR18(nn.Module):
459
+ def __init__(self):
460
+ super().__init__()
461
+ maps = 32
462
+ nhead = 8
463
+ dim_feature = 7*7
464
+ dim_feedforward=512
465
+ dropout = 0.1
466
+ num_layers=6
467
+
468
+ self.base_model = resnet18(pretrained=True) #False, maps=maps)
469
+ self.base_model_head = FeatureTransformer(in_channels=dim_feedforward, maps=maps)
470
+
471
+ # d_model: dim of Q, K, V
472
+ # nhead: seq num
473
+ # dim_feedforward: dim of hidden linear layers
474
+ # dropout: prob
475
+
476
+ encoder_layer = TransformerEncoderLayer(
477
+ maps,
478
+ nhead,
479
+ dim_feedforward,
480
+ dropout)
481
+
482
+ encoder_norm = nn.LayerNorm(maps)
483
+ # num_encoder_layer: deeps of layers
484
+ self.encoder = TransformerEncoder(encoder_layer, num_layers, encoder_norm)
485
+ self.cls_token = nn.Parameter(torch.randn(1, 1, maps))
486
+ self.pos_embedding = nn.Embedding(dim_feature+1, maps)
487
+ self.feed = nn.Linear(maps, 2)
488
+
489
+
490
+ def forward(self, x_in, normalize_z=False):
491
+ output_dict = {}
492
+ # feature = self.base_model(x_in["face"])
493
+ feature = self.base_model(x_in)
494
+ feature = self.base_model_head(feature)
495
+ batch_size = feature.size(0)
496
+ feature = feature.flatten(2)
497
+ feature = feature.permute(2, 0, 1)
498
+ cls = self.cls_token.repeat( (1, batch_size, 1))
499
+ feature = torch.cat([cls, feature], 0)
500
+ position = torch.from_numpy(np.arange(0, 50)).cuda()
501
+
502
+ pos_feature = self.pos_embedding(position)
503
+ # feature is [HW, batch, channel]
504
+ feature = self.encoder(feature, pos_feature)
505
+
506
+ feature = feature.permute(1, 2, 0)
507
+ feature = feature[:,:,0]
508
+ pred_gaze = self.feed(feature)
509
+ output_dict['pred_gaze'] = pred_gaze
510
+ return output_dict
511
+
512
+
513
+
514
+ class HybridTR50(nn.Module):
515
+ def __init__(self):
516
+ super().__init__()
517
+ maps = 32
518
+ nhead = 8
519
+ dim_feature = 7*7
520
+ dim_feedforward=2048
521
+ dropout = 0.1
522
+ num_layers=6
523
+
524
+ self.base_model = resnet50(pretrained=True) #False, maps=maps)
525
+ self.base_model_head = FeatureTransformer(in_channels=dim_feedforward,maps=maps)
526
+
527
+ # d_model: dim of Q, K, V
528
+ # nhead: seq num
529
+ # dim_feedforward: dim of hidden linear layers
530
+ # dropout: prob
531
+
532
+ encoder_layer = TransformerEncoderLayer(
533
+ maps,
534
+ nhead,
535
+ dim_feedforward,
536
+ dropout)
537
+
538
+ encoder_norm = nn.LayerNorm(maps)
539
+ # num_encoder_layer: deeps of layers
540
+
541
+ self.encoder = TransformerEncoder(encoder_layer, num_layers, encoder_norm)
542
+ self.cls_token = nn.Parameter(torch.randn(1, 1, maps))
543
+ self.pos_embedding = nn.Embedding(dim_feature+1, maps)
544
+
545
+ self.feed = nn.Linear(maps, 2)
546
+
547
+
548
+
549
+
550
+ def forward(self, x_in, normalize_z=False):
551
+ output_dict = {}
552
+ feature = self.base_model(x_in) ##(batch, 2048, 7, 7)
553
+ feature = self.base_model_head(feature) ## (batch, 32, 7, 7)
554
+ batch_size = feature.size(0) ## batch size
555
+ feature = feature.flatten(2) ## (batch, 32, 49)
556
+ feature = feature.permute(2, 0, 1) ## (49, batch, 32)
557
+ cls = self.cls_token.repeat( (1, batch_size, 1)) ## (1, batch, 32)
558
+ feature = torch.cat([cls, feature], 0) ## (50, batch, 32)
559
+ position = torch.from_numpy(np.arange(0, 50)).cuda() ## (50,)
560
+ pos_feature = self.pos_embedding(position) ## (50, 32)
561
+ # feature is [HW, batch, channel]
562
+ feature = self.encoder(feature, pos_feature) ## (50, batch, 32)
563
+ feature = feature.permute(1, 2, 0) ## (batch, 32, 50)
564
+ feature = feature[:,:,0] ## (batch, 32)
565
+ pred_gaze = self.feed(feature) ## (batch, 2)
566
+ output_dict['pred_gaze'] = pred_gaze
567
+ return output_dict
568
+
569
+
570
+
models/resnet.py ADDED
@@ -0,0 +1,366 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from torch.utils.model_zoo import load_url as load_state_dict_from_url
4
+ import torch.nn.functional as F
5
+
6
+
7
+ model_urls = {
8
+ 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
9
+ 'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
10
+ 'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
11
+ 'resnet152': 'https://download.pytorch.org/models/resnet152-394f9c45.pth'
12
+ }
13
+
14
+
15
+ def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
16
+ """3x3 convolution with padding"""
17
+ return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
18
+ padding=dilation, groups=groups, bias=False, dilation=dilation)
19
+
20
+
21
+ def conv1x1(in_planes, out_planes, stride=1):
22
+ """1x1 convolution"""
23
+ return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)
24
+
25
+
26
+ class BasicBlock(nn.Module):
27
+ expansion = 1
28
+
29
+ def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
30
+ base_width=64, dilation=1, norm_layer=None):
31
+ super(BasicBlock, self).__init__()
32
+ if norm_layer is None:
33
+ norm_layer = nn.BatchNorm2d
34
+ if groups != 1 or base_width != 64:
35
+ raise ValueError('BasicBlock only supports groups=1 and base_width=64')
36
+ if dilation > 1:
37
+ raise NotImplementedError("Dilation > 1 not supported in BasicBlock")
38
+ # Both self.conv1 and self.downsample layers downsample the input when stride != 1
39
+ self.conv1 = conv3x3(inplanes, planes, stride)
40
+ self.bn1 = norm_layer(planes)
41
+ self.relu = nn.ReLU(inplace=True)
42
+ self.conv2 = conv3x3(planes, planes)
43
+ self.bn2 = norm_layer(planes)
44
+ self.downsample = downsample
45
+ self.stride = stride
46
+
47
+ def forward(self, x):
48
+ identity = x
49
+
50
+ out = self.conv1(x)
51
+ out = self.bn1(out)
52
+ out = self.relu(out)
53
+
54
+ out = self.conv2(out)
55
+ out = self.bn2(out)
56
+
57
+ if self.downsample is not None:
58
+ identity = self.downsample(x)
59
+
60
+ out += identity
61
+ out = self.relu(out)
62
+
63
+ return out
64
+
65
+
66
+ class Bottleneck(nn.Module):
67
+ expansion = 4
68
+
69
+ def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
70
+ base_width=64, dilation=1, norm_layer=None):
71
+ super(Bottleneck, self).__init__()
72
+ if norm_layer is None:
73
+ norm_layer = nn.BatchNorm2d
74
+ width = int(planes * (base_width / 64.)) * groups
75
+ # Both self.conv2 and self.downsample layers downsample the input when stride != 1
76
+ self.conv1 = conv1x1(inplanes, width)
77
+ self.bn1 = norm_layer(width)
78
+ self.conv2 = conv3x3(width, width, stride, groups, dilation)
79
+ self.bn2 = norm_layer(width)
80
+ self.conv3 = conv1x1(width, planes * self.expansion)
81
+ self.bn3 = norm_layer(planes * self.expansion)
82
+ self.relu = nn.ReLU(inplace=True)
83
+ self.downsample = downsample
84
+ self.stride = stride
85
+
86
+ def forward(self, x):
87
+ identity = x
88
+
89
+ out = self.conv1(x)
90
+ out = self.bn1(out)
91
+ out = self.relu(out)
92
+
93
+ out = self.conv2(out)
94
+ out = self.bn2(out)
95
+ out = self.relu(out)
96
+
97
+ out = self.conv3(out)
98
+ out = self.bn3(out)
99
+
100
+ if self.downsample is not None:
101
+ identity = self.downsample(x)
102
+
103
+ out += identity
104
+ out = self.relu(out)
105
+
106
+ return out
107
+
108
+ class DeconvBasicBlock(nn.Module):
109
+ def __init__(self, in_planes, stride=1, norm_layer=None):
110
+ super(DeconvBasicBlock, self).__init__()
111
+
112
+ if norm_layer is None:
113
+ norm_layer = nn.BatchNorm2d
114
+ planes = int(in_planes/stride)
115
+
116
+ self.conv2 = nn.Conv2d(in_planes, in_planes, kernel_size=3, stride=1, padding=1, bias=False)
117
+ self.bn2 = norm_layer(in_planes)
118
+
119
+ self.bn1 = norm_layer(planes)
120
+
121
+ if stride == 1:
122
+ self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
123
+ self.bn1 = norm_layer(planes)
124
+ self.shortcut = nn.Sequential()
125
+ else:
126
+ self.conv1 = nn.ConvTranspose2d(in_planes, planes, kernel_size=3, stride=stride, bias=False, padding=1, output_padding=1)
127
+ self.bn1 = norm_layer(planes)
128
+ self.shortcut = nn.Sequential(
129
+ nn.ConvTranspose2d(in_planes, planes, kernel_size=3, stride=stride, bias=False, padding=1, output_padding=1),
130
+ norm_layer(planes)
131
+ )
132
+
133
+ def forward(self, x):
134
+ out = torch.relu(self.bn2(self.conv2(x)))
135
+ out = self.bn1(self.conv1(out))
136
+ out += self.shortcut(x)
137
+ out = torch.relu(out)
138
+ return out
139
+
140
+ class DeconvBottleneck(nn.Module):
141
+ def __init__(self, in_channels, out_channels, expansion=2, stride=1, upsample=None, norm_layer=None):
142
+ super(DeconvBottleneck, self).__init__()
143
+ if norm_layer is None:
144
+ norm_layer = nn.BatchNorm2d
145
+ self.expansion = expansion
146
+ self.conv1 = nn.Conv2d(in_channels, out_channels,
147
+ kernel_size=1, bias=False)
148
+ self.bn1 = norm_layer(out_channels)
149
+ if stride == 1:
150
+ self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3,
151
+ stride=stride, bias=False, padding=1)
152
+ else:
153
+ self.conv2 = nn.ConvTranspose2d(out_channels, out_channels,
154
+ kernel_size=3,
155
+ stride=stride, bias=False,
156
+ padding=1,
157
+ output_padding=1)
158
+ self.bn2 = norm_layer(out_channels)
159
+ self.conv3 = nn.Conv2d(out_channels, out_channels * self.expansion,
160
+ kernel_size=1, bias=False)
161
+ self.bn3 = norm_layer(out_channels * self.expansion)
162
+ self.relu = nn.ReLU()
163
+ self.upsample = upsample
164
+
165
+ def forward(self, x):
166
+ shortcut = x
167
+
168
+ out = self.conv1(x)
169
+ out = self.bn1(out)
170
+ out = self.relu(out)
171
+
172
+ out = self.conv2(out)
173
+ out = self.bn2(out)
174
+ out = self.relu(out)
175
+
176
+ out = self.conv3(out)
177
+ out = self.bn3(out)
178
+ out = self.relu(out)
179
+
180
+ if self.upsample is not None:
181
+ shortcut = self.upsample(x)
182
+
183
+ out += shortcut
184
+ out = self.relu(out)
185
+
186
+ return out
187
+
188
+
189
+ class ResNet(nn.Module):
190
+
191
+ def __init__(self, block, layers, num_classes=1000, zero_init_residual=False,
192
+ groups=1, width_per_group=64, replace_stride_with_dilation=None,
193
+ norm_layer=None):
194
+ super(ResNet, self).__init__()
195
+ if norm_layer is None:
196
+ norm_layer = nn.BatchNorm2d
197
+ self._norm_layer = norm_layer
198
+
199
+ self.inplanes = 64
200
+ self.dilation = 1
201
+ if replace_stride_with_dilation is None:
202
+ # each element in the tuple indicates if we should replace
203
+ # the 2x2 stride with a dilated convolution instead
204
+ replace_stride_with_dilation = [False, False, False]
205
+ if len(replace_stride_with_dilation) != 3:
206
+ raise ValueError("replace_stride_with_dilation should be None "
207
+ "or a 3-element tuple, got {}".format(replace_stride_with_dilation))
208
+ self.groups = groups
209
+ self.base_width = width_per_group
210
+ self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3,
211
+ bias=False)
212
+ self.bn1 = norm_layer(self.inplanes)
213
+ self.relu = nn.ReLU(inplace=True)
214
+ self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
215
+ self.layer1 = self._make_layer(block, 64, layers[0])
216
+ self.layer2 = self._make_layer(block, 128, layers[1], stride=2,
217
+ dilate=replace_stride_with_dilation[0])
218
+ self.layer3 = self._make_layer(block, 256, layers[2], stride=2,
219
+ dilate=replace_stride_with_dilation[1])
220
+ self.layer4 = self._make_layer(block, 512, layers[3], stride=2,
221
+ dilate=replace_stride_with_dilation[2])
222
+
223
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
224
+ self.fc = nn.Linear(512 * block.expansion, num_classes)
225
+
226
+ for m in self.modules():
227
+ if isinstance(m, nn.Conv2d):
228
+ nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
229
+ elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
230
+ nn.init.constant_(m.weight, 1)
231
+ nn.init.constant_(m.bias, 0)
232
+
233
+ # Zero-initialize the last BN in each residual branch,
234
+ # so that the residual branch starts with zeros, and each residual block behaves like an identity.
235
+ # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677
236
+ if zero_init_residual:
237
+ for m in self.modules():
238
+ if isinstance(m, Bottleneck):
239
+ nn.init.constant_(m.bn3.weight, 0)
240
+ elif isinstance(m, BasicBlock):
241
+ nn.init.constant_(m.bn2.weight, 0)
242
+
243
+ def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
244
+ norm_layer = self._norm_layer
245
+ downsample = None
246
+ previous_dilation = self.dilation
247
+ if dilate:
248
+ self.dilation *= stride
249
+ stride = 1
250
+ if stride != 1 or self.inplanes != planes * block.expansion:
251
+ downsample = nn.Sequential(
252
+ conv1x1(self.inplanes, planes * block.expansion, stride),
253
+ norm_layer(planes * block.expansion),
254
+ )
255
+
256
+ layers = []
257
+ layers.append(block(self.inplanes, planes, stride, downsample, self.groups,
258
+ self.base_width, previous_dilation, norm_layer))
259
+ self.inplanes = planes * block.expansion
260
+ for _ in range(1, blocks):
261
+ layers.append(block(self.inplanes, planes, groups=self.groups,
262
+ base_width=self.base_width, dilation=self.dilation,
263
+ norm_layer=norm_layer))
264
+
265
+ return nn.Sequential(*layers)
266
+
267
+ def forward(self, x):
268
+ x = self.conv1(x)
269
+ x = self.bn1(x)
270
+ x = self.relu(x)
271
+ x = self.maxpool(x)
272
+
273
+ x = self.layer1(x)
274
+ x = self.layer2(x)
275
+ x = self.layer3(x)
276
+ x = self.layer4(x)
277
+
278
+ return x
279
+
280
+
281
+ def _resnet(arch, block, layers, pretrained, progress, **kwargs):
282
+ model = ResNet(block, layers, **kwargs)
283
+ if pretrained:
284
+ state_dict = load_state_dict_from_url(model_urls[arch],
285
+ progress=progress)
286
+
287
+ model.load_state_dict(state_dict)
288
+ return model
289
+
290
+ def resnet18(pretrained=False, progress=True, **kwargs):
291
+ r"""ResNet-18 model from
292
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
293
+ Args:
294
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
295
+ progress (bool): If True, displays a progress bar of the download to stderr
296
+ """
297
+ return _resnet('resnet18', BasicBlock, [2, 2, 2, 2], pretrained, progress,
298
+ **kwargs)
299
+
300
+ def resnet34(pretrained=False, progress=True, **kwargs):
301
+ r"""ResNet-34 model from
302
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
303
+ Args:
304
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
305
+ progress (bool): If True, displays a progress bar of the download to stderr
306
+ """
307
+ return _resnet('resnet34', BasicBlock, [3, 4, 6, 3], pretrained, progress,
308
+ **kwargs)
309
+
310
+ def resnet50(pretrained=False, progress=True, **kwargs):
311
+ r"""ResNet-50 model from
312
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
313
+ Args:
314
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
315
+ progress (bool): If True, displays a progress bar of the download to stderr
316
+ """
317
+ return _resnet('resnet50', Bottleneck, [3, 4, 6, 3], pretrained, progress,
318
+ **kwargs)
319
+
320
+ def resnet152(pretrained=False, progress=True, **kwargs):
321
+ r"""ResNet-152 model from
322
+ `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>'_
323
+ Args:
324
+ pretrained (bool): If True, returns a model pre-trained on ImageNet
325
+ progress (bool): If True, displays a progress bar of the download to stderr
326
+ """
327
+ return _resnet('resnet152', Bottleneck, [3, 8, 36, 3], pretrained, progress,
328
+ **kwargs)
329
+
330
+
331
+ class ResNetGaze(nn.Module):
332
+ def __init__(self):
333
+ raise NotImplementedError
334
+
335
+ def forward(self, x_in):
336
+ output_dict = {}
337
+ features = self.feature(x_in)
338
+ z = self.avgpool(features)
339
+ z = z.view(z.size(0), -1) ## (batch, dim)
340
+ pred_gaze = self.fc(z)
341
+ output_dict['pred_gaze'] = pred_gaze
342
+ return output_dict
343
+
344
+ class Res18(ResNetGaze, nn.Module):
345
+ def __init__(self, resnet_pretrained=True):
346
+ nn.Module.__init__(self)
347
+ self.feature = resnet18(pretrained=resnet_pretrained)
348
+ self.avgpool = nn.AdaptiveAvgPool2d((1,1))
349
+
350
+ self.fc = nn.Linear(512, 2)
351
+
352
+
353
+ class Res50(ResNetGaze, nn.Module):
354
+ def __init__(self, resnet_pretrained=True):
355
+ nn.Module.__init__(self)
356
+ self.feature = resnet50(pretrained=resnet_pretrained)
357
+ self.avgpool = nn.AdaptiveAvgPool2d((1,1))
358
+ self.fc = nn.Linear(2048, 2)
359
+
360
+
361
+ class Res152(ResNetGaze, nn.Module):
362
+ def __init__(self, resnet_pretrained=True):
363
+ nn.Module.__init__(self)
364
+ self.feature = resnet152(pretrained=resnet_pretrained)
365
+ self.avgpool = nn.AdaptiveAvgPool2d((1,1))
366
+ self.fc = nn.Linear(2048, 2)
models/vit/mae.py ADDED
@@ -0,0 +1,429 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+
4
+ # This source code is licensed under the license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+ # --------------------------------------------------------
7
+ # References:
8
+ # timm: https://github.com/rwightman/pytorch-image-models/tree/master/timm
9
+ # DeiT: https://github.com/facebookresearch/deit
10
+ # --------------------------------------------------------
11
+
12
+ from functools import partial
13
+
14
+ import torch
15
+ import torch.nn as nn
16
+
17
+ from timm.models.vision_transformer import PatchEmbed, Block
18
+
19
+ # from util.pos_embed import get_2d_sincos_pos_embed
20
+
21
+
22
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
23
+ # All rights reserved.
24
+
25
+ # This source code is licensed under the license found in the
26
+ # LICENSE file in the root directory of this source tree.
27
+ # --------------------------------------------------------
28
+ # Position embedding utils
29
+ # --------------------------------------------------------
30
+
31
+ import numpy as np
32
+
33
+ import torch
34
+
35
+ # --------------------------------------------------------
36
+ # 2D sine-cosine position embedding
37
+ # References:
38
+ # Transformer: https://github.com/tensorflow/models/blob/master/official/nlp/transformer/model_utils.py
39
+ # MoCo v3: https://github.com/facebookresearch/moco-v3
40
+ # --------------------------------------------------------
41
+ def get_2d_sincos_pos_embed(embed_dim, grid_size, cls_token=False):
42
+ """
43
+ grid_size: int of the grid height and width
44
+ return:
45
+ pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)
46
+ """
47
+ grid_h = np.arange(grid_size, dtype=np.float32)
48
+ grid_w = np.arange(grid_size, dtype=np.float32)
49
+ grid = np.meshgrid(grid_w, grid_h) # here w goes first
50
+ grid = np.stack(grid, axis=0)
51
+
52
+ grid = grid.reshape([2, 1, grid_size, grid_size])
53
+ pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid)
54
+ if cls_token:
55
+ pos_embed = np.concatenate([np.zeros([1, embed_dim]), pos_embed], axis=0)
56
+ return pos_embed
57
+
58
+
59
+ def get_2d_sincos_pos_embed_from_grid(embed_dim, grid):
60
+ assert embed_dim % 2 == 0
61
+
62
+ # use half of dimensions to encode grid_h
63
+ emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2)
64
+ emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2)
65
+
66
+ emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D)
67
+ return emb
68
+
69
+
70
+ def get_1d_sincos_pos_embed_from_grid(embed_dim, pos):
71
+ """
72
+ embed_dim: output dimension for each position
73
+ pos: a list of positions to be encoded: size (M,)
74
+ out: (M, D)
75
+ """
76
+ assert embed_dim % 2 == 0
77
+ omega = np.arange(embed_dim // 2, dtype=float)
78
+ omega /= embed_dim / 2.
79
+ omega = 1. / 10000**omega # (D/2,)
80
+
81
+ pos = pos.reshape(-1) # (M,)
82
+ out = np.einsum('m,d->md', pos, omega) # (M, D/2), outer product
83
+
84
+ emb_sin = np.sin(out) # (M, D/2)
85
+ emb_cos = np.cos(out) # (M, D/2)
86
+
87
+ emb = np.concatenate([emb_sin, emb_cos], axis=1) # (M, D)
88
+ return emb
89
+
90
+
91
+
92
+ # --------------------------------------------------------
93
+ # Interpolate position embeddings for high-resolution
94
+ # References:
95
+ # DeiT: https://github.com/facebookresearch/deit
96
+ # --------------------------------------------------------
97
+ def interpolate_pos_embed(model, checkpoint_model):
98
+ if 'pos_embed' in checkpoint_model:
99
+ pos_embed_checkpoint = checkpoint_model['pos_embed']
100
+ embedding_size = pos_embed_checkpoint.shape[-1]
101
+ num_patches = model.patch_embed.num_patches
102
+ num_extra_tokens = model.pos_embed.shape[-2] - num_patches
103
+ # height (== width) for the checkpoint position embedding
104
+ orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)
105
+ # height (== width) for the new position embedding
106
+ new_size = int(num_patches ** 0.5)
107
+ # class_token and dist_token are kept unchanged
108
+ if orig_size != new_size:
109
+ print("Position interpolate from %dx%d to %dx%d" % (orig_size, orig_size, new_size, new_size))
110
+ extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]
111
+ # only the position tokens are interpolated
112
+ pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]
113
+ pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)
114
+ pos_tokens = torch.nn.functional.interpolate(
115
+ pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)
116
+ pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)
117
+ new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)
118
+ checkpoint_model['pos_embed'] = new_pos_embed
119
+
120
+
121
+ class MaskedAutoencoderViT(nn.Module):
122
+ """ Masked Autoencoder with VisionTransformer backbone
123
+ """
124
+ def __init__(self, img_size=224, patch_size=16, in_chans=3,
125
+ embed_dim=1024, depth=24, num_heads=16,
126
+ decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,
127
+ mlp_ratio=4., norm_layer=nn.LayerNorm, norm_pix_loss=False):
128
+ super().__init__()
129
+
130
+ # --------------------------------------------------------------------------
131
+ # MAE encoder specifics
132
+ self.patch_embed = PatchEmbed(img_size, patch_size, in_chans, embed_dim)
133
+ num_patches = self.patch_embed.num_patches
134
+
135
+ self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))
136
+ self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim), requires_grad=False) # fixed sin-cos embedding
137
+
138
+ self.blocks = nn.ModuleList([
139
+ # Block(embed_dim, num_heads, mlp_ratio, qkv_bias=True, qk_scale=None, norm_layer=norm_layer)
140
+ Block(embed_dim, num_heads, mlp_ratio, qkv_bias=True, norm_layer=norm_layer)
141
+ for i in range(depth)])
142
+ self.norm = norm_layer(embed_dim)
143
+ # --------------------------------------------------------------------------
144
+
145
+ # --------------------------------------------------------------------------
146
+ # MAE decoder specifics
147
+ self.decoder_embed = nn.Linear(embed_dim, decoder_embed_dim, bias=True)
148
+
149
+ self.mask_token = nn.Parameter(torch.zeros(1, 1, decoder_embed_dim))
150
+
151
+ self.decoder_pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, decoder_embed_dim), requires_grad=False) # fixed sin-cos embedding
152
+
153
+ self.decoder_blocks = nn.ModuleList([
154
+ # Block(decoder_embed_dim, decoder_num_heads, mlp_ratio, qkv_bias=True, qk_scale=None, norm_layer=norm_layer)
155
+ Block(decoder_embed_dim, decoder_num_heads, mlp_ratio, qkv_bias=True, norm_layer=norm_layer)
156
+ for i in range(decoder_depth)])
157
+
158
+ self.decoder_norm = norm_layer(decoder_embed_dim)
159
+ self.decoder_pred = nn.Linear(decoder_embed_dim, patch_size**2 * in_chans, bias=True) # decoder to patch
160
+ # --------------------------------------------------------------------------
161
+
162
+ self.norm_pix_loss = norm_pix_loss
163
+
164
+ self.initialize_weights()
165
+
166
+ def initialize_weights(self):
167
+ # initialization
168
+ # initialize (and freeze) pos_embed by sin-cos embedding
169
+ pos_embed = get_2d_sincos_pos_embed(self.pos_embed.shape[-1], int(self.patch_embed.num_patches**.5), cls_token=True)
170
+ self.pos_embed.data.copy_(torch.from_numpy(pos_embed).float().unsqueeze(0))
171
+
172
+ decoder_pos_embed = get_2d_sincos_pos_embed(self.decoder_pos_embed.shape[-1], int(self.patch_embed.num_patches**.5), cls_token=True)
173
+ self.decoder_pos_embed.data.copy_(torch.from_numpy(decoder_pos_embed).float().unsqueeze(0))
174
+
175
+ # initialize patch_embed like nn.Linear (instead of nn.Conv2d)
176
+ w = self.patch_embed.proj.weight.data
177
+ torch.nn.init.xavier_uniform_(w.view([w.shape[0], -1]))
178
+
179
+ # timm's trunc_normal_(std=.02) is effectively normal_(std=0.02) as cutoff is too big (2.)
180
+ torch.nn.init.normal_(self.cls_token, std=.02)
181
+ torch.nn.init.normal_(self.mask_token, std=.02)
182
+
183
+ # initialize nn.Linear and nn.LayerNorm
184
+ self.apply(self._init_weights)
185
+
186
+ def _init_weights(self, m):
187
+ if isinstance(m, nn.Linear):
188
+ # we use xavier_uniform following official JAX ViT:
189
+ torch.nn.init.xavier_uniform_(m.weight)
190
+ if isinstance(m, nn.Linear) and m.bias is not None:
191
+ nn.init.constant_(m.bias, 0)
192
+ elif isinstance(m, nn.LayerNorm):
193
+ nn.init.constant_(m.bias, 0)
194
+ nn.init.constant_(m.weight, 1.0)
195
+
196
+ def patchify(self, imgs):
197
+ """
198
+ imgs: (N, 3, H, W)
199
+ x: (N, L, patch_size**2 *3)
200
+ """
201
+ p = self.patch_embed.patch_size[0]
202
+ assert imgs.shape[2] == imgs.shape[3] and imgs.shape[2] % p == 0
203
+
204
+ h = w = imgs.shape[2] // p
205
+ x = imgs.reshape(shape=(imgs.shape[0], 3, h, p, w, p))
206
+ x = torch.einsum('nchpwq->nhwpqc', x)
207
+ x = x.reshape(shape=(imgs.shape[0], h * w, p**2 * 3))
208
+ return x
209
+
210
+ def unpatchify(self, x):
211
+ """
212
+ x: (N, L, patch_size**2 *3)
213
+ imgs: (N, 3, H, W)
214
+ """
215
+ p = self.patch_embed.patch_size[0]
216
+ h = w = int(x.shape[1]**.5)
217
+ assert h * w == x.shape[1]
218
+
219
+ x = x.reshape(shape=(x.shape[0], h, w, p, p, 3))
220
+ x = torch.einsum('nhwpqc->nchpwq', x)
221
+ imgs = x.reshape(shape=(x.shape[0], 3, h * p, h * p))
222
+ return imgs
223
+
224
+ def random_masking(self, x, mask_ratio):
225
+ """
226
+ Perform per-sample random masking by per-sample shuffling.
227
+ Per-sample shuffling is done by argsort random noise.
228
+ x: [N, L, D], sequence
229
+ """
230
+ N, L, D = x.shape # batch, length, dim
231
+ len_keep = int(L * (1 - mask_ratio))
232
+
233
+ noise = torch.rand(N, L, device=x.device) # noise in [0, 1]
234
+
235
+ # sort noise for each sample
236
+ ids_shuffle = torch.argsort(noise, dim=1) # ascend: small is keep, large is remove
237
+ ids_restore = torch.argsort(ids_shuffle, dim=1)
238
+
239
+ # keep the first subset
240
+ ids_keep = ids_shuffle[:, :len_keep]
241
+ x_masked = torch.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))
242
+
243
+ # generate the binary mask: 0 is keep, 1 is remove
244
+ mask = torch.ones([N, L], device=x.device)
245
+ mask[:, :len_keep] = 0
246
+ # unshuffle to get the binary mask
247
+ mask = torch.gather(mask, dim=1, index=ids_restore)
248
+
249
+ return x_masked, mask, ids_restore
250
+
251
+ def forward_encoder(self, x, mask_ratio):
252
+ # embed patches
253
+ x = self.patch_embed(x)
254
+
255
+ # add pos embed w/o cls token
256
+ x = x + self.pos_embed[:, 1:, :]
257
+
258
+ # masking: length -> length * mask_ratio
259
+ x, mask, ids_restore = self.random_masking(x, mask_ratio)
260
+
261
+ # append cls token
262
+ cls_token = self.cls_token + self.pos_embed[:, :1, :]
263
+ cls_tokens = cls_token.expand(x.shape[0], -1, -1)
264
+ x = torch.cat((cls_tokens, x), dim=1)
265
+
266
+ # apply Transformer blocks
267
+ for blk in self.blocks:
268
+ x = blk(x)
269
+ x = self.norm(x)
270
+
271
+ return x, mask, ids_restore
272
+
273
+ def forward_decoder(self, x, ids_restore):
274
+ # embed tokens
275
+ x = self.decoder_embed(x)
276
+
277
+ # append mask tokens to sequence
278
+ mask_tokens = self.mask_token.repeat(x.shape[0], ids_restore.shape[1] + 1 - x.shape[1], 1)
279
+ x_ = torch.cat([x[:, 1:, :], mask_tokens], dim=1) # no cls token
280
+ x_ = torch.gather(x_, dim=1, index=ids_restore.unsqueeze(-1).repeat(1, 1, x.shape[2])) # unshuffle
281
+ x = torch.cat([x[:, :1, :], x_], dim=1) # append cls token
282
+
283
+ # add pos embed
284
+ x = x + self.decoder_pos_embed
285
+
286
+ # apply Transformer blocks
287
+ for blk in self.decoder_blocks:
288
+ x = blk(x)
289
+ x = self.decoder_norm(x)
290
+
291
+ # predictor projection
292
+ x = self.decoder_pred(x)
293
+
294
+ # remove cls token
295
+ x = x[:, 1:, :]
296
+
297
+ return x
298
+
299
+ def forward_loss(self, imgs, pred, mask):
300
+ """
301
+ imgs: [N, 3, H, W]
302
+ pred: [N, L, p*p*3]
303
+ mask: [N, L], 0 is keep, 1 is remove,
304
+ """
305
+ target = self.patchify(imgs)
306
+ if self.norm_pix_loss:
307
+ mean = target.mean(dim=-1, keepdim=True)
308
+ var = target.var(dim=-1, keepdim=True)
309
+ target = (target - mean) / (var + 1.e-6)**.5
310
+
311
+ loss = (pred - target) ** 2
312
+ loss = loss.mean(dim=-1) # [N, L], mean loss per patch
313
+
314
+ loss = (loss * mask).sum() / mask.sum() # mean loss on removed patches
315
+ return loss
316
+
317
+ def forward(self, imgs, mask_ratio=0.75):
318
+ latent, mask, ids_restore = self.forward_encoder(imgs, mask_ratio)
319
+ pred = self.forward_decoder(latent, ids_restore) # [N, L, p*p*3]
320
+ loss = self.forward_loss(imgs, pred, mask)
321
+ return loss, pred, mask
322
+
323
+
324
+ def mae_vit_base_patch16_dec512d8b(**kwargs):
325
+ model = MaskedAutoencoderViT(
326
+ patch_size=16, embed_dim=768, depth=12, num_heads=12,
327
+ decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,
328
+ mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)
329
+ return model
330
+
331
+
332
+ def mae_vit_large_patch16_dec512d8b(**kwargs):
333
+ model = MaskedAutoencoderViT(
334
+ patch_size=16, embed_dim=1024, depth=24, num_heads=16,
335
+ decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,
336
+ mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)
337
+ return model
338
+
339
+
340
+ def mae_vit_huge_patch14_dec512d8b(**kwargs):
341
+ model = MaskedAutoencoderViT(
342
+ patch_size=14, embed_dim=1280, depth=32, num_heads=16,
343
+ decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,
344
+ mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)
345
+ return model
346
+
347
+
348
+ # set recommended archs
349
+ mae_vit_base_patch16 = mae_vit_base_patch16_dec512d8b # decoder: 512 dim, 8 blocks
350
+ mae_vit_large_patch16 = mae_vit_large_patch16_dec512d8b # decoder: 512 dim, 8 blocks
351
+ mae_vit_huge_patch14 = mae_vit_huge_patch14_dec512d8b # decoder: 512 dim, 8 blocks
352
+
353
+
354
+
355
+
356
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
357
+ # All rights reserved.
358
+
359
+ # This source code is licensed under the license found in the
360
+ # LICENSE file in the root directory of this source tree.
361
+ # --------------------------------------------------------
362
+ # References:
363
+ # timm: https://github.com/rwightman/pytorch-image-models/tree/master/timm
364
+ # DeiT: https://github.com/facebookresearch/deit
365
+ # --------------------------------------------------------
366
+
367
+ from functools import partial
368
+
369
+ import torch
370
+ import torch.nn as nn
371
+
372
+ import timm.models.vision_transformer
373
+
374
+
375
+ class VisionTransformer(timm.models.vision_transformer.VisionTransformer):
376
+ """ Vision Transformer with support for global average pooling
377
+ """
378
+ def __init__(self, global_pool=False, **kwargs):
379
+ super(VisionTransformer, self).__init__(**kwargs)
380
+
381
+ self.global_pool = global_pool
382
+ if self.global_pool:
383
+ norm_layer = kwargs['norm_layer']
384
+ embed_dim = kwargs['embed_dim']
385
+ self.fc_norm = norm_layer(embed_dim)
386
+
387
+ del self.norm # remove the original norm
388
+
389
+ def forward_features(self, x):
390
+ B = x.shape[0]
391
+ x = self.patch_embed(x)
392
+
393
+ cls_tokens = self.cls_token.expand(B, -1, -1) # stole cls_tokens impl from Phil Wang, thanks
394
+ x = torch.cat((cls_tokens, x), dim=1)
395
+ x = x + self.pos_embed
396
+ x = self.pos_drop(x)
397
+
398
+ for blk in self.blocks:
399
+ x = blk(x)
400
+
401
+ if self.global_pool:
402
+ x = x[:, 1:, :].mean(dim=1) # global pool without cls token
403
+ outcome = self.fc_norm(x)
404
+ else:
405
+ x = self.norm(x)
406
+ outcome = x[:, 0]
407
+
408
+ return outcome
409
+
410
+
411
+ def vit_base_patch16(**kwargs):
412
+ model = VisionTransformer(
413
+ patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,
414
+ norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)
415
+ return model
416
+
417
+
418
+ def vit_large_patch16(**kwargs):
419
+ model = VisionTransformer(
420
+ patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,
421
+ norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)
422
+ return model
423
+
424
+
425
+ def vit_huge_patch14(**kwargs):
426
+ model = VisionTransformer(
427
+ patch_size=14, embed_dim=1280, depth=32, num_heads=16, mlp_ratio=4, qkv_bias=True,
428
+ norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)
429
+ return model
models/vit/mae_gaze.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from os import replace
3
+ import torch
4
+ import torch.nn as nn
5
+ import torch.nn.functional as F
6
+ from torch.optim.lr_scheduler import StepLR
7
+ import torch.utils.model_zoo as model_zoo
8
+ from torch.utils.model_zoo import load_url as load_state_dict_from_url
9
+
10
+ from functools import partial
11
+ from torchvision.models import vit_b_16, vit_b_32, vit_l_16, vit_l_32
12
+
13
+ from models.vit.mae import interpolate_pos_embed, MaskedAutoencoderViT, vit_base_patch16, vit_large_patch16, vit_huge_patch14
14
+
15
+
16
+
17
+
18
+ class MAE_Gaze(nn.Module):
19
+
20
+ def __init__(self, model_type='vit_b_16', global_pool=False, drop_path_rate=0.1,
21
+ custom_pretrained_path=None):
22
+
23
+ super().__init__()
24
+ if model_type == "vit_b_16":
25
+ self.vit = vit_base_patch16( global_pool=global_pool, drop_path_rate=drop_path_rate)
26
+ elif model_type == "vit_l_16":
27
+ self.vit = vit_large_patch16( global_pool=global_pool, drop_path_rate=drop_path_rate)
28
+ elif model_type == "vit_h_14":
29
+ self.vit = vit_huge_patch14( global_pool=global_pool, drop_path_rate=drop_path_rate)
30
+ else:
31
+ raise ValueError('model_type not supported')
32
+
33
+ if custom_pretrained_path is not None:
34
+ checkpoint_model = torch.load(custom_pretrained_path, map_location='cpu')['model']
35
+ state_dict = self.vit.state_dict()
36
+ for k in ['head.weight', 'head.bias']:
37
+ if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:
38
+ print(f"Removing key {k} from pretrained checkpoint")
39
+ del checkpoint_model[k]
40
+
41
+
42
+
43
+ # interpolate position embedding
44
+ interpolate_pos_embed(self.vit, checkpoint_model)
45
+
46
+ # keys_in_ckpt = checkpoint_model.keys()
47
+ # print('Keys in ckpt: ', keys_in_ckpt)
48
+ self.vit.load_state_dict( checkpoint_model, strict=False)
49
+ print('Loaded custom pretrained weights from {}'.format(custom_pretrained_path))
50
+
51
+ # del self.decoder_embed
52
+ # del self.mask_token
53
+ # del self.decoder_pos_embed
54
+ # del self.decoder_blocks
55
+ # del self.decoder_norm
56
+ # del self.decoder_pred
57
+
58
+ embed_dim = self.vit.embed_dim
59
+ self.gaze_fc = nn.Linear(embed_dim, 2)
60
+
61
+
62
+ def forward(self, input):
63
+ features = self.vit.forward_features(input)
64
+
65
+ pred_gaze = self.gaze_fc(features)
66
+ output_dict = {}
67
+ output_dict['pred_gaze'] = pred_gaze
68
+ return output_dict
69
+
models/vit/vit_gaze.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from os import replace
3
+ import torch
4
+ import torch.nn as nn
5
+ import torch.nn.functional as F
6
+ from torch.optim.lr_scheduler import StepLR
7
+ import torch.utils.model_zoo as model_zoo
8
+ from torch.utils.model_zoo import load_url as load_state_dict_from_url
9
+ from functools import partial
10
+ from torchvision.models import vit_b_16, vit_b_32, vit_l_16, vit_l_32
11
+
12
+
13
+
14
+ class ViTGaze(nn.Module):
15
+ def __init__(self,
16
+ vit_type="b_16",
17
+ pretrained=True,
18
+ custom_pretrained_path=None,
19
+ **kwargs
20
+ ):
21
+ super().__init__()
22
+ if vit_type == "b_16":
23
+ """
24
+ patch_size=16,
25
+ num_layers=12,
26
+ num_heads=12,
27
+ hidden_dim=768,
28
+ mlp_dim=3072,
29
+ """
30
+ self.vit = vit_b_16(pretrained=pretrained )
31
+
32
+
33
+ self.vit.heads = nn.Sequential(
34
+ nn.Linear(768,2)
35
+ )
36
+ elif vit_type == "b_32":
37
+ self.vit = vit_b_32(pretrained=pretrained)
38
+ self.vit.heads = nn.Sequential(
39
+ nn.Linear(768,2)
40
+ )
41
+ elif vit_type == "l_16":
42
+ self.vit = vit_l_16(pretrained=pretrained)
43
+ self.vit.heads = nn.Sequential(
44
+ nn.Linear(1024,2)
45
+ )
46
+ elif vit_type == "l_32":
47
+ self.vit = vit_l_32(pretrained=pretrained)
48
+ self.vit.heads = nn.Sequential(
49
+ nn.Linear(1024,2)
50
+ )
51
+ if custom_pretrained_path is not None:
52
+ ckpt = torch.load(custom_pretrained_path)
53
+ print('Loading custom pretrained weights from: ', custom_pretrained_path)
54
+ # self.vit.load_state_dict( ckpt['model'], strict=True)
55
+ keys_in_ckpt = ckpt.keys()
56
+ print('Keys in ckpt: ', keys_in_ckpt)
57
+ self.vit.load_state_dict( ckpt, strict=True)
58
+
59
+ def forward(self, x_in):
60
+ out_dict = {}
61
+ gaze = self.vit(x_in)
62
+ out_dict['pred_gaze'] = gaze
63
+ return out_dict
64
+
65
+
66
+
67
+ from models.vit.mae import interpolate_pos_embed, vit_huge_patch14
68
+ class CustomViT_H14(nn.Module):
69
+ def __init__(self, global_pool=False, drop_path_rate=0.1,
70
+ custom_pretrained_path=None):
71
+ super().__init__()
72
+ self.vit = vit_huge_patch14( global_pool=global_pool, drop_path_rate=drop_path_rate)
73
+
74
+ if custom_pretrained_path is not None:
75
+ checkpoint_model = torch.load(custom_pretrained_path, map_location='cpu')
76
+
77
+ state_dict = self.vit.state_dict()
78
+ for k in ['head.weight', 'head.bias']:
79
+ if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:
80
+ print(f"Removing key {k} from pretrained checkpoint")
81
+ del checkpoint_model[k]
82
+
83
+ # interpolate position embedding
84
+ interpolate_pos_embed(self.vit, checkpoint_model)
85
+
86
+ self.vit.load_state_dict( checkpoint_model, strict=False )
87
+ print('Loaded custom pretrained weights from {}'.format(custom_pretrained_path))
88
+
89
+ embed_dim = self.vit.embed_dim
90
+ self.gaze_fc = nn.Linear(embed_dim, 2)
91
+
92
+
93
+ def forward(self, input):
94
+ features = self.vit.forward_features(input)
95
+
96
+ pred_gaze = self.gaze_fc(features)
97
+ output_dict = {}
98
+ output_dict['pred_gaze'] = pred_gaze
99
+ return output_dict
100
+
101
+
102
+
103
+
unigaze/__init__.py ADDED
File without changes
unigaze/configs/config.yaml ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defaults:
2
+ - _self_
3
+ - exp: exp_224
4
+
5
+
6
+
7
+ mode: train
8
+ random_seed: 42
9
+ num_workers: 20
10
+
11
+
12
+ test_per_epoch: 1
13
+ print_freq: 100
14
+ data_sanity_check: false
15
+ log_wandb: false
16
+ output_dir: "./logs"
17
+ ckpt_resume: null
18
+ pretrain_ckptpath: null
19
+
20
+
21
+ optimizer_cfg: null
22
+ scheduler_cfg: null
23
+
24
+ batch_size: 50
25
+ test_batch_size: 200
26
+
27
+ epochs: 25
28
+ valid_epoch: 1
29
+ eval_epoch: 10
30
+ save_epoch: 10
31
+
32
+
33
+ use_autocast: False
34
+
35
+ batchnorm_type:
36
+ label: clean
37
+ unlabel: aug
38
+ test: clean
unigaze/configs/data/eyediap_cs.yaml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.eyediap.EYEDIAPDataset
2
+ params:
3
+ data_name: eyediap_cs
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ keys_to_use:
9
+ - 'person_1.h5'
10
+ - 'person_2.h5'
11
+ - 'person_3.h5'
12
+ - 'person_4.h5'
13
+ - 'person_5.h5'
14
+ - 'person_6.h5'
15
+ - 'person_7.h5'
16
+ - 'person_8.h5'
17
+ - 'person_9.h5'
18
+ - 'person_10.h5'
19
+ - 'person_11.h5'
20
+ - 'person_14.h5'
21
+ - 'person_15.h5'
22
+ - 'person_16.h5'
unigaze/configs/data/eyediap_cs_test.yaml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.eyediap.EYEDIAPDataset
2
+ params:
3
+ data_name: eyediap_cs
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ keys_to_use:
9
+ # - 'person_1.h5'
10
+ # - 'person_2.h5'
11
+ # - 'person_3.h5'
12
+ # - 'person_4.h5'
13
+ # - 'person_5.h5'
14
+ # - 'person_6.h5'
15
+ # - 'person_7.h5'
16
+ # - 'person_8.h5'
17
+ - 'person_9.h5'
18
+ - 'person_10.h5'
19
+ - 'person_11.h5'
20
+ - 'person_14.h5'
21
+ - 'person_15.h5'
22
+ - 'person_16.h5'
unigaze/configs/data/eyediap_cs_train.yaml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.eyediap.EYEDIAPDataset
2
+ params:
3
+ data_name: eyediap_cs
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ keys_to_use:
9
+ - 'person_1.h5'
10
+ - 'person_2.h5'
11
+ - 'person_3.h5'
12
+ - 'person_4.h5'
13
+ - 'person_5.h5'
14
+ - 'person_6.h5'
15
+ - 'person_7.h5'
16
+ - 'person_8.h5'
17
+ # - 'person_9.h5'
18
+ # - 'person_10.h5'
19
+ # - 'person_11.h5'
20
+ # - 'person_14.h5'
21
+ # - 'person_15.h5'
22
+ # - 'person_16.h5'
unigaze/configs/data/eyediap_ft.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.eyediap.EYEDIAPDataset
2
+ params:
3
+ data_name: eyediap_ft
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ keys_to_use:
9
+ - 'person_1.h5'
10
+ - 'person_2.h5'
11
+ - 'person_3.h5'
12
+ - 'person_4.h5'
13
+ - 'person_5.h5'
14
+ - 'person_6.h5'
15
+ - 'person_7.h5'
16
+ - 'person_8.h5'
17
+ - 'person_9.h5'
18
+ - 'person_10.h5'
19
+ - 'person_11.h5'
20
+ - 'person_12.h5'
21
+ - 'person_13.h5'
22
+ - 'person_14.h5'
23
+ - 'person_15.h5'
24
+ - 'person_16.h5'
unigaze/configs/data/eyediap_ft_test.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.eyediap.EYEDIAPDataset
2
+ params:
3
+ data_name: eyediap_ft
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ keys_to_use:
9
+ # - 'person_1.h5'
10
+ # - 'person_2.h5'
11
+ # - 'person_3.h5'
12
+ # - 'person_4.h5'
13
+ # - 'person_5.h5'
14
+ # - 'person_6.h5'
15
+ # - 'person_7.h5'
16
+ # - 'person_8.h5'
17
+ - 'person_9.h5'
18
+ - 'person_10.h5'
19
+ - 'person_11.h5'
20
+ - 'person_12.h5'
21
+ - 'person_13.h5'
22
+ - 'person_14.h5'
23
+ - 'person_15.h5'
24
+ - 'person_16.h5'
unigaze/configs/data/eyediap_ft_train.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.eyediap.EYEDIAPDataset
2
+ params:
3
+ data_name: eyediap_ft
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ keys_to_use:
9
+ - 'person_1.h5'
10
+ - 'person_2.h5'
11
+ - 'person_3.h5'
12
+ - 'person_4.h5'
13
+ - 'person_5.h5'
14
+ - 'person_6.h5'
15
+ - 'person_7.h5'
16
+ - 'person_8.h5'
17
+ # - 'person_9.h5'
18
+ # - 'person_10.h5'
19
+ # - 'person_11.h5'
20
+ # - 'person_12.h5'
21
+ # - 'person_13.h5'
22
+ # - 'person_14.h5'
23
+ # - 'person_15.h5'
24
+ # - 'person_16.h5'
unigaze/configs/data/gaze360_test.yaml ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+
4
+ type: datasets.gaze360.Gaze360Dataset
5
+ params:
6
+ data_name: gaze360_224_test
7
+ saved_norm_config:
8
+ focal_norm: 960
9
+ distance_norm: 600
10
+ roi_size: [224, 224]
11
+ norm_config:
12
+ focal_norm: 960
13
+ distance_norm: 600
14
+ roi_size: [224, 224]
15
+
16
+ color_type: bgr
17
+ transform_type: 'basic_imagenet'
18
+ dataset_path: null
19
+ image_size: 224
20
+ sample_rate_use: 1
21
+ whether_crop_resize: False
22
+ keys_to_use:
23
+ - 000000.h5
24
+ - 000001.h5
25
+ - 000002.h5
26
+ - 000003.h5
27
+ - 000004.h5
28
+ - 000010.h5
29
+ - 000014.h5
30
+ - 000022.h5
31
+ - 000031.h5
32
+ - 000032.h5
33
+ - 000044.h5
34
+ - 000045.h5
35
+ - 000057.h5
36
+ - 000058.h5
37
+ - 000070.h5
38
+ - 000078.h5
39
+ - 000270.h5
40
+ - 000277.h5
41
+ - 000278.h5
42
+ - 000279.h5
43
+ - 000316.h5
44
+ - 000364.h5
45
+ - 000367.h5
46
+ - 000511.h5
47
+ - 000512.h5
48
+ - 000513.h5
49
+ - 000515.h5
50
+ - 000527.h5
51
+ - 000536.h5
52
+ - 000543.h5
53
+ - 000579.h5
54
+ - 000584.h5
55
+ - 000585.h5
56
+ - 000600.h5
57
+ - 000603.h5
58
+ - 000604.h5
59
+ - 000611.h5
60
+ - 000614.h5
61
+ - 000615.h5
62
+ - 000616.h5
63
+ - 000649.h5
64
+ - 000650.h5
65
+ - 000651.h5
66
+ - 000652.h5
67
+ - 000687.h5
68
+ - 000723.h5
69
+ - 000777.h5
70
+ - 000782.h5
71
+ - 000823.h5
72
+ - 000907.h5
73
+ - 000909.h5
74
+ - 000982.h5
unigaze/configs/data/gaze360_train.yaml ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+
4
+ type: datasets.gaze360.Gaze360Dataset
5
+ params:
6
+ data_name: gaze360_224_train
7
+ saved_norm_config:
8
+ focal_norm: 960
9
+ distance_norm: 600
10
+ roi_size: [224, 224]
11
+ norm_config:
12
+ focal_norm: 960
13
+ distance_norm: 600
14
+ roi_size: [224, 224]
15
+
16
+ color_type: bgr
17
+ transform_type: 'basic_imagenet'
18
+ dataset_path: null
19
+ image_size: 224
20
+ sample_rate_use: 1
21
+
22
+ keys_to_use:
23
+ - 000000.h5
24
+ - 000001.h5
25
+ - 000002.h5
26
+ - 000003.h5
27
+ - 000004.h5
28
+ - 000006.h5
29
+ - 000007.h5
30
+ - 000009.h5
31
+ - 000010.h5
32
+ - 000011.h5
33
+ - 000013.h5
34
+ - 000016.h5
35
+ - 000019.h5
36
+ - 000020.h5
37
+ - 000029.h5
38
+ - 000030.h5
39
+ - 000031.h5
40
+ - 000032.h5
41
+ - 000034.h5
42
+ - 000035.h5
43
+ - 000038.h5
44
+ - 000039.h5
45
+ - 000043.h5
46
+ - 000048.h5
47
+ - 000049.h5
48
+ - 000050.h5
49
+ - 000058.h5
50
+ - 000060.h5
51
+ - 000061.h5
52
+ - 000062.h5
53
+ - 000063.h5
54
+ - 000072.h5
55
+ - 000073.h5
56
+ - 000074.h5
57
+ - 000075.h5
58
+ - 000076.h5
59
+ - 000077.h5
60
+ - 000081.h5
61
+ - 000083.h5
62
+ - 000084.h5
63
+ - 000085.h5
64
+ - 000090.h5
65
+ - 000093.h5
66
+ - 000094.h5
67
+ - 000099.h5
68
+ - 000109.h5
69
+ - 000111.h5
70
+ - 000112.h5
71
+ - 000116.h5
72
+ - 000122.h5
73
+ - 000134.h5
74
+ - 000146.h5
75
+ - 000148.h5
76
+ - 000149.h5
77
+ - 000150.h5
78
+ - 000151.h5
79
+ - 000152.h5
80
+ - 000154.h5
81
+ - 000156.h5
82
+ - 000158.h5
83
+ - 000159.h5
84
+ - 000160.h5
85
+ - 000161.h5
86
+ - 000162.h5
87
+ - 000165.h5
88
+ - 000166.h5
89
+ - 000170.h5
90
+ - 000171.h5
91
+ - 000172.h5
92
+ - 000184.h5
93
+ - 000185.h5
94
+ - 000186.h5
95
+ - 000187.h5
96
+ - 000188.h5
97
+ - 000189.h5
98
+ - 000190.h5
99
+ - 000202.h5
100
+ - 000205.h5
101
+ - 000206.h5
102
+ - 000208.h5
103
+ - 000214.h5
104
+ - 000216.h5
105
+ - 000217.h5
106
+ - 000219.h5
107
+ - 000220.h5
108
+ - 000221.h5
109
+ - 000222.h5
110
+ - 000228.h5
111
+ - 000237.h5
112
+ - 000248.h5
113
+ - 000250.h5
114
+ - 000255.h5
115
+ - 000256.h5
116
+ - 000257.h5
117
+ - 000258.h5
118
+ - 000262.h5
119
+ - 000278.h5
120
+ - 000283.h5
121
+ - 000284.h5
122
+ - 000287.h5
123
+ - 000288.h5
124
+ - 000297.h5
125
+ - 000298.h5
126
+ - 000299.h5
127
+ - 000300.h5
128
+ - 000324.h5
129
+ - 000368.h5
130
+ - 000369.h5
131
+ - 000408.h5
132
+ - 000409.h5
133
+ - 000410.h5
134
+ - 000418.h5
135
+ - 000440.h5
136
+ - 000441.h5
137
+ - 000449.h5
138
+ - 000457.h5
139
+ - 000458.h5
140
+ - 000459.h5
141
+ - 000460.h5
142
+ - 000461.h5
143
+ - 000463.h5
144
+ - 000494.h5
145
+ - 000501.h5
146
+ - 000502.h5
147
+ - 000509.h5
148
+ - 000510.h5
149
+ - 000511.h5
150
+ - 000512.h5
151
+ - 000513.h5
152
+ - 000514.h5
153
+ - 000515.h5
154
+ - 000517.h5
155
+ - 000519.h5
156
+ - 000529.h5
157
+ - 000541.h5
158
+ - 000547.h5
159
+ - 000548.h5
160
+ - 000549.h5
161
+ - 000550.h5
162
+ - 000551.h5
163
+ - 000552.h5
164
+ - 000565.h5
165
+ - 000566.h5
166
+ - 000569.h5
167
+ - 000571.h5
168
+ - 000573.h5
169
+ - 000574.h5
170
+ - 000586.h5
171
+ - 000587.h5
172
+ - 000588.h5
173
+ - 000589.h5
174
+ - 000592.h5
175
+ - 000597.h5
176
+ - 000603.h5
177
+ - 000604.h5
178
+ - 000605.h5
179
+ - 000611.h5
180
+ - 000613.h5
181
+ - 000617.h5
182
+ - 000620.h5
183
+ - 000623.h5
184
+ - 000634.h5
185
+ - 000635.h5
186
+ - 000636.h5
187
+ - 000639.h5
188
+ - 000640.h5
189
+ - 000641.h5
190
+ - 000642.h5
191
+ - 000643.h5
192
+ - 000644.h5
193
+ - 000645.h5
194
+ - 000650.h5
195
+ - 000656.h5
196
+ - 000658.h5
197
+ - 000659.h5
198
+ - 000660.h5
199
+ - 000661.h5
200
+ - 000662.h5
201
+ - 000670.h5
202
+ - 000671.h5
203
+ - 000677.h5
204
+ - 000683.h5
205
+ - 000714.h5
206
+ - 000721.h5
207
+ - 000723.h5
208
+ - 000738.h5
209
+ - 000741.h5
210
+ - 000742.h5
211
+ - 000744.h5
212
+ - 000751.h5
213
+ - 000755.h5
214
+ - 000761.h5
215
+ - 000762.h5
216
+ - 000763.h5
217
+ - 000764.h5
218
+ - 000765.h5
219
+ - 000768.h5
220
+ - 000777.h5
221
+ - 000779.h5
222
+ - 000780.h5
223
+ - 000781.h5
224
+ - 000783.h5
225
+ - 000786.h5
226
+ - 000787.h5
227
+ - 000789.h5
228
+ - 000800.h5
229
+ - 000801.h5
230
+ - 000802.h5
231
+ - 000803.h5
232
+ - 000813.h5
233
+ - 000815.h5
234
+ - 000816.h5
235
+ - 000831.h5
236
+ - 000834.h5
237
+ - 000835.h5
238
+ - 000838.h5
239
+ - 000861.h5
240
+ - 000862.h5
241
+ - 000899.h5
242
+ - 000900.h5
243
+ - 000916.h5
244
+ - 000918.h5
245
+ - 000923.h5
246
+ - 000935.h5
247
+ - 000946.h5
248
+ - 000971.h5
249
+ - 000978.h5
250
+ - 000990.h5
251
+ - 000991.h5
252
+ - 001092.h5
unigaze/configs/data/gazecapture_test.yaml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.gazecapture.GazeCaptureDataset
2
+ params:
3
+ data_name: gazecapture_test
4
+ color_type: rgb
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ keys_to_use: [ "00010.h5", "00110.h5", "00126.h5", "00178.h5", "00190.h5", "00192.h5", "00220.h5", "00222.h5", "00233.h5", "00319.h5", "00330.h5", "00343.h5", "00382.h5", "00460.h5", "00509.h5", "00511.h5", "00546.h5", "00563.h5", "00580.h5", "00585.h5",
9
+ "00611.h5", "00616.h5", "00619.h5", "00646.h5", "00654.h5", "00680.h5", "00686.h5", "00700.h5", "00721.h5", "00741.h5", "00777.h5", "00796.h5", "00868.h5", "00921.h5", "00935.h5", "00949.h5", "00953.h5",
10
+ "00965.h5", "00968.h5", "01036.h5", "01041.h5", "01051.h5", "01091.h5", "01148.h5", "01152.h5", "01155.h5", "01183.h5", "01200.h5", "01273.h5", "01278.h5", "01286.h5", "01326.h5", "01329.h5", "01370.h5", "01376.h5", "01425.h5", "01457.h5", "01477.h5",
11
+ "01506.h5", "01517.h5", "01525.h5", "01575.h5", "01625.h5", "01672.h5", "01674.h5", "01689.h5", "01782.h5", "01794.h5", "01813.h5", "01830.h5", "01855.h5", "01863.h5", "01877.h5", "01893.h5", "01941.h5", "01959.h5", "01978.h5",
12
+ "01983.h5", "01985.h5", "01997.h5", "02006.h5", "02020.h5", "02043.h5", "02078.h5", "02091.h5", "02109.h5", "02197.h5", "02213.h5", "02239.h5", "02240.h5", "02269.h5", "02275.h5", "02281.h5", "02292.h5",
13
+ "02301.h5", "02348.h5", "02413.h5", "02419.h5", "02450.h5", "02455.h5", "02461.h5", "02480.h5", "02536.h5", "02601.h5", "02734.h5", "02755.h5", "02756.h5", "02805.h5", "02833.h5", "02851.h5", "02885.h5", "02899.h5", "02942.h5", "02966.h5",
14
+ "02986.h5", "03011.h5", "03024.h5", "03043.h5", "03117.h5", "03126.h5", "03140.h5", "03177.h5", "03183.h5", "03185.h5", "03202.h5", "03216.h5", "03223.h5", "03247.h5", "03270.h5", "03324.h5", "03326.h5", "03344.h5", "03352.h5", "03361.h5", "03366.h5",
15
+ "03404.h5", "03412.h5", "03451.h5", "03523.h5"]
unigaze/configs/data/gazecapture_test_ds15.yaml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.gazecapture.GazeCaptureDataset
2
+ params:
3
+ data_name: gazecapture_test
4
+ color_type: rgb
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ sample_rate_use: 15
8
+ dataset_path: null
9
+ keys_to_use: [ "00010.h5", "00110.h5", "00126.h5", "00178.h5", "00190.h5", "00192.h5", "00220.h5", "00222.h5", "00233.h5", "00319.h5", "00330.h5", "00343.h5", "00382.h5", "00460.h5", "00509.h5", "00511.h5", "00546.h5", "00563.h5", "00580.h5", "00585.h5",
10
+ "00611.h5", "00616.h5", "00619.h5", "00646.h5", "00654.h5", "00680.h5", "00686.h5", "00700.h5", "00721.h5", "00741.h5", "00777.h5", "00796.h5", "00868.h5", "00921.h5", "00935.h5", "00949.h5", "00953.h5",
11
+ "00965.h5", "00968.h5", "01036.h5", "01041.h5", "01051.h5", "01091.h5", "01148.h5", "01152.h5", "01155.h5", "01183.h5", "01200.h5", "01273.h5", "01278.h5", "01286.h5", "01326.h5", "01329.h5", "01370.h5", "01376.h5", "01425.h5", "01457.h5", "01477.h5",
12
+ "01506.h5", "01517.h5", "01525.h5", "01575.h5", "01625.h5", "01672.h5", "01674.h5", "01689.h5", "01782.h5", "01794.h5", "01813.h5", "01830.h5", "01855.h5", "01863.h5", "01877.h5", "01893.h5", "01941.h5", "01959.h5", "01978.h5",
13
+ "01983.h5", "01985.h5", "01997.h5", "02006.h5", "02020.h5", "02043.h5", "02078.h5", "02091.h5", "02109.h5", "02197.h5", "02213.h5", "02239.h5", "02240.h5", "02269.h5", "02275.h5", "02281.h5", "02292.h5",
14
+ "02301.h5", "02348.h5", "02413.h5", "02419.h5", "02450.h5", "02455.h5", "02461.h5", "02480.h5", "02536.h5", "02601.h5", "02734.h5", "02755.h5", "02756.h5", "02805.h5", "02833.h5", "02851.h5", "02885.h5", "02899.h5", "02942.h5", "02966.h5",
15
+ "02986.h5", "03011.h5", "03024.h5", "03043.h5", "03117.h5", "03126.h5", "03140.h5", "03177.h5", "03183.h5", "03185.h5", "03202.h5", "03216.h5", "03223.h5", "03247.h5", "03270.h5", "03324.h5", "03326.h5", "03344.h5", "03352.h5", "03361.h5", "03366.h5",
16
+ "03404.h5", "03412.h5", "03451.h5", "03523.h5"]
unigaze/configs/data/gazecapture_train.yaml ADDED
@@ -0,0 +1,1189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.gazecapture.GazeCaptureDataset
2
+ params:
3
+ data_name: gazecapture_train_224
4
+ color_type: rgb
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ sample_rate_use: 1
9
+ keys_to_use:
10
+ - 00002.h5
11
+ - 00003.h5
12
+ - 00005.h5
13
+ - 00006.h5
14
+ - 00024.h5
15
+ - 00028.h5
16
+ - 00033.h5
17
+ - 00034.h5
18
+ - 00087.h5
19
+ - 00089.h5
20
+ - 00097.h5
21
+ - 00098.h5
22
+ - 00099.h5
23
+ - 00102.h5
24
+ - 00103.h5
25
+ - 00104.h5
26
+ - 00114.h5
27
+ - 00120.h5
28
+ - 00121.h5
29
+ - 00122.h5
30
+ - 00123.h5
31
+ - 00127.h5
32
+ - 00128.h5
33
+ - 00130.h5
34
+ - 00132.h5
35
+ - 00137.h5
36
+ - 00138.h5
37
+ - 00139.h5
38
+ - 00140.h5
39
+ - 00141.h5
40
+ - 00142.h5
41
+ - 00143.h5
42
+ - 00144.h5
43
+ - 00145.h5
44
+ - 00146.h5
45
+ - 00148.h5
46
+ - 00149.h5
47
+ - 00150.h5
48
+ - 00153.h5
49
+ - 00154.h5
50
+ - 00156.h5
51
+ - 00162.h5
52
+ - 00164.h5
53
+ - 00165.h5
54
+ - 00173.h5
55
+ - 00179.h5
56
+ - 00191.h5
57
+ - 00194.h5
58
+ - 00200.h5
59
+ - 00202.h5
60
+ - 00208.h5
61
+ - 00209.h5
62
+ - 00210.h5
63
+ - 00211.h5
64
+ - 00212.h5
65
+ - 00214.h5
66
+ - 00218.h5
67
+ - 00221.h5
68
+ - 00224.h5
69
+ - 00225.h5
70
+ - 00226.h5
71
+ - 00227.h5
72
+ - 00228.h5
73
+ - 00232.h5
74
+ - 00234.h5
75
+ - 00236.h5
76
+ - 00237.h5
77
+ - 00238.h5
78
+ - 00239.h5
79
+ - 00240.h5
80
+ - 00241.h5
81
+ - 00243.h5
82
+ - 00245.h5
83
+ - 00247.h5
84
+ - 00249.h5
85
+ - 00268.h5
86
+ - 00269.h5
87
+ - 00273.h5
88
+ - 00274.h5
89
+ - 00285.h5
90
+ - 00288.h5
91
+ - 00289.h5
92
+ - 00295.h5
93
+ - 00296.h5
94
+ - 00299.h5
95
+ - 00300.h5
96
+ - 00303.h5
97
+ - 00304.h5
98
+ - 00305.h5
99
+ - 00307.h5
100
+ - 00309.h5
101
+ - 00310.h5
102
+ - 00311.h5
103
+ - 00312.h5
104
+ - 00317.h5
105
+ - 00324.h5
106
+ - 00325.h5
107
+ - 00326.h5
108
+ - 00331.h5
109
+ - 00332.h5
110
+ - 00339.h5
111
+ - 00342.h5
112
+ - 00351.h5
113
+ - 00354.h5
114
+ - 00355.h5
115
+ - 00356.h5
116
+ - 00357.h5
117
+ - 00358.h5
118
+ - 00359.h5
119
+ - 00363.h5
120
+ - 00376.h5
121
+ - 00377.h5
122
+ - 00459.h5
123
+ - 00465.h5
124
+ - 00466.h5
125
+ - 00467.h5
126
+ - 00469.h5
127
+ - 00472.h5
128
+ - 00473.h5
129
+ - 00475.h5
130
+ - 00477.h5
131
+ - 00480.h5
132
+ - 00481.h5
133
+ - 00487.h5
134
+ - 00488.h5
135
+ - 00491.h5
136
+ - 00492.h5
137
+ - 00493.h5
138
+ - 00494.h5
139
+ - 00495.h5
140
+ - 00496.h5
141
+ - 00499.h5
142
+ - 00501.h5
143
+ - 00503.h5
144
+ - 00505.h5
145
+ - 00510.h5
146
+ - 00512.h5
147
+ - 00513.h5
148
+ - 00514.h5
149
+ - 00518.h5
150
+ - 00519.h5
151
+ - 00520.h5
152
+ - 00522.h5
153
+ - 00525.h5
154
+ - 00531.h5
155
+ - 00533.h5
156
+ - 00534.h5
157
+ - 00535.h5
158
+ - 00539.h5
159
+ - 00540.h5
160
+ - 00542.h5
161
+ - 00544.h5
162
+ - 00545.h5
163
+ - 00548.h5
164
+ - 00550.h5
165
+ - 00553.h5
166
+ - 00554.h5
167
+ - 00555.h5
168
+ - 00560.h5
169
+ - 00562.h5
170
+ - 00565.h5
171
+ - 00566.h5
172
+ - 00569.h5
173
+ - 00572.h5
174
+ - 00574.h5
175
+ - 00575.h5
176
+ - 00578.h5
177
+ - 00581.h5
178
+ - 00584.h5
179
+ - 00588.h5
180
+ - 00590.h5
181
+ - 00599.h5
182
+ - 00600.h5
183
+ - 00601.h5
184
+ - 00602.h5
185
+ - 00605.h5
186
+ - 00606.h5
187
+ - 00607.h5
188
+ - 00610.h5
189
+ - 00613.h5
190
+ - 00617.h5
191
+ - 00621.h5
192
+ - 00622.h5
193
+ - 00623.h5
194
+ - 00624.h5
195
+ - 00626.h5
196
+ - 00627.h5
197
+ - 00632.h5
198
+ - 00633.h5
199
+ - 00634.h5
200
+ - 00636.h5
201
+ - 00638.h5
202
+ - 00641.h5
203
+ - 00642.h5
204
+ - 00643.h5
205
+ - 00644.h5
206
+ - 00645.h5
207
+ - 00649.h5
208
+ - 00650.h5
209
+ - 00658.h5
210
+ - 00661.h5
211
+ - 00663.h5
212
+ - 00666.h5
213
+ - 00667.h5
214
+ - 00668.h5
215
+ - 00669.h5
216
+ - 00670.h5
217
+ - 00672.h5
218
+ - 00675.h5
219
+ - 00676.h5
220
+ - 00677.h5
221
+ - 00678.h5
222
+ - 00679.h5
223
+ - 00682.h5
224
+ - 00683.h5
225
+ - 00687.h5
226
+ - 00688.h5
227
+ - 00690.h5
228
+ - 00691.h5
229
+ - 00693.h5
230
+ - 00694.h5
231
+ - 00695.h5
232
+ - 00699.h5
233
+ - 00704.h5
234
+ - 00706.h5
235
+ - 00707.h5
236
+ - 00710.h5
237
+ - 00711.h5
238
+ - 00712.h5
239
+ - 00714.h5
240
+ - 00716.h5
241
+ - 00718.h5
242
+ - 00719.h5
243
+ - 00722.h5
244
+ - 00728.h5
245
+ - 00729.h5
246
+ - 00730.h5
247
+ - 00731.h5
248
+ - 00732.h5
249
+ - 00733.h5
250
+ - 00737.h5
251
+ - 00742.h5
252
+ - 00743.h5
253
+ - 00745.h5
254
+ - 00747.h5
255
+ - 00749.h5
256
+ - 00750.h5
257
+ - 00752.h5
258
+ - 00753.h5
259
+ - 00755.h5
260
+ - 00756.h5
261
+ - 00757.h5
262
+ - 00764.h5
263
+ - 00765.h5
264
+ - 00767.h5
265
+ - 00771.h5
266
+ - 00772.h5
267
+ - 00773.h5
268
+ - 00774.h5
269
+ - 00775.h5
270
+ - 00789.h5
271
+ - 00790.h5
272
+ - 00791.h5
273
+ - 00795.h5
274
+ - 00798.h5
275
+ - 00801.h5
276
+ - 00802.h5
277
+ - 00804.h5
278
+ - 00806.h5
279
+ - 00807.h5
280
+ - 00810.h5
281
+ - 00811.h5
282
+ - 00812.h5
283
+ - 00814.h5
284
+ - 00818.h5
285
+ - 00819.h5
286
+ - 00820.h5
287
+ - 00821.h5
288
+ - 00823.h5
289
+ - 00825.h5
290
+ - 00827.h5
291
+ - 00831.h5
292
+ - 00832.h5
293
+ - 00833.h5
294
+ - 00835.h5
295
+ - 00837.h5
296
+ - 00840.h5
297
+ - 00841.h5
298
+ - 00842.h5
299
+ - 00849.h5
300
+ - 00850.h5
301
+ - 00851.h5
302
+ - 00852.h5
303
+ - 00853.h5
304
+ - 00855.h5
305
+ - 00859.h5
306
+ - 00864.h5
307
+ - 00865.h5
308
+ - 00869.h5
309
+ - 00872.h5
310
+ - 00873.h5
311
+ - 00874.h5
312
+ - 00875.h5
313
+ - 00878.h5
314
+ - 00881.h5
315
+ - 00882.h5
316
+ - 00886.h5
317
+ - 00888.h5
318
+ - 00889.h5
319
+ - 00891.h5
320
+ - 00892.h5
321
+ - 00894.h5
322
+ - 00896.h5
323
+ - 00897.h5
324
+ - 00898.h5
325
+ - 00899.h5
326
+ - 00900.h5
327
+ - 00904.h5
328
+ - 00905.h5
329
+ - 00907.h5
330
+ - 00911.h5
331
+ - 00912.h5
332
+ - 00914.h5
333
+ - 00915.h5
334
+ - 00923.h5
335
+ - 00924.h5
336
+ - 00927.h5
337
+ - 00931.h5
338
+ - 00933.h5
339
+ - 00934.h5
340
+ - 00938.h5
341
+ - 00944.h5
342
+ - 00945.h5
343
+ - 00947.h5
344
+ - 00948.h5
345
+ - 00956.h5
346
+ - 00961.h5
347
+ - 00963.h5
348
+ - 00969.h5
349
+ - 00971.h5
350
+ - 00974.h5
351
+ - 00980.h5
352
+ - 00981.h5
353
+ - 00982.h5
354
+ - 00983.h5
355
+ - 00984.h5
356
+ - 00986.h5
357
+ - 00989.h5
358
+ - 00991.h5
359
+ - 00992.h5
360
+ - 00997.h5
361
+ - 00999.h5
362
+ - 01000.h5
363
+ - 01002.h5
364
+ - 01003.h5
365
+ - 01009.h5
366
+ - 01010.h5
367
+ - 01012.h5
368
+ - 01015.h5
369
+ - 01018.h5
370
+ - 01019.h5
371
+ - 01020.h5
372
+ - 01021.h5
373
+ - 01022.h5
374
+ - 01024.h5
375
+ - 01025.h5
376
+ - 01031.h5
377
+ - 01032.h5
378
+ - 01034.h5
379
+ - 01035.h5
380
+ - 01038.h5
381
+ - 01039.h5
382
+ - 01042.h5
383
+ - 01044.h5
384
+ - 01045.h5
385
+ - 01046.h5
386
+ - 01050.h5
387
+ - 01052.h5
388
+ - 01054.h5
389
+ - 01055.h5
390
+ - 01056.h5
391
+ - 01057.h5
392
+ - 01058.h5
393
+ - 01059.h5
394
+ - 01060.h5
395
+ - 01062.h5
396
+ - 01063.h5
397
+ - 01064.h5
398
+ - 01065.h5
399
+ - 01069.h5
400
+ - 01070.h5
401
+ - 01073.h5
402
+ - 01075.h5
403
+ - 01076.h5
404
+ - 01077.h5
405
+ - 01080.h5
406
+ - 01081.h5
407
+ - 01082.h5
408
+ - 01083.h5
409
+ - 01084.h5
410
+ - 01085.h5
411
+ - 01086.h5
412
+ - 01087.h5
413
+ - 01088.h5
414
+ - 01089.h5
415
+ - 01090.h5
416
+ - 01092.h5
417
+ - 01093.h5
418
+ - 01095.h5
419
+ - 01100.h5
420
+ - 01102.h5
421
+ - 01104.h5
422
+ - 01105.h5
423
+ - 01106.h5
424
+ - 01107.h5
425
+ - 01110.h5
426
+ - 01118.h5
427
+ - 01120.h5
428
+ - 01121.h5
429
+ - 01123.h5
430
+ - 01127.h5
431
+ - 01128.h5
432
+ - 01129.h5
433
+ - 01135.h5
434
+ - 01138.h5
435
+ - 01139.h5
436
+ - 01143.h5
437
+ - 01145.h5
438
+ - 01146.h5
439
+ - 01147.h5
440
+ - 01149.h5
441
+ - 01151.h5
442
+ - 01156.h5
443
+ - 01157.h5
444
+ - 01158.h5
445
+ - 01161.h5
446
+ - 01162.h5
447
+ - 01163.h5
448
+ - 01164.h5
449
+ - 01165.h5
450
+ - 01166.h5
451
+ - 01167.h5
452
+ - 01168.h5
453
+ - 01169.h5
454
+ - 01170.h5
455
+ - 01171.h5
456
+ - 01172.h5
457
+ - 01173.h5
458
+ - 01174.h5
459
+ - 01175.h5
460
+ - 01177.h5
461
+ - 01178.h5
462
+ - 01180.h5
463
+ - 01181.h5
464
+ - 01182.h5
465
+ - 01184.h5
466
+ - 01186.h5
467
+ - 01188.h5
468
+ - 01191.h5
469
+ - 01195.h5
470
+ - 01199.h5
471
+ - 01201.h5
472
+ - 01204.h5
473
+ - 01207.h5
474
+ - 01208.h5
475
+ - 01209.h5
476
+ - 01211.h5
477
+ - 01212.h5
478
+ - 01213.h5
479
+ - 01219.h5
480
+ - 01221.h5
481
+ - 01222.h5
482
+ - 01231.h5
483
+ - 01232.h5
484
+ - 01233.h5
485
+ - 01237.h5
486
+ - 01243.h5
487
+ - 01244.h5
488
+ - 01247.h5
489
+ - 01250.h5
490
+ - 01252.h5
491
+ - 01254.h5
492
+ - 01255.h5
493
+ - 01256.h5
494
+ - 01259.h5
495
+ - 01260.h5
496
+ - 01262.h5
497
+ - 01266.h5
498
+ - 01269.h5
499
+ - 01270.h5
500
+ - 01275.h5
501
+ - 01276.h5
502
+ - 01279.h5
503
+ - 01281.h5
504
+ - 01283.h5
505
+ - 01285.h5
506
+ - 01293.h5
507
+ - 01295.h5
508
+ - 01298.h5
509
+ - 01300.h5
510
+ - 01301.h5
511
+ - 01303.h5
512
+ - 01304.h5
513
+ - 01315.h5
514
+ - 01316.h5
515
+ - 01320.h5
516
+ - 01323.h5
517
+ - 01327.h5
518
+ - 01328.h5
519
+ - 01330.h5
520
+ - 01331.h5
521
+ - 01333.h5
522
+ - 01340.h5
523
+ - 01347.h5
524
+ - 01348.h5
525
+ - 01349.h5
526
+ - 01351.h5
527
+ - 01352.h5
528
+ - 01353.h5
529
+ - 01354.h5
530
+ - 01356.h5
531
+ - 01357.h5
532
+ - 01358.h5
533
+ - 01360.h5
534
+ - 01361.h5
535
+ - 01362.h5
536
+ - 01368.h5
537
+ - 01375.h5
538
+ - 01377.h5
539
+ - 01379.h5
540
+ - 01380.h5
541
+ - 01382.h5
542
+ - 01383.h5
543
+ - 01384.h5
544
+ - 01386.h5
545
+ - 01387.h5
546
+ - 01388.h5
547
+ - 01389.h5
548
+ - 01390.h5
549
+ - 01391.h5
550
+ - 01393.h5
551
+ - 01396.h5
552
+ - 01400.h5
553
+ - 01405.h5
554
+ - 01406.h5
555
+ - 01414.h5
556
+ - 01415.h5
557
+ - 01420.h5
558
+ - 01421.h5
559
+ - 01423.h5
560
+ - 01424.h5
561
+ - 01428.h5
562
+ - 01430.h5
563
+ - 01431.h5
564
+ - 01434.h5
565
+ - 01435.h5
566
+ - 01438.h5
567
+ - 01440.h5
568
+ - 01445.h5
569
+ - 01446.h5
570
+ - 01448.h5
571
+ - 01451.h5
572
+ - 01454.h5
573
+ - 01456.h5
574
+ - 01459.h5
575
+ - 01460.h5
576
+ - 01462.h5
577
+ - 01467.h5
578
+ - 01470.h5
579
+ - 01471.h5
580
+ - 01472.h5
581
+ - 01473.h5
582
+ - 01478.h5
583
+ - 01479.h5
584
+ - 01480.h5
585
+ - 01481.h5
586
+ - 01482.h5
587
+ - 01483.h5
588
+ - 01485.h5
589
+ - 01486.h5
590
+ - 01487.h5
591
+ - 01488.h5
592
+ - 01491.h5
593
+ - 01492.h5
594
+ - 01496.h5
595
+ - 01497.h5
596
+ - 01499.h5
597
+ - 01508.h5
598
+ - 01510.h5
599
+ - 01511.h5
600
+ - 01514.h5
601
+ - 01515.h5
602
+ - 01516.h5
603
+ - 01519.h5
604
+ - 01523.h5
605
+ - 01524.h5
606
+ - 01528.h5
607
+ - 01531.h5
608
+ - 01532.h5
609
+ - 01533.h5
610
+ - 01534.h5
611
+ - 01540.h5
612
+ - 01542.h5
613
+ - 01546.h5
614
+ - 01551.h5
615
+ - 01553.h5
616
+ - 01566.h5
617
+ - 01569.h5
618
+ - 01574.h5
619
+ - 01577.h5
620
+ - 01581.h5
621
+ - 01582.h5
622
+ - 01583.h5
623
+ - 01584.h5
624
+ - 01602.h5
625
+ - 01603.h5
626
+ - 01604.h5
627
+ - 01606.h5
628
+ - 01611.h5
629
+ - 01612.h5
630
+ - 01613.h5
631
+ - 01617.h5
632
+ - 01618.h5
633
+ - 01627.h5
634
+ - 01630.h5
635
+ - 01631.h5
636
+ - 01633.h5
637
+ - 01635.h5
638
+ - 01636.h5
639
+ - 01637.h5
640
+ - 01640.h5
641
+ - 01643.h5
642
+ - 01644.h5
643
+ - 01645.h5
644
+ - 01648.h5
645
+ - 01650.h5
646
+ - 01651.h5
647
+ - 01653.h5
648
+ - 01658.h5
649
+ - 01665.h5
650
+ - 01669.h5
651
+ - 01671.h5
652
+ - 01678.h5
653
+ - 01680.h5
654
+ - 01681.h5
655
+ - 01682.h5
656
+ - 01684.h5
657
+ - 01687.h5
658
+ - 01690.h5
659
+ - 01692.h5
660
+ - 01693.h5
661
+ - 01697.h5
662
+ - 01698.h5
663
+ - 01700.h5
664
+ - 01703.h5
665
+ - 01705.h5
666
+ - 01706.h5
667
+ - 01709.h5
668
+ - 01710.h5
669
+ - 01713.h5
670
+ - 01717.h5
671
+ - 01718.h5
672
+ - 01719.h5
673
+ - 01720.h5
674
+ - 01726.h5
675
+ - 01727.h5
676
+ - 01728.h5
677
+ - 01729.h5
678
+ - 01730.h5
679
+ - 01731.h5
680
+ - 01734.h5
681
+ - 01738.h5
682
+ - 01741.h5
683
+ - 01744.h5
684
+ - 01745.h5
685
+ - 01747.h5
686
+ - 01748.h5
687
+ - 01755.h5
688
+ - 01762.h5
689
+ - 01763.h5
690
+ - 01768.h5
691
+ - 01770.h5
692
+ - 01771.h5
693
+ - 01775.h5
694
+ - 01778.h5
695
+ - 01779.h5
696
+ - 01783.h5
697
+ - 01789.h5
698
+ - 01792.h5
699
+ - 01795.h5
700
+ - 01796.h5
701
+ - 01798.h5
702
+ - 01802.h5
703
+ - 01803.h5
704
+ - 01806.h5
705
+ - 01812.h5
706
+ - 01816.h5
707
+ - 01817.h5
708
+ - 01818.h5
709
+ - 01821.h5
710
+ - 01823.h5
711
+ - 01825.h5
712
+ - 01826.h5
713
+ - 01827.h5
714
+ - 01828.h5
715
+ - 01833.h5
716
+ - 01843.h5
717
+ - 01849.h5
718
+ - 01858.h5
719
+ - 01860.h5
720
+ - 01862.h5
721
+ - 01866.h5
722
+ - 01867.h5
723
+ - 01868.h5
724
+ - 01869.h5
725
+ - 01870.h5
726
+ - 01874.h5
727
+ - 01878.h5
728
+ - 01880.h5
729
+ - 01882.h5
730
+ - 01883.h5
731
+ - 01884.h5
732
+ - 01885.h5
733
+ - 01887.h5
734
+ - 01888.h5
735
+ - 01889.h5
736
+ - 01892.h5
737
+ - 01897.h5
738
+ - 01900.h5
739
+ - 01901.h5
740
+ - 01902.h5
741
+ - 01905.h5
742
+ - 01906.h5
743
+ - 01907.h5
744
+ - 01908.h5
745
+ - 01912.h5
746
+ - 01915.h5
747
+ - 01921.h5
748
+ - 01922.h5
749
+ - 01924.h5
750
+ - 01925.h5
751
+ - 01926.h5
752
+ - 01927.h5
753
+ - 01930.h5
754
+ - 01933.h5
755
+ - 01936.h5
756
+ - 01943.h5
757
+ - 01960.h5
758
+ - 01961.h5
759
+ - 01962.h5
760
+ - 01964.h5
761
+ - 01965.h5
762
+ - 01966.h5
763
+ - 01975.h5
764
+ - 01976.h5
765
+ - 01977.h5
766
+ - 01979.h5
767
+ - 01984.h5
768
+ - 01987.h5
769
+ - 01995.h5
770
+ - 02009.h5
771
+ - 02011.h5
772
+ - 02015.h5
773
+ - 02019.h5
774
+ - 02022.h5
775
+ - 02023.h5
776
+ - 02024.h5
777
+ - 02025.h5
778
+ - 02026.h5
779
+ - 02028.h5
780
+ - 02029.h5
781
+ - 02034.h5
782
+ - 02035.h5
783
+ - 02038.h5
784
+ - 02045.h5
785
+ - 02047.h5
786
+ - 02051.h5
787
+ - 02052.h5
788
+ - 02056.h5
789
+ - 02058.h5
790
+ - 02059.h5
791
+ - 02061.h5
792
+ - 02064.h5
793
+ - 02065.h5
794
+ - 02077.h5
795
+ - 02084.h5
796
+ - 02085.h5
797
+ - 02086.h5
798
+ - 02087.h5
799
+ - 02090.h5
800
+ - 02092.h5
801
+ - 02093.h5
802
+ - 02099.h5
803
+ - 02102.h5
804
+ - 02105.h5
805
+ - 02106.h5
806
+ - 02112.h5
807
+ - 02113.h5
808
+ - 02114.h5
809
+ - 02115.h5
810
+ - 02118.h5
811
+ - 02123.h5
812
+ - 02131.h5
813
+ - 02136.h5
814
+ - 02137.h5
815
+ - 02138.h5
816
+ - 02140.h5
817
+ - 02141.h5
818
+ - 02142.h5
819
+ - 02152.h5
820
+ - 02154.h5
821
+ - 02156.h5
822
+ - 02159.h5
823
+ - 02161.h5
824
+ - 02162.h5
825
+ - 02168.h5
826
+ - 02170.h5
827
+ - 02172.h5
828
+ - 02173.h5
829
+ - 02186.h5
830
+ - 02187.h5
831
+ - 02193.h5
832
+ - 02198.h5
833
+ - 02203.h5
834
+ - 02204.h5
835
+ - 02206.h5
836
+ - 02207.h5
837
+ - 02212.h5
838
+ - 02216.h5
839
+ - 02219.h5
840
+ - 02220.h5
841
+ - 02229.h5
842
+ - 02230.h5
843
+ - 02232.h5
844
+ - 02234.h5
845
+ - 02237.h5
846
+ - 02241.h5
847
+ - 02244.h5
848
+ - 02249.h5
849
+ - 02250.h5
850
+ - 02255.h5
851
+ - 02257.h5
852
+ - 02264.h5
853
+ - 02266.h5
854
+ - 02267.h5
855
+ - 02270.h5
856
+ - 02272.h5
857
+ - 02277.h5
858
+ - 02278.h5
859
+ - 02279.h5
860
+ - 02282.h5
861
+ - 02293.h5
862
+ - 02297.h5
863
+ - 02298.h5
864
+ - 02300.h5
865
+ - 02311.h5
866
+ - 02314.h5
867
+ - 02319.h5
868
+ - 02321.h5
869
+ - 02322.h5
870
+ - 02324.h5
871
+ - 02326.h5
872
+ - 02327.h5
873
+ - 02328.h5
874
+ - 02332.h5
875
+ - 02334.h5
876
+ - 02337.h5
877
+ - 02339.h5
878
+ - 02342.h5
879
+ - 02343.h5
880
+ - 02347.h5
881
+ - 02349.h5
882
+ - 02350.h5
883
+ - 02352.h5
884
+ - 02355.h5
885
+ - 02358.h5
886
+ - 02359.h5
887
+ - 02361.h5
888
+ - 02362.h5
889
+ - 02365.h5
890
+ - 02366.h5
891
+ - 02367.h5
892
+ - 02368.h5
893
+ - 02370.h5
894
+ - 02371.h5
895
+ - 02373.h5
896
+ - 02375.h5
897
+ - 02379.h5
898
+ - 02394.h5
899
+ - 02412.h5
900
+ - 02414.h5
901
+ - 02415.h5
902
+ - 02418.h5
903
+ - 02420.h5
904
+ - 02421.h5
905
+ - 02424.h5
906
+ - 02426.h5
907
+ - 02430.h5
908
+ - 02431.h5
909
+ - 02432.h5
910
+ - 02434.h5
911
+ - 02435.h5
912
+ - 02436.h5
913
+ - 02439.h5
914
+ - 02440.h5
915
+ - 02441.h5
916
+ - 02442.h5
917
+ - 02443.h5
918
+ - 02445.h5
919
+ - 02447.h5
920
+ - 02448.h5
921
+ - 02452.h5
922
+ - 02454.h5
923
+ - 02457.h5
924
+ - 02458.h5
925
+ - 02459.h5
926
+ - 02462.h5
927
+ - 02465.h5
928
+ - 02467.h5
929
+ - 02468.h5
930
+ - 02469.h5
931
+ - 02472.h5
932
+ - 02474.h5
933
+ - 02478.h5
934
+ - 02510.h5
935
+ - 02518.h5
936
+ - 02520.h5
937
+ - 02521.h5
938
+ - 02522.h5
939
+ - 02524.h5
940
+ - 02525.h5
941
+ - 02534.h5
942
+ - 02535.h5
943
+ - 02540.h5
944
+ - 02547.h5
945
+ - 02550.h5
946
+ - 02552.h5
947
+ - 02553.h5
948
+ - 02554.h5
949
+ - 02557.h5
950
+ - 02559.h5
951
+ - 02566.h5
952
+ - 02567.h5
953
+ - 02571.h5
954
+ - 02573.h5
955
+ - 02575.h5
956
+ - 02576.h5
957
+ - 02578.h5
958
+ - 02581.h5
959
+ - 02585.h5
960
+ - 02587.h5
961
+ - 02588.h5
962
+ - 02590.h5
963
+ - 02595.h5
964
+ - 02610.h5
965
+ - 02611.h5
966
+ - 02613.h5
967
+ - 02615.h5
968
+ - 02617.h5
969
+ - 02619.h5
970
+ - 02629.h5
971
+ - 02632.h5
972
+ - 02634.h5
973
+ - 02649.h5
974
+ - 02663.h5
975
+ - 02666.h5
976
+ - 02669.h5
977
+ - 02673.h5
978
+ - 02681.h5
979
+ - 02689.h5
980
+ - 02690.h5
981
+ - 02700.h5
982
+ - 02705.h5
983
+ - 02709.h5
984
+ - 02713.h5
985
+ - 02718.h5
986
+ - 02721.h5
987
+ - 02722.h5
988
+ - 02723.h5
989
+ - 02725.h5
990
+ - 02729.h5
991
+ - 02730.h5
992
+ - 02732.h5
993
+ - 02737.h5
994
+ - 02740.h5
995
+ - 02741.h5
996
+ - 02749.h5
997
+ - 02758.h5
998
+ - 02760.h5
999
+ - 02761.h5
1000
+ - 02762.h5
1001
+ - 02763.h5
1002
+ - 02764.h5
1003
+ - 02765.h5
1004
+ - 02772.h5
1005
+ - 02773.h5
1006
+ - 02774.h5
1007
+ - 02776.h5
1008
+ - 02780.h5
1009
+ - 02781.h5
1010
+ - 02785.h5
1011
+ - 02797.h5
1012
+ - 02818.h5
1013
+ - 02819.h5
1014
+ - 02827.h5
1015
+ - 02829.h5
1016
+ - 02832.h5
1017
+ - 02837.h5
1018
+ - 02841.h5
1019
+ - 02843.h5
1020
+ - 02846.h5
1021
+ - 02847.h5
1022
+ - 02852.h5
1023
+ - 02854.h5
1024
+ - 02857.h5
1025
+ - 02868.h5
1026
+ - 02872.h5
1027
+ - 02873.h5
1028
+ - 02874.h5
1029
+ - 02876.h5
1030
+ - 02877.h5
1031
+ - 02878.h5
1032
+ - 02879.h5
1033
+ - 02880.h5
1034
+ - 02882.h5
1035
+ - 02883.h5
1036
+ - 02888.h5
1037
+ - 02898.h5
1038
+ - 02902.h5
1039
+ - 02908.h5
1040
+ - 02911.h5
1041
+ - 02919.h5
1042
+ - 02920.h5
1043
+ - 02921.h5
1044
+ - 02922.h5
1045
+ - 02924.h5
1046
+ - 02925.h5
1047
+ - 02928.h5
1048
+ - 02938.h5
1049
+ - 02941.h5
1050
+ - 02944.h5
1051
+ - 02945.h5
1052
+ - 02954.h5
1053
+ - 02955.h5
1054
+ - 02956.h5
1055
+ - 02960.h5
1056
+ - 02961.h5
1057
+ - 02964.h5
1058
+ - 02967.h5
1059
+ - 02977.h5
1060
+ - 02978.h5
1061
+ - 02979.h5
1062
+ - 02980.h5
1063
+ - 02985.h5
1064
+ - 02987.h5
1065
+ - 02988.h5
1066
+ - 02989.h5
1067
+ - 02991.h5
1068
+ - 02997.h5
1069
+ - 02998.h5
1070
+ - 03003.h5
1071
+ - 03004.h5
1072
+ - 03006.h5
1073
+ - 03009.h5
1074
+ - 03012.h5
1075
+ - 03013.h5
1076
+ - 03014.h5
1077
+ - 03023.h5
1078
+ - 03026.h5
1079
+ - 03027.h5
1080
+ - 03037.h5
1081
+ - 03042.h5
1082
+ - 03051.h5
1083
+ - 03057.h5
1084
+ - 03064.h5
1085
+ - 03065.h5
1086
+ - 03079.h5
1087
+ - 03089.h5
1088
+ - 03102.h5
1089
+ - 03107.h5
1090
+ - 03116.h5
1091
+ - 03122.h5
1092
+ - 03125.h5
1093
+ - 03130.h5
1094
+ - 03133.h5
1095
+ - 03134.h5
1096
+ - 03137.h5
1097
+ - 03139.h5
1098
+ - 03160.h5
1099
+ - 03163.h5
1100
+ - 03172.h5
1101
+ - 03174.h5
1102
+ - 03178.h5
1103
+ - 03179.h5
1104
+ - 03180.h5
1105
+ - 03188.h5
1106
+ - 03189.h5
1107
+ - 03190.h5
1108
+ - 03192.h5
1109
+ - 03193.h5
1110
+ - 03197.h5
1111
+ - 03199.h5
1112
+ - 03200.h5
1113
+ - 03205.h5
1114
+ - 03206.h5
1115
+ - 03211.h5
1116
+ - 03218.h5
1117
+ - 03219.h5
1118
+ - 03222.h5
1119
+ - 03225.h5
1120
+ - 03231.h5
1121
+ - 03246.h5
1122
+ - 03248.h5
1123
+ - 03251.h5
1124
+ - 03253.h5
1125
+ - 03255.h5
1126
+ - 03259.h5
1127
+ - 03263.h5
1128
+ - 03265.h5
1129
+ - 03266.h5
1130
+ - 03273.h5
1131
+ - 03275.h5
1132
+ - 03277.h5
1133
+ - 03278.h5
1134
+ - 03282.h5
1135
+ - 03283.h5
1136
+ - 03302.h5
1137
+ - 03303.h5
1138
+ - 03304.h5
1139
+ - 03307.h5
1140
+ - 03314.h5
1141
+ - 03315.h5
1142
+ - 03327.h5
1143
+ - 03328.h5
1144
+ - 03332.h5
1145
+ - 03336.h5
1146
+ - 03340.h5
1147
+ - 03342.h5
1148
+ - 03343.h5
1149
+ - 03348.h5
1150
+ - 03351.h5
1151
+ - 03354.h5
1152
+ - 03358.h5
1153
+ - 03359.h5
1154
+ - 03360.h5
1155
+ - 03367.h5
1156
+ - 03371.h5
1157
+ - 03374.h5
1158
+ - 03375.h5
1159
+ - 03377.h5
1160
+ - 03378.h5
1161
+ - 03379.h5
1162
+ - 03381.h5
1163
+ - 03382.h5
1164
+ - 03384.h5
1165
+ - 03397.h5
1166
+ - 03403.h5
1167
+ - 03406.h5
1168
+ - 03413.h5
1169
+ - 03425.h5
1170
+ - 03431.h5
1171
+ - 03432.h5
1172
+ - 03435.h5
1173
+ - 03442.h5
1174
+ - 03453.h5
1175
+ - 03454.h5
1176
+ - 03456.h5
1177
+ - 03463.h5
1178
+ - 03465.h5
1179
+ - 03466.h5
1180
+ - 03467.h5
1181
+ - 03469.h5
1182
+ - 03473.h5
1183
+ - 03491.h5
1184
+ - 03492.h5
1185
+ - 03495.h5
1186
+ - 03498.h5
1187
+ - 03501.h5
1188
+ - 03502.h5
1189
+
unigaze/configs/data/gazecapture_train_ds15.yaml ADDED
@@ -0,0 +1,1189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.gazecapture.GazeCaptureDataset
2
+ params:
3
+ data_name: gazecapture_train_224
4
+ color_type: rgb
5
+ transform_type: 'basic_imagenet'
6
+ image_size: 224
7
+ dataset_path: null
8
+ sample_rate_use: 15
9
+ keys_to_use:
10
+ - 00002.h5
11
+ - 00003.h5
12
+ - 00005.h5
13
+ - 00006.h5
14
+ - 00024.h5
15
+ - 00028.h5
16
+ - 00033.h5
17
+ - 00034.h5
18
+ - 00087.h5
19
+ - 00089.h5
20
+ - 00097.h5
21
+ - 00098.h5
22
+ - 00099.h5
23
+ - 00102.h5
24
+ - 00103.h5
25
+ - 00104.h5
26
+ - 00114.h5
27
+ - 00120.h5
28
+ - 00121.h5
29
+ - 00122.h5
30
+ - 00123.h5
31
+ - 00127.h5
32
+ - 00128.h5
33
+ - 00130.h5
34
+ - 00132.h5
35
+ - 00137.h5
36
+ - 00138.h5
37
+ - 00139.h5
38
+ - 00140.h5
39
+ - 00141.h5
40
+ - 00142.h5
41
+ - 00143.h5
42
+ - 00144.h5
43
+ - 00145.h5
44
+ - 00146.h5
45
+ - 00148.h5
46
+ - 00149.h5
47
+ - 00150.h5
48
+ - 00153.h5
49
+ - 00154.h5
50
+ - 00156.h5
51
+ - 00162.h5
52
+ - 00164.h5
53
+ - 00165.h5
54
+ - 00173.h5
55
+ - 00179.h5
56
+ - 00191.h5
57
+ - 00194.h5
58
+ - 00200.h5
59
+ - 00202.h5
60
+ - 00208.h5
61
+ - 00209.h5
62
+ - 00210.h5
63
+ - 00211.h5
64
+ - 00212.h5
65
+ - 00214.h5
66
+ - 00218.h5
67
+ - 00221.h5
68
+ - 00224.h5
69
+ - 00225.h5
70
+ - 00226.h5
71
+ - 00227.h5
72
+ - 00228.h5
73
+ - 00232.h5
74
+ - 00234.h5
75
+ - 00236.h5
76
+ - 00237.h5
77
+ - 00238.h5
78
+ - 00239.h5
79
+ - 00240.h5
80
+ - 00241.h5
81
+ - 00243.h5
82
+ - 00245.h5
83
+ - 00247.h5
84
+ - 00249.h5
85
+ - 00268.h5
86
+ - 00269.h5
87
+ - 00273.h5
88
+ - 00274.h5
89
+ - 00285.h5
90
+ - 00288.h5
91
+ - 00289.h5
92
+ - 00295.h5
93
+ - 00296.h5
94
+ - 00299.h5
95
+ - 00300.h5
96
+ - 00303.h5
97
+ - 00304.h5
98
+ - 00305.h5
99
+ - 00307.h5
100
+ - 00309.h5
101
+ - 00310.h5
102
+ - 00311.h5
103
+ - 00312.h5
104
+ - 00317.h5
105
+ - 00324.h5
106
+ - 00325.h5
107
+ - 00326.h5
108
+ - 00331.h5
109
+ - 00332.h5
110
+ - 00339.h5
111
+ - 00342.h5
112
+ - 00351.h5
113
+ - 00354.h5
114
+ - 00355.h5
115
+ - 00356.h5
116
+ - 00357.h5
117
+ - 00358.h5
118
+ - 00359.h5
119
+ - 00363.h5
120
+ - 00376.h5
121
+ - 00377.h5
122
+ - 00459.h5
123
+ - 00465.h5
124
+ - 00466.h5
125
+ - 00467.h5
126
+ - 00469.h5
127
+ - 00472.h5
128
+ - 00473.h5
129
+ - 00475.h5
130
+ - 00477.h5
131
+ - 00480.h5
132
+ - 00481.h5
133
+ - 00487.h5
134
+ - 00488.h5
135
+ - 00491.h5
136
+ - 00492.h5
137
+ - 00493.h5
138
+ - 00494.h5
139
+ - 00495.h5
140
+ - 00496.h5
141
+ - 00499.h5
142
+ - 00501.h5
143
+ - 00503.h5
144
+ - 00505.h5
145
+ - 00510.h5
146
+ - 00512.h5
147
+ - 00513.h5
148
+ - 00514.h5
149
+ - 00518.h5
150
+ - 00519.h5
151
+ - 00520.h5
152
+ - 00522.h5
153
+ - 00525.h5
154
+ - 00531.h5
155
+ - 00533.h5
156
+ - 00534.h5
157
+ - 00535.h5
158
+ - 00539.h5
159
+ - 00540.h5
160
+ - 00542.h5
161
+ - 00544.h5
162
+ - 00545.h5
163
+ - 00548.h5
164
+ - 00550.h5
165
+ - 00553.h5
166
+ - 00554.h5
167
+ - 00555.h5
168
+ - 00560.h5
169
+ - 00562.h5
170
+ - 00565.h5
171
+ - 00566.h5
172
+ - 00569.h5
173
+ - 00572.h5
174
+ - 00574.h5
175
+ - 00575.h5
176
+ - 00578.h5
177
+ - 00581.h5
178
+ - 00584.h5
179
+ - 00588.h5
180
+ - 00590.h5
181
+ - 00599.h5
182
+ - 00600.h5
183
+ - 00601.h5
184
+ - 00602.h5
185
+ - 00605.h5
186
+ - 00606.h5
187
+ - 00607.h5
188
+ - 00610.h5
189
+ - 00613.h5
190
+ - 00617.h5
191
+ - 00621.h5
192
+ - 00622.h5
193
+ - 00623.h5
194
+ - 00624.h5
195
+ - 00626.h5
196
+ - 00627.h5
197
+ - 00632.h5
198
+ - 00633.h5
199
+ - 00634.h5
200
+ - 00636.h5
201
+ - 00638.h5
202
+ - 00641.h5
203
+ - 00642.h5
204
+ - 00643.h5
205
+ - 00644.h5
206
+ - 00645.h5
207
+ - 00649.h5
208
+ - 00650.h5
209
+ - 00658.h5
210
+ - 00661.h5
211
+ - 00663.h5
212
+ - 00666.h5
213
+ - 00667.h5
214
+ - 00668.h5
215
+ - 00669.h5
216
+ - 00670.h5
217
+ - 00672.h5
218
+ - 00675.h5
219
+ - 00676.h5
220
+ - 00677.h5
221
+ - 00678.h5
222
+ - 00679.h5
223
+ - 00682.h5
224
+ - 00683.h5
225
+ - 00687.h5
226
+ - 00688.h5
227
+ - 00690.h5
228
+ - 00691.h5
229
+ - 00693.h5
230
+ - 00694.h5
231
+ - 00695.h5
232
+ - 00699.h5
233
+ - 00704.h5
234
+ - 00706.h5
235
+ - 00707.h5
236
+ - 00710.h5
237
+ - 00711.h5
238
+ - 00712.h5
239
+ - 00714.h5
240
+ - 00716.h5
241
+ - 00718.h5
242
+ - 00719.h5
243
+ - 00722.h5
244
+ - 00728.h5
245
+ - 00729.h5
246
+ - 00730.h5
247
+ - 00731.h5
248
+ - 00732.h5
249
+ - 00733.h5
250
+ - 00737.h5
251
+ - 00742.h5
252
+ - 00743.h5
253
+ - 00745.h5
254
+ - 00747.h5
255
+ - 00749.h5
256
+ - 00750.h5
257
+ - 00752.h5
258
+ - 00753.h5
259
+ - 00755.h5
260
+ - 00756.h5
261
+ - 00757.h5
262
+ - 00764.h5
263
+ - 00765.h5
264
+ - 00767.h5
265
+ - 00771.h5
266
+ - 00772.h5
267
+ - 00773.h5
268
+ - 00774.h5
269
+ - 00775.h5
270
+ - 00789.h5
271
+ - 00790.h5
272
+ - 00791.h5
273
+ - 00795.h5
274
+ - 00798.h5
275
+ - 00801.h5
276
+ - 00802.h5
277
+ - 00804.h5
278
+ - 00806.h5
279
+ - 00807.h5
280
+ - 00810.h5
281
+ - 00811.h5
282
+ - 00812.h5
283
+ - 00814.h5
284
+ - 00818.h5
285
+ - 00819.h5
286
+ - 00820.h5
287
+ - 00821.h5
288
+ - 00823.h5
289
+ - 00825.h5
290
+ - 00827.h5
291
+ - 00831.h5
292
+ - 00832.h5
293
+ - 00833.h5
294
+ - 00835.h5
295
+ - 00837.h5
296
+ - 00840.h5
297
+ - 00841.h5
298
+ - 00842.h5
299
+ - 00849.h5
300
+ - 00850.h5
301
+ - 00851.h5
302
+ - 00852.h5
303
+ - 00853.h5
304
+ - 00855.h5
305
+ - 00859.h5
306
+ - 00864.h5
307
+ - 00865.h5
308
+ - 00869.h5
309
+ - 00872.h5
310
+ - 00873.h5
311
+ - 00874.h5
312
+ - 00875.h5
313
+ - 00878.h5
314
+ - 00881.h5
315
+ - 00882.h5
316
+ - 00886.h5
317
+ - 00888.h5
318
+ - 00889.h5
319
+ - 00891.h5
320
+ - 00892.h5
321
+ - 00894.h5
322
+ - 00896.h5
323
+ - 00897.h5
324
+ - 00898.h5
325
+ - 00899.h5
326
+ - 00900.h5
327
+ - 00904.h5
328
+ - 00905.h5
329
+ - 00907.h5
330
+ - 00911.h5
331
+ - 00912.h5
332
+ - 00914.h5
333
+ - 00915.h5
334
+ - 00923.h5
335
+ - 00924.h5
336
+ - 00927.h5
337
+ - 00931.h5
338
+ - 00933.h5
339
+ - 00934.h5
340
+ - 00938.h5
341
+ - 00944.h5
342
+ - 00945.h5
343
+ - 00947.h5
344
+ - 00948.h5
345
+ - 00956.h5
346
+ - 00961.h5
347
+ - 00963.h5
348
+ - 00969.h5
349
+ - 00971.h5
350
+ - 00974.h5
351
+ - 00980.h5
352
+ - 00981.h5
353
+ - 00982.h5
354
+ - 00983.h5
355
+ - 00984.h5
356
+ - 00986.h5
357
+ - 00989.h5
358
+ - 00991.h5
359
+ - 00992.h5
360
+ - 00997.h5
361
+ - 00999.h5
362
+ - 01000.h5
363
+ - 01002.h5
364
+ - 01003.h5
365
+ - 01009.h5
366
+ - 01010.h5
367
+ - 01012.h5
368
+ - 01015.h5
369
+ - 01018.h5
370
+ - 01019.h5
371
+ - 01020.h5
372
+ - 01021.h5
373
+ - 01022.h5
374
+ - 01024.h5
375
+ - 01025.h5
376
+ - 01031.h5
377
+ - 01032.h5
378
+ - 01034.h5
379
+ - 01035.h5
380
+ - 01038.h5
381
+ - 01039.h5
382
+ - 01042.h5
383
+ - 01044.h5
384
+ - 01045.h5
385
+ - 01046.h5
386
+ - 01050.h5
387
+ - 01052.h5
388
+ - 01054.h5
389
+ - 01055.h5
390
+ - 01056.h5
391
+ - 01057.h5
392
+ - 01058.h5
393
+ - 01059.h5
394
+ - 01060.h5
395
+ - 01062.h5
396
+ - 01063.h5
397
+ - 01064.h5
398
+ - 01065.h5
399
+ - 01069.h5
400
+ - 01070.h5
401
+ - 01073.h5
402
+ - 01075.h5
403
+ - 01076.h5
404
+ - 01077.h5
405
+ - 01080.h5
406
+ - 01081.h5
407
+ - 01082.h5
408
+ - 01083.h5
409
+ - 01084.h5
410
+ - 01085.h5
411
+ - 01086.h5
412
+ - 01087.h5
413
+ - 01088.h5
414
+ - 01089.h5
415
+ - 01090.h5
416
+ - 01092.h5
417
+ - 01093.h5
418
+ - 01095.h5
419
+ - 01100.h5
420
+ - 01102.h5
421
+ - 01104.h5
422
+ - 01105.h5
423
+ - 01106.h5
424
+ - 01107.h5
425
+ - 01110.h5
426
+ - 01118.h5
427
+ - 01120.h5
428
+ - 01121.h5
429
+ - 01123.h5
430
+ - 01127.h5
431
+ - 01128.h5
432
+ - 01129.h5
433
+ - 01135.h5
434
+ - 01138.h5
435
+ - 01139.h5
436
+ - 01143.h5
437
+ - 01145.h5
438
+ - 01146.h5
439
+ - 01147.h5
440
+ - 01149.h5
441
+ - 01151.h5
442
+ - 01156.h5
443
+ - 01157.h5
444
+ - 01158.h5
445
+ - 01161.h5
446
+ - 01162.h5
447
+ - 01163.h5
448
+ - 01164.h5
449
+ - 01165.h5
450
+ - 01166.h5
451
+ - 01167.h5
452
+ - 01168.h5
453
+ - 01169.h5
454
+ - 01170.h5
455
+ - 01171.h5
456
+ - 01172.h5
457
+ - 01173.h5
458
+ - 01174.h5
459
+ - 01175.h5
460
+ - 01177.h5
461
+ - 01178.h5
462
+ - 01180.h5
463
+ - 01181.h5
464
+ - 01182.h5
465
+ - 01184.h5
466
+ - 01186.h5
467
+ - 01188.h5
468
+ - 01191.h5
469
+ - 01195.h5
470
+ - 01199.h5
471
+ - 01201.h5
472
+ - 01204.h5
473
+ - 01207.h5
474
+ - 01208.h5
475
+ - 01209.h5
476
+ - 01211.h5
477
+ - 01212.h5
478
+ - 01213.h5
479
+ - 01219.h5
480
+ - 01221.h5
481
+ - 01222.h5
482
+ - 01231.h5
483
+ - 01232.h5
484
+ - 01233.h5
485
+ - 01237.h5
486
+ - 01243.h5
487
+ - 01244.h5
488
+ - 01247.h5
489
+ - 01250.h5
490
+ - 01252.h5
491
+ - 01254.h5
492
+ - 01255.h5
493
+ - 01256.h5
494
+ - 01259.h5
495
+ - 01260.h5
496
+ - 01262.h5
497
+ - 01266.h5
498
+ - 01269.h5
499
+ - 01270.h5
500
+ - 01275.h5
501
+ - 01276.h5
502
+ - 01279.h5
503
+ - 01281.h5
504
+ - 01283.h5
505
+ - 01285.h5
506
+ - 01293.h5
507
+ - 01295.h5
508
+ - 01298.h5
509
+ - 01300.h5
510
+ - 01301.h5
511
+ - 01303.h5
512
+ - 01304.h5
513
+ - 01315.h5
514
+ - 01316.h5
515
+ - 01320.h5
516
+ - 01323.h5
517
+ - 01327.h5
518
+ - 01328.h5
519
+ - 01330.h5
520
+ - 01331.h5
521
+ - 01333.h5
522
+ - 01340.h5
523
+ - 01347.h5
524
+ - 01348.h5
525
+ - 01349.h5
526
+ - 01351.h5
527
+ - 01352.h5
528
+ - 01353.h5
529
+ - 01354.h5
530
+ - 01356.h5
531
+ - 01357.h5
532
+ - 01358.h5
533
+ - 01360.h5
534
+ - 01361.h5
535
+ - 01362.h5
536
+ - 01368.h5
537
+ - 01375.h5
538
+ - 01377.h5
539
+ - 01379.h5
540
+ - 01380.h5
541
+ - 01382.h5
542
+ - 01383.h5
543
+ - 01384.h5
544
+ - 01386.h5
545
+ - 01387.h5
546
+ - 01388.h5
547
+ - 01389.h5
548
+ - 01390.h5
549
+ - 01391.h5
550
+ - 01393.h5
551
+ - 01396.h5
552
+ - 01400.h5
553
+ - 01405.h5
554
+ - 01406.h5
555
+ - 01414.h5
556
+ - 01415.h5
557
+ - 01420.h5
558
+ - 01421.h5
559
+ - 01423.h5
560
+ - 01424.h5
561
+ - 01428.h5
562
+ - 01430.h5
563
+ - 01431.h5
564
+ - 01434.h5
565
+ - 01435.h5
566
+ - 01438.h5
567
+ - 01440.h5
568
+ - 01445.h5
569
+ - 01446.h5
570
+ - 01448.h5
571
+ - 01451.h5
572
+ - 01454.h5
573
+ - 01456.h5
574
+ - 01459.h5
575
+ - 01460.h5
576
+ - 01462.h5
577
+ - 01467.h5
578
+ - 01470.h5
579
+ - 01471.h5
580
+ - 01472.h5
581
+ - 01473.h5
582
+ - 01478.h5
583
+ - 01479.h5
584
+ - 01480.h5
585
+ - 01481.h5
586
+ - 01482.h5
587
+ - 01483.h5
588
+ - 01485.h5
589
+ - 01486.h5
590
+ - 01487.h5
591
+ - 01488.h5
592
+ - 01491.h5
593
+ - 01492.h5
594
+ - 01496.h5
595
+ - 01497.h5
596
+ - 01499.h5
597
+ - 01508.h5
598
+ - 01510.h5
599
+ - 01511.h5
600
+ - 01514.h5
601
+ - 01515.h5
602
+ - 01516.h5
603
+ - 01519.h5
604
+ - 01523.h5
605
+ - 01524.h5
606
+ - 01528.h5
607
+ - 01531.h5
608
+ - 01532.h5
609
+ - 01533.h5
610
+ - 01534.h5
611
+ - 01540.h5
612
+ - 01542.h5
613
+ - 01546.h5
614
+ - 01551.h5
615
+ - 01553.h5
616
+ - 01566.h5
617
+ - 01569.h5
618
+ - 01574.h5
619
+ - 01577.h5
620
+ - 01581.h5
621
+ - 01582.h5
622
+ - 01583.h5
623
+ - 01584.h5
624
+ - 01602.h5
625
+ - 01603.h5
626
+ - 01604.h5
627
+ - 01606.h5
628
+ - 01611.h5
629
+ - 01612.h5
630
+ - 01613.h5
631
+ - 01617.h5
632
+ - 01618.h5
633
+ - 01627.h5
634
+ - 01630.h5
635
+ - 01631.h5
636
+ - 01633.h5
637
+ - 01635.h5
638
+ - 01636.h5
639
+ - 01637.h5
640
+ - 01640.h5
641
+ - 01643.h5
642
+ - 01644.h5
643
+ - 01645.h5
644
+ - 01648.h5
645
+ - 01650.h5
646
+ - 01651.h5
647
+ - 01653.h5
648
+ - 01658.h5
649
+ - 01665.h5
650
+ - 01669.h5
651
+ - 01671.h5
652
+ - 01678.h5
653
+ - 01680.h5
654
+ - 01681.h5
655
+ - 01682.h5
656
+ - 01684.h5
657
+ - 01687.h5
658
+ - 01690.h5
659
+ - 01692.h5
660
+ - 01693.h5
661
+ - 01697.h5
662
+ - 01698.h5
663
+ - 01700.h5
664
+ - 01703.h5
665
+ - 01705.h5
666
+ - 01706.h5
667
+ - 01709.h5
668
+ - 01710.h5
669
+ - 01713.h5
670
+ - 01717.h5
671
+ - 01718.h5
672
+ - 01719.h5
673
+ - 01720.h5
674
+ - 01726.h5
675
+ - 01727.h5
676
+ - 01728.h5
677
+ - 01729.h5
678
+ - 01730.h5
679
+ - 01731.h5
680
+ - 01734.h5
681
+ - 01738.h5
682
+ - 01741.h5
683
+ - 01744.h5
684
+ - 01745.h5
685
+ - 01747.h5
686
+ - 01748.h5
687
+ - 01755.h5
688
+ - 01762.h5
689
+ - 01763.h5
690
+ - 01768.h5
691
+ - 01770.h5
692
+ - 01771.h5
693
+ - 01775.h5
694
+ - 01778.h5
695
+ - 01779.h5
696
+ - 01783.h5
697
+ - 01789.h5
698
+ - 01792.h5
699
+ - 01795.h5
700
+ - 01796.h5
701
+ - 01798.h5
702
+ - 01802.h5
703
+ - 01803.h5
704
+ - 01806.h5
705
+ - 01812.h5
706
+ - 01816.h5
707
+ - 01817.h5
708
+ - 01818.h5
709
+ - 01821.h5
710
+ - 01823.h5
711
+ - 01825.h5
712
+ - 01826.h5
713
+ - 01827.h5
714
+ - 01828.h5
715
+ - 01833.h5
716
+ - 01843.h5
717
+ - 01849.h5
718
+ - 01858.h5
719
+ - 01860.h5
720
+ - 01862.h5
721
+ - 01866.h5
722
+ - 01867.h5
723
+ - 01868.h5
724
+ - 01869.h5
725
+ - 01870.h5
726
+ - 01874.h5
727
+ - 01878.h5
728
+ - 01880.h5
729
+ - 01882.h5
730
+ - 01883.h5
731
+ - 01884.h5
732
+ - 01885.h5
733
+ - 01887.h5
734
+ - 01888.h5
735
+ - 01889.h5
736
+ - 01892.h5
737
+ - 01897.h5
738
+ - 01900.h5
739
+ - 01901.h5
740
+ - 01902.h5
741
+ - 01905.h5
742
+ - 01906.h5
743
+ - 01907.h5
744
+ - 01908.h5
745
+ - 01912.h5
746
+ - 01915.h5
747
+ - 01921.h5
748
+ - 01922.h5
749
+ - 01924.h5
750
+ - 01925.h5
751
+ - 01926.h5
752
+ - 01927.h5
753
+ - 01930.h5
754
+ - 01933.h5
755
+ - 01936.h5
756
+ - 01943.h5
757
+ - 01960.h5
758
+ - 01961.h5
759
+ - 01962.h5
760
+ - 01964.h5
761
+ - 01965.h5
762
+ - 01966.h5
763
+ - 01975.h5
764
+ - 01976.h5
765
+ - 01977.h5
766
+ - 01979.h5
767
+ - 01984.h5
768
+ - 01987.h5
769
+ - 01995.h5
770
+ - 02009.h5
771
+ - 02011.h5
772
+ - 02015.h5
773
+ - 02019.h5
774
+ - 02022.h5
775
+ - 02023.h5
776
+ - 02024.h5
777
+ - 02025.h5
778
+ - 02026.h5
779
+ - 02028.h5
780
+ - 02029.h5
781
+ - 02034.h5
782
+ - 02035.h5
783
+ - 02038.h5
784
+ - 02045.h5
785
+ - 02047.h5
786
+ - 02051.h5
787
+ - 02052.h5
788
+ - 02056.h5
789
+ - 02058.h5
790
+ - 02059.h5
791
+ - 02061.h5
792
+ - 02064.h5
793
+ - 02065.h5
794
+ - 02077.h5
795
+ - 02084.h5
796
+ - 02085.h5
797
+ - 02086.h5
798
+ - 02087.h5
799
+ - 02090.h5
800
+ - 02092.h5
801
+ - 02093.h5
802
+ - 02099.h5
803
+ - 02102.h5
804
+ - 02105.h5
805
+ - 02106.h5
806
+ - 02112.h5
807
+ - 02113.h5
808
+ - 02114.h5
809
+ - 02115.h5
810
+ - 02118.h5
811
+ - 02123.h5
812
+ - 02131.h5
813
+ - 02136.h5
814
+ - 02137.h5
815
+ - 02138.h5
816
+ - 02140.h5
817
+ - 02141.h5
818
+ - 02142.h5
819
+ - 02152.h5
820
+ - 02154.h5
821
+ - 02156.h5
822
+ - 02159.h5
823
+ - 02161.h5
824
+ - 02162.h5
825
+ - 02168.h5
826
+ - 02170.h5
827
+ - 02172.h5
828
+ - 02173.h5
829
+ - 02186.h5
830
+ - 02187.h5
831
+ - 02193.h5
832
+ - 02198.h5
833
+ - 02203.h5
834
+ - 02204.h5
835
+ - 02206.h5
836
+ - 02207.h5
837
+ - 02212.h5
838
+ - 02216.h5
839
+ - 02219.h5
840
+ - 02220.h5
841
+ - 02229.h5
842
+ - 02230.h5
843
+ - 02232.h5
844
+ - 02234.h5
845
+ - 02237.h5
846
+ - 02241.h5
847
+ - 02244.h5
848
+ - 02249.h5
849
+ - 02250.h5
850
+ - 02255.h5
851
+ - 02257.h5
852
+ - 02264.h5
853
+ - 02266.h5
854
+ - 02267.h5
855
+ - 02270.h5
856
+ - 02272.h5
857
+ - 02277.h5
858
+ - 02278.h5
859
+ - 02279.h5
860
+ - 02282.h5
861
+ - 02293.h5
862
+ - 02297.h5
863
+ - 02298.h5
864
+ - 02300.h5
865
+ - 02311.h5
866
+ - 02314.h5
867
+ - 02319.h5
868
+ - 02321.h5
869
+ - 02322.h5
870
+ - 02324.h5
871
+ - 02326.h5
872
+ - 02327.h5
873
+ - 02328.h5
874
+ - 02332.h5
875
+ - 02334.h5
876
+ - 02337.h5
877
+ - 02339.h5
878
+ - 02342.h5
879
+ - 02343.h5
880
+ - 02347.h5
881
+ - 02349.h5
882
+ - 02350.h5
883
+ - 02352.h5
884
+ - 02355.h5
885
+ - 02358.h5
886
+ - 02359.h5
887
+ - 02361.h5
888
+ - 02362.h5
889
+ - 02365.h5
890
+ - 02366.h5
891
+ - 02367.h5
892
+ - 02368.h5
893
+ - 02370.h5
894
+ - 02371.h5
895
+ - 02373.h5
896
+ - 02375.h5
897
+ - 02379.h5
898
+ - 02394.h5
899
+ - 02412.h5
900
+ - 02414.h5
901
+ - 02415.h5
902
+ - 02418.h5
903
+ - 02420.h5
904
+ - 02421.h5
905
+ - 02424.h5
906
+ - 02426.h5
907
+ - 02430.h5
908
+ - 02431.h5
909
+ - 02432.h5
910
+ - 02434.h5
911
+ - 02435.h5
912
+ - 02436.h5
913
+ - 02439.h5
914
+ - 02440.h5
915
+ - 02441.h5
916
+ - 02442.h5
917
+ - 02443.h5
918
+ - 02445.h5
919
+ - 02447.h5
920
+ - 02448.h5
921
+ - 02452.h5
922
+ - 02454.h5
923
+ - 02457.h5
924
+ - 02458.h5
925
+ - 02459.h5
926
+ - 02462.h5
927
+ - 02465.h5
928
+ - 02467.h5
929
+ - 02468.h5
930
+ - 02469.h5
931
+ - 02472.h5
932
+ - 02474.h5
933
+ - 02478.h5
934
+ - 02510.h5
935
+ - 02518.h5
936
+ - 02520.h5
937
+ - 02521.h5
938
+ - 02522.h5
939
+ - 02524.h5
940
+ - 02525.h5
941
+ - 02534.h5
942
+ - 02535.h5
943
+ - 02540.h5
944
+ - 02547.h5
945
+ - 02550.h5
946
+ - 02552.h5
947
+ - 02553.h5
948
+ - 02554.h5
949
+ - 02557.h5
950
+ - 02559.h5
951
+ - 02566.h5
952
+ - 02567.h5
953
+ - 02571.h5
954
+ - 02573.h5
955
+ - 02575.h5
956
+ - 02576.h5
957
+ - 02578.h5
958
+ - 02581.h5
959
+ - 02585.h5
960
+ - 02587.h5
961
+ - 02588.h5
962
+ - 02590.h5
963
+ - 02595.h5
964
+ - 02610.h5
965
+ - 02611.h5
966
+ - 02613.h5
967
+ - 02615.h5
968
+ - 02617.h5
969
+ - 02619.h5
970
+ - 02629.h5
971
+ - 02632.h5
972
+ - 02634.h5
973
+ - 02649.h5
974
+ - 02663.h5
975
+ - 02666.h5
976
+ - 02669.h5
977
+ - 02673.h5
978
+ - 02681.h5
979
+ - 02689.h5
980
+ - 02690.h5
981
+ - 02700.h5
982
+ - 02705.h5
983
+ - 02709.h5
984
+ - 02713.h5
985
+ - 02718.h5
986
+ - 02721.h5
987
+ - 02722.h5
988
+ - 02723.h5
989
+ - 02725.h5
990
+ - 02729.h5
991
+ - 02730.h5
992
+ - 02732.h5
993
+ - 02737.h5
994
+ - 02740.h5
995
+ - 02741.h5
996
+ - 02749.h5
997
+ - 02758.h5
998
+ - 02760.h5
999
+ - 02761.h5
1000
+ - 02762.h5
1001
+ - 02763.h5
1002
+ - 02764.h5
1003
+ - 02765.h5
1004
+ - 02772.h5
1005
+ - 02773.h5
1006
+ - 02774.h5
1007
+ - 02776.h5
1008
+ - 02780.h5
1009
+ - 02781.h5
1010
+ - 02785.h5
1011
+ - 02797.h5
1012
+ - 02818.h5
1013
+ - 02819.h5
1014
+ - 02827.h5
1015
+ - 02829.h5
1016
+ - 02832.h5
1017
+ - 02837.h5
1018
+ - 02841.h5
1019
+ - 02843.h5
1020
+ - 02846.h5
1021
+ - 02847.h5
1022
+ - 02852.h5
1023
+ - 02854.h5
1024
+ - 02857.h5
1025
+ - 02868.h5
1026
+ - 02872.h5
1027
+ - 02873.h5
1028
+ - 02874.h5
1029
+ - 02876.h5
1030
+ - 02877.h5
1031
+ - 02878.h5
1032
+ - 02879.h5
1033
+ - 02880.h5
1034
+ - 02882.h5
1035
+ - 02883.h5
1036
+ - 02888.h5
1037
+ - 02898.h5
1038
+ - 02902.h5
1039
+ - 02908.h5
1040
+ - 02911.h5
1041
+ - 02919.h5
1042
+ - 02920.h5
1043
+ - 02921.h5
1044
+ - 02922.h5
1045
+ - 02924.h5
1046
+ - 02925.h5
1047
+ - 02928.h5
1048
+ - 02938.h5
1049
+ - 02941.h5
1050
+ - 02944.h5
1051
+ - 02945.h5
1052
+ - 02954.h5
1053
+ - 02955.h5
1054
+ - 02956.h5
1055
+ - 02960.h5
1056
+ - 02961.h5
1057
+ - 02964.h5
1058
+ - 02967.h5
1059
+ - 02977.h5
1060
+ - 02978.h5
1061
+ - 02979.h5
1062
+ - 02980.h5
1063
+ - 02985.h5
1064
+ - 02987.h5
1065
+ - 02988.h5
1066
+ - 02989.h5
1067
+ - 02991.h5
1068
+ - 02997.h5
1069
+ - 02998.h5
1070
+ - 03003.h5
1071
+ - 03004.h5
1072
+ - 03006.h5
1073
+ - 03009.h5
1074
+ - 03012.h5
1075
+ - 03013.h5
1076
+ - 03014.h5
1077
+ - 03023.h5
1078
+ - 03026.h5
1079
+ - 03027.h5
1080
+ - 03037.h5
1081
+ - 03042.h5
1082
+ - 03051.h5
1083
+ - 03057.h5
1084
+ - 03064.h5
1085
+ - 03065.h5
1086
+ - 03079.h5
1087
+ - 03089.h5
1088
+ - 03102.h5
1089
+ - 03107.h5
1090
+ - 03116.h5
1091
+ - 03122.h5
1092
+ - 03125.h5
1093
+ - 03130.h5
1094
+ - 03133.h5
1095
+ - 03134.h5
1096
+ - 03137.h5
1097
+ - 03139.h5
1098
+ - 03160.h5
1099
+ - 03163.h5
1100
+ - 03172.h5
1101
+ - 03174.h5
1102
+ - 03178.h5
1103
+ - 03179.h5
1104
+ - 03180.h5
1105
+ - 03188.h5
1106
+ - 03189.h5
1107
+ - 03190.h5
1108
+ - 03192.h5
1109
+ - 03193.h5
1110
+ - 03197.h5
1111
+ - 03199.h5
1112
+ - 03200.h5
1113
+ - 03205.h5
1114
+ - 03206.h5
1115
+ - 03211.h5
1116
+ - 03218.h5
1117
+ - 03219.h5
1118
+ - 03222.h5
1119
+ - 03225.h5
1120
+ - 03231.h5
1121
+ - 03246.h5
1122
+ - 03248.h5
1123
+ - 03251.h5
1124
+ - 03253.h5
1125
+ - 03255.h5
1126
+ - 03259.h5
1127
+ - 03263.h5
1128
+ - 03265.h5
1129
+ - 03266.h5
1130
+ - 03273.h5
1131
+ - 03275.h5
1132
+ - 03277.h5
1133
+ - 03278.h5
1134
+ - 03282.h5
1135
+ - 03283.h5
1136
+ - 03302.h5
1137
+ - 03303.h5
1138
+ - 03304.h5
1139
+ - 03307.h5
1140
+ - 03314.h5
1141
+ - 03315.h5
1142
+ - 03327.h5
1143
+ - 03328.h5
1144
+ - 03332.h5
1145
+ - 03336.h5
1146
+ - 03340.h5
1147
+ - 03342.h5
1148
+ - 03343.h5
1149
+ - 03348.h5
1150
+ - 03351.h5
1151
+ - 03354.h5
1152
+ - 03358.h5
1153
+ - 03359.h5
1154
+ - 03360.h5
1155
+ - 03367.h5
1156
+ - 03371.h5
1157
+ - 03374.h5
1158
+ - 03375.h5
1159
+ - 03377.h5
1160
+ - 03378.h5
1161
+ - 03379.h5
1162
+ - 03381.h5
1163
+ - 03382.h5
1164
+ - 03384.h5
1165
+ - 03397.h5
1166
+ - 03403.h5
1167
+ - 03406.h5
1168
+ - 03413.h5
1169
+ - 03425.h5
1170
+ - 03431.h5
1171
+ - 03432.h5
1172
+ - 03435.h5
1173
+ - 03442.h5
1174
+ - 03453.h5
1175
+ - 03454.h5
1176
+ - 03456.h5
1177
+ - 03463.h5
1178
+ - 03465.h5
1179
+ - 03466.h5
1180
+ - 03467.h5
1181
+ - 03469.h5
1182
+ - 03473.h5
1183
+ - 03491.h5
1184
+ - 03492.h5
1185
+ - 03495.h5
1186
+ - 03498.h5
1187
+ - 03501.h5
1188
+ - 03502.h5
1189
+
unigaze/configs/data/mpiigaze.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.mpiigaze.MPIIGazeDataset
2
+ params:
3
+ data_name: mpii
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ dataset_path: null
7
+ image_size: 224
8
+ keys_to_use:
9
+ - p00.h5
10
+ - p01.h5
11
+ - p02.h5
12
+ - p03.h5
13
+ - p04.h5
14
+ - p05.h5
15
+ - p06.h5
16
+ - p07.h5
17
+ - p08.h5
18
+ - p09.h5
19
+ - p10.h5
20
+ - p11.h5
21
+ - p12.h5
22
+ - p13.h5
23
+ - p14.h5
24
+
unigaze/configs/data/mpiigaze_test.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.mpiigaze.MPIIGazeDataset
2
+ params:
3
+ data_name: mpii
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ dataset_path: null
7
+ image_size: 224
8
+ keys_to_use:
9
+ # - p00.h5
10
+ # - p01.h5
11
+ # - p02.h5
12
+ # - p03.h5
13
+ # - p04.h5
14
+ # - p05.h5
15
+ # - p06.h5
16
+ # - p07.h5
17
+ # - p08.h5
18
+ # - p09.h5
19
+ - p10.h5
20
+ - p11.h5
21
+ - p12.h5
22
+ - p13.h5
23
+ - p14.h5
24
+
unigaze/configs/data/mpiigaze_train.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.mpiigaze.MPIIGazeDataset
2
+ params:
3
+ data_name: mpii
4
+ color_type: bgr
5
+ transform_type: 'basic_imagenet'
6
+ dataset_path: null
7
+ image_size: 224
8
+ keys_to_use:
9
+ - p00.h5
10
+ - p01.h5
11
+ - p02.h5
12
+ - p03.h5
13
+ - p04.h5
14
+ - p05.h5
15
+ - p06.h5
16
+ - p07.h5
17
+ - p08.h5
18
+ - p09.h5
19
+ # - p10.h5
20
+ # - p11.h5
21
+ # - p12.h5
22
+ # - p13.h5
23
+ # - p14.h5
24
+
unigaze/configs/data/xgaze_0_60sub.yaml ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ type: datasets.xgaze.XGazeDataset
3
+ params:
4
+ data_name: xgaze_v2_224
5
+
6
+ images_per_frame: 18
7
+ color_type: bgr
8
+ transform_type: 'basic_imagenet'
9
+ dataset_path: null
10
+ frame_tag: 'all'
11
+ image_size: 224
12
+ keys_to_use:
13
+ - subject0000.h5
14
+ - subject0003.h5
15
+ - subject0004.h5
16
+ - subject0005.h5
17
+ - subject0006.h5
18
+ - subject0007.h5
19
+ - subject0008.h5
20
+ - subject0009.h5
21
+ - subject0010.h5
22
+ - subject0013.h5
23
+ - subject0014.h5
24
+ - subject0015.h5
25
+ - subject0016.h5
26
+ - subject0018.h5
27
+ - subject0019.h5
28
+ - subject0021.h5
29
+ - subject0024.h5
30
+ - subject0026.h5
31
+ - subject0027.h5
32
+ - subject0028.h5
33
+ - subject0029.h5
34
+ - subject0030.h5
35
+ - subject0031.h5
36
+ - subject0032.h5
37
+ - subject0033.h5
38
+ - subject0035.h5
39
+ - subject0036.h5
40
+ - subject0038.h5
41
+ - subject0039.h5
42
+ - subject0040.h5
43
+ - subject0041.h5
44
+ - subject0043.h5
45
+ - subject0044.h5
46
+ - subject0045.h5
47
+ - subject0046.h5
48
+ - subject0048.h5
49
+ - subject0050.h5
50
+ - subject0051.h5
51
+ - subject0052.h5
52
+ - subject0055.h5
53
+ - subject0056.h5
54
+ - subject0057.h5
55
+ - subject0058.h5
56
+ - subject0059.h5
57
+ - subject0060.h5
58
+ - subject0061.h5
59
+ - subject0062.h5
60
+ - subject0063.h5
61
+ - subject0065.h5
62
+ - subject0066.h5
63
+ - subject0067.h5
64
+ - subject0069.h5
65
+ - subject0072.h5
66
+ - subject0073.h5
67
+ - subject0075.h5
68
+ - subject0076.h5
69
+ - subject0078.h5
70
+ - subject0079.h5
71
+ - subject0080.h5
72
+ - subject0081.h5
73
+
74
+
75
+
76
+
unigaze/configs/data/xgaze_0_60sub_d3.yaml ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ type: datasets.xgaze.XGazeDataset
3
+ params:
4
+ data_name: xgaze_v2_224
5
+
6
+ images_per_frame: 18
7
+ color_type: bgr
8
+ transform_type: 'basic_imagenet'
9
+ dataset_path: null
10
+ frame_tag: 'all'
11
+ camera_random: 3
12
+ image_size: 224
13
+
14
+
15
+
16
+ keys_to_use:
17
+ - subject0000.h5
18
+ - subject0003.h5
19
+ - subject0004.h5
20
+ - subject0005.h5
21
+ - subject0006.h5
22
+ - subject0007.h5
23
+ - subject0008.h5
24
+ - subject0009.h5
25
+ - subject0010.h5
26
+ - subject0013.h5
27
+ - subject0014.h5
28
+ - subject0015.h5
29
+ - subject0016.h5
30
+ - subject0018.h5
31
+ - subject0019.h5
32
+ - subject0021.h5
33
+ - subject0024.h5
34
+ - subject0026.h5
35
+ - subject0027.h5
36
+ - subject0028.h5
37
+ - subject0029.h5
38
+ - subject0030.h5
39
+ - subject0031.h5
40
+ - subject0032.h5
41
+ - subject0033.h5
42
+ - subject0035.h5
43
+ - subject0036.h5
44
+ - subject0038.h5
45
+ - subject0039.h5
46
+ - subject0040.h5
47
+ - subject0041.h5
48
+ - subject0043.h5
49
+ - subject0044.h5
50
+ - subject0045.h5
51
+ - subject0046.h5
52
+ - subject0048.h5
53
+ - subject0050.h5
54
+ - subject0051.h5
55
+ - subject0052.h5
56
+ - subject0055.h5
57
+ - subject0056.h5
58
+ - subject0057.h5
59
+ - subject0058.h5
60
+ - subject0059.h5
61
+ - subject0060.h5
62
+ - subject0061.h5
63
+ - subject0062.h5
64
+ - subject0063.h5
65
+ - subject0065.h5
66
+ - subject0066.h5
67
+ - subject0067.h5
68
+ - subject0069.h5
69
+ - subject0072.h5
70
+ - subject0073.h5
71
+ - subject0075.h5
72
+ - subject0076.h5
73
+ - subject0078.h5
74
+ - subject0079.h5
75
+ - subject0080.h5
76
+ - subject0081.h5
77
+
78
+
79
+
80
+
unigaze/configs/data/xgaze_0_80sub.yaml ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ type: datasets.xgaze.XGazeDataset
3
+ params:
4
+ data_name: xgaze_v2_224
5
+
6
+ images_per_frame: 18
7
+ color_type: bgr
8
+ transform_type: 'basic_imagenet'
9
+ dataset_path: null
10
+ frame_tag: 'all'
11
+ image_size: 224
12
+
13
+ keys_to_use:
14
+ - subject0000.h5
15
+ - subject0003.h5
16
+ - subject0004.h5
17
+ - subject0005.h5
18
+ - subject0006.h5
19
+ - subject0007.h5
20
+ - subject0008.h5
21
+ - subject0009.h5
22
+ - subject0010.h5
23
+ - subject0013.h5
24
+ - subject0014.h5
25
+ - subject0015.h5
26
+ - subject0016.h5
27
+ - subject0018.h5
28
+ - subject0019.h5
29
+ - subject0021.h5
30
+ - subject0024.h5
31
+ - subject0026.h5
32
+ - subject0027.h5
33
+ - subject0028.h5
34
+ - subject0029.h5
35
+ - subject0030.h5
36
+ - subject0031.h5
37
+ - subject0032.h5
38
+ - subject0033.h5
39
+ - subject0035.h5
40
+ - subject0036.h5
41
+ - subject0038.h5
42
+ - subject0039.h5
43
+ - subject0040.h5
44
+ - subject0041.h5
45
+ - subject0043.h5
46
+ - subject0044.h5
47
+ - subject0045.h5
48
+ - subject0046.h5
49
+ - subject0048.h5
50
+ - subject0050.h5
51
+ - subject0051.h5
52
+ - subject0052.h5
53
+ - subject0055.h5
54
+ - subject0056.h5
55
+ - subject0057.h5
56
+ - subject0058.h5
57
+ - subject0059.h5
58
+ - subject0060.h5
59
+ - subject0061.h5
60
+ - subject0062.h5
61
+ - subject0063.h5
62
+ - subject0065.h5
63
+ - subject0066.h5
64
+ - subject0067.h5
65
+ - subject0069.h5
66
+ - subject0072.h5
67
+ - subject0073.h5
68
+ - subject0075.h5
69
+ - subject0076.h5
70
+ - subject0078.h5
71
+ - subject0079.h5
72
+ - subject0080.h5
73
+ - subject0081.h5
74
+ - subject0083.h5
75
+ - subject0084.h5
76
+ - subject0085.h5
77
+ - subject0088.h5
78
+ - subject0090.h5
79
+ - subject0092.h5
80
+ - subject0095.h5
81
+ - subject0098.h5
82
+ - subject0099.h5
83
+ - subject0100.h5
84
+ - subject0101.h5
85
+ - subject0102.h5
86
+ - subject0103.h5
87
+ - subject0104.h5
88
+ - subject0105.h5
89
+ - subject0106.h5
90
+ - subject0107.h5
91
+ - subject0108.h5
92
+ - subject0109.h5
93
+ - subject0111.h5
94
+
95
+
96
+
97
+
unigaze/configs/data/xgaze_0_80sub_d3.yaml ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ type: datasets.xgaze.XGazeDataset
3
+ params:
4
+ data_name: xgaze_v2_224
5
+ color_type: bgr
6
+ images_per_frame: 18
7
+ transform_type: 'basic_imagenet'
8
+ dataset_path: null
9
+ frame_tag: 'all'
10
+ camera_random: 3
11
+ image_size: 224
12
+
13
+ keys_to_use:
14
+ - subject0000.h5
15
+ - subject0003.h5
16
+ - subject0004.h5
17
+ - subject0005.h5
18
+ - subject0006.h5
19
+ - subject0007.h5
20
+ - subject0008.h5
21
+ - subject0009.h5
22
+ - subject0010.h5
23
+ - subject0013.h5
24
+ - subject0014.h5
25
+ - subject0015.h5
26
+ - subject0016.h5
27
+ - subject0018.h5
28
+ - subject0019.h5
29
+ - subject0021.h5
30
+ - subject0024.h5
31
+ - subject0026.h5
32
+ - subject0027.h5
33
+ - subject0028.h5
34
+ - subject0029.h5
35
+ - subject0030.h5
36
+ - subject0031.h5
37
+ - subject0032.h5
38
+ - subject0033.h5
39
+ - subject0035.h5
40
+ - subject0036.h5
41
+ - subject0038.h5
42
+ - subject0039.h5
43
+ - subject0040.h5
44
+ - subject0041.h5
45
+ - subject0043.h5
46
+ - subject0044.h5
47
+ - subject0045.h5
48
+ - subject0046.h5
49
+ - subject0048.h5
50
+ - subject0050.h5
51
+ - subject0051.h5
52
+ - subject0052.h5
53
+ - subject0055.h5
54
+ - subject0056.h5
55
+ - subject0057.h5
56
+ - subject0058.h5
57
+ - subject0059.h5
58
+ - subject0060.h5
59
+ - subject0061.h5
60
+ - subject0062.h5
61
+ - subject0063.h5
62
+ - subject0065.h5
63
+ - subject0066.h5
64
+ - subject0067.h5
65
+ - subject0069.h5
66
+ - subject0072.h5
67
+ - subject0073.h5
68
+ - subject0075.h5
69
+ - subject0076.h5
70
+ - subject0078.h5
71
+ - subject0079.h5
72
+ - subject0080.h5
73
+ - subject0081.h5
74
+ - subject0083.h5
75
+ - subject0084.h5
76
+ - subject0085.h5
77
+ - subject0088.h5
78
+ - subject0090.h5
79
+ - subject0092.h5
80
+ - subject0095.h5
81
+ - subject0098.h5
82
+ - subject0099.h5
83
+ - subject0100.h5
84
+ - subject0101.h5
85
+ - subject0102.h5
86
+ - subject0103.h5
87
+ - subject0104.h5
88
+ - subject0105.h5
89
+ - subject0106.h5
90
+ - subject0107.h5
91
+ - subject0108.h5
92
+ - subject0109.h5
93
+ - subject0111.h5
94
+
95
+
96
+
97
+
unigaze/configs/data/xgaze_60_80sub.yaml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type: datasets.xgaze.XGazeDataset
2
+ params:
3
+ data_name: xgaze_v2_224
4
+ images_per_frame: 18
5
+ color_type: bgr
6
+ transform_type: 'basic_imagenet'
7
+ dataset_path: null
8
+ frame_tag: 'all'
9
+ image_size: 224
10
+ keys_to_use:
11
+ - subject0083.h5
12
+ - subject0084.h5
13
+ - subject0085.h5
14
+ - subject0088.h5
15
+ - subject0090.h5
16
+ - subject0092.h5
17
+ - subject0095.h5
18
+ - subject0098.h5
19
+ - subject0099.h5
20
+ - subject0100.h5
21
+ - subject0101.h5
22
+ - subject0102.h5
23
+ - subject0103.h5
24
+ - subject0104.h5
25
+ - subject0105.h5
26
+ - subject0106.h5
27
+ - subject0107.h5
28
+ - subject0108.h5
29
+ - subject0109.h5
30
+ - subject0111.h5
31
+
unigaze/configs/exp/blank.yaml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+
4
+
5
+ exp_name: tbd
6
+
7
+
8
+ exp_explanation:
9
+
10
+ data: null
11
+
12
+ ## can be overwritten
13
+ model: null
14
+
15
+
16
+ trainer: null
17
+ loss: null
18
+
19
+
20
+ optimizer: configs/optimizers/default_Adam_e4.yaml
21
+ scheduler: configs/schedulers/default_stepLR_5.yaml
22
+
unigaze/configs/exp/cross/train_ED.yaml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+
4
+ train:
5
+ - configs/data/eyediap_cs.yaml
6
+ - configs/data/eyediap_ft.yaml
7
+
8
+
9
+
10
+ val:
11
+
12
+ - configs/data/mpiigaze_train.yaml
13
+ - configs/data/mpiigaze_test.yaml
14
+
15
+
16
+ test:
17
+ # - configs/data/xgaze_0_80sub.yaml
18
+ - configs/data/xgaze_0_60sub.yaml
19
+ - configs/data/xgaze_60_80sub.yaml
20
+
21
+ - configs/data/gazecapture_train.yaml
22
+ - configs/data/gazecapture_test.yaml
23
+ - configs/data/gaze360_train.yaml
24
+ - configs/data/gaze360_test.yaml
25
+
26
+ - configs/data/mpiigaze.yaml
27
+ - configs/data/our_mpii.yaml