| import os |
| import cv2 |
| import numpy as np |
| import h5py |
| import scipy.io |
| from tqdm import tqdm |
| import sys |
| from pathlib import Path |
|
|
| |
| sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) |
| from src.utils.preprocess import GazePreprocessor |
|
|
| class RobustGazePreprocessor(GazePreprocessor): |
| def get_landmarks_robust(self, frame): |
| rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) |
| landmarks = self.get_landmarks(frame) |
| if landmarks: return landmarks |
| return None |
|
|
| def create_unseen_split(): |
| mat_path = 'data/raw/metadata.mat' |
| img_root = 'data/raw/imgs' |
| output_path = 'data/processed/gaze360_unseen_verification.h5' |
| |
| |
| |
| |
| UNSEEN_IDS = [0, 1, 17, 25, 49, 61] |
| REC_IDX = 6 |
| patch_size = 16 |
|
|
| print(f"Loading metadata and selecting unseen IDs: {UNSEEN_IDS}") |
| mat = scipy.io.loadmat(mat_path) |
| rec_indices = mat['recording'].flatten() |
| person_ids = mat['person_identity'].flatten() |
| |
| mask = (rec_indices == REC_IDX) & np.isin(person_ids, UNSEEN_IDS) |
| indices = np.where(mask)[0] |
| rec_name = mat['recordings'][0, REC_IDX][0] |
| |
| preprocessor = RobustGazePreprocessor() |
| os.makedirs('data/processed', exist_ok=True) |
|
|
| with h5py.File(output_path, 'w') as h5f: |
| lp_ds = h5f.create_dataset('left_patches', (0, 4, patch_size, patch_size), maxshape=(None, 4, patch_size, patch_size), dtype='uint8', compression='gzip') |
| rp_ds = h5f.create_dataset('right_patches', (0, 4, patch_size, patch_size), maxshape=(None, 4, patch_size, patch_size), dtype='uint8', compression='gzip') |
| gaze_ds = h5f.create_dataset('gaze', (0, 2), maxshape=(None, 2), dtype='float32') |
| lm_ds = h5f.create_dataset('landmarks', (0, 478, 2), maxshape=(None, 478, 2), dtype='float32') |
| |
| count = 0 |
| for i in tqdm(indices, desc="Preprocessing Unseen Subjects"): |
| p_id = person_ids[i] |
| frame_num = mat['frame'][0, i] |
| gaze_3d = mat['gaze_dir'][i] |
| |
| img_path = os.path.join(img_root, rec_name, 'head', f'{p_id:06d}', f'{frame_num:06d}.jpg') |
| if not os.path.exists(img_path): continue |
| |
| frame = cv2.imread(img_path) |
| if frame is None: continue |
| |
| landmarks = preprocessor.get_landmarks_robust(frame) |
| if landmarks is None: continue |
|
|
| try: |
| |
| left_eye_img, left_angle = preprocessor.normalize_eye(frame, landmarks, 'left', method='new') |
| left_patches = preprocessor.extract_patches(left_eye_img, patch_size=patch_size) |
| |
| right_eye_img, right_angle = preprocessor.normalize_eye(frame, landmarks, 'right', method='new') |
| right_patches = preprocessor.extract_patches(right_eye_img, patch_size=patch_size) |
| |
| |
| avg_angle = (left_angle + right_angle) / 2 |
| gaze_rot = preprocessor.rotate_gaze(gaze_3d, avg_angle) |
| gaze_rad = preprocessor.gaze_3d_to_mag(gaze_rot) |
|
|
| |
| lms_arr = np.array([[lm.x, lm.y] for lm in landmarks]) |
| left_c = np.mean([[landmarks[idx].x, landmarks[idx].y] for idx in preprocessor.LEFT_CORNERS], axis=0) |
| right_c = np.mean([[landmarks[idx].x, landmarks[idx].y] for idx in preprocessor.RIGHT_CORNERS], axis=0) |
| face_center = (left_c + right_c) / 2 |
| landmarks_centered = lms_arr - face_center |
|
|
| |
| lp_ds.resize((count + 1, 4, patch_size, patch_size)) |
| lp_ds[count] = left_patches |
| rp_ds.resize((count + 1, 4, patch_size, patch_size)) |
| rp_ds[count] = right_patches |
| gaze_ds.resize((count + 1, 2)) |
| gaze_ds[count] = gaze_rad |
| lm_ds.resize((count + 1, 478, 2)) |
| lm_ds[count] = landmarks_centered |
| |
| count += 1 |
| except: |
| continue |
|
|
| print(f"\nDone! Created {output_path} with {count} samples.") |
|
|
| if __name__ == "__main__": |
| create_unseen_split() |
|
|