Download src/data/preprocess_gaze360.py from thanhhuyvan/Gaze-LIPE: direct link, hf CLI and curl.
- Browser
- Download file 4.47 kB
-
https://huggingface.co/thanhhuyvan/Gaze-LIPE/resolve/main/src/data/preprocess_gaze360.py
- Command line
-
hf download hf://thanhhuyvan/Gaze-LIPE/src/data/preprocess_gaze360.py
-
curl -L -o preprocess_gaze360.py https://huggingface.co/thanhhuyvan/Gaze-LIPE/resolve/main/src/data/preprocess_gaze360.py
4.47 kB
| import os | |
| import cv2 | |
| import numpy as np | |
| import h5py | |
| import scipy.io | |
| from tqdm import tqdm | |
| import sys | |
| from pathlib import Path | |
| # Add src to path | |
| sys.path.append(str(Path(__file__).parent.parent.parent)) | |
| from src.utils.preprocess import GazePreprocessor | |
| def process_gaze360_subset(mat_path, img_root, output_path, rec_idx=6, patch_size=16): | |
| print(f"Loading metadata from {mat_path}...") | |
| mat = scipy.io.loadmat(mat_path) | |
| recording_indices = mat['recording'].flatten() | |
| mask = (recording_indices == rec_idx) | |
| indices = np.where(mask)[0] | |
| print(f"Found {len(indices)} potential samples in recording {rec_idx}") | |
| preprocessor = GazePreprocessor() | |
| # Get recording name | |
| rec_name = mat['recordings'][0, rec_idx][0] | |
| os.makedirs(os.path.dirname(output_path), exist_ok=True) | |
| with h5py.File(output_path, 'w') as h5f: | |
| # Datasets | |
| left_patches_ds = h5f.create_dataset('left_patches', (0, 4, patch_size, patch_size), maxshape=(None, 4, patch_size, patch_size), dtype='uint8', compression='gzip') | |
| right_patches_ds = h5f.create_dataset('right_patches', (0, 4, patch_size, patch_size), maxshape=(None, 4, patch_size, patch_size), dtype='uint8', compression='gzip') | |
| # We store person's gaze as both left and right for compatibility | |
| gaze_ds = h5f.create_dataset('gaze', (0, 2), maxshape=(None, 2), dtype='float32') | |
| landmarks_ds = h5f.create_dataset('landmarks', (0, 478, 2), maxshape=(None, 478, 2), dtype='float32') | |
| sample_idx = 0 | |
| for i in tqdm(indices, desc="Processing Gaze360"): | |
| person_id = mat['person_identity'][0, i] | |
| frame_num = mat['frame'][0, i] | |
| gaze_3d = mat['gaze_dir'][i] # (3,) | |
| # Construct path | |
| img_path = os.path.join(img_root, rec_name, 'head', f'{person_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(frame) | |
| if landmarks is None: | |
| continue | |
| # 1. Landmarks (Centered) | |
| landmarks_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 = landmarks_arr - face_center | |
| # 2. Eye Patches | |
| try: | |
| # We use Left Eye for normalizing the 3D gaze (assuming they are close) | |
| # In a more precise setup, we'd do it for each eye. | |
| left_eye_img, left_angle = preprocessor.normalize_eye(frame, landmarks, 'left') | |
| left_patches = preprocessor.extract_patches(left_eye_img, patch_size=patch_size) | |
| right_eye_img, right_angle = preprocessor.normalize_eye(frame, landmarks, 'right') | |
| right_patches = preprocessor.extract_patches(right_eye_img, patch_size=patch_size) | |
| # Rotate Gaze (Using average angle or just left eye's angle) | |
| 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) # (pitch, yaw) | |
| # Store | |
| for ds, data in zip([left_patches_ds, right_patches_ds, gaze_ds, landmarks_ds], | |
| [left_patches, right_patches, gaze_rad, landmarks_centered]): | |
| ds.resize((sample_idx + 1, *ds.shape[1:])) | |
| ds[sample_idx] = data | |
| sample_idx += 1 | |
| except Exception as e: | |
| # print(f"Error processing frame: {e}") | |
| continue | |
| print(f"\nFinished! Processed {sample_idx} samples. Saved to {output_path}") | |
| if __name__ == "__main__": | |
| process_gaze360_subset( | |
| mat_path='data/raw/metadata.mat', | |
| img_root='data/raw/imgs', | |
| output_path='data/processed/gaze360_v16.h5', | |
| rec_idx=6, | |
| patch_size=16 | |
| ) | |