sid385 commited on
Commit
1abfecb
·
1 Parent(s): 0182276

feat: add dataset and transforms for TIR triplets

Browse files
src/data/dataset.py CHANGED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import torch
4
+ from torch.utils.data import Dataset
5
+
6
+ from src.data.transforms import augment_triplet
7
+
8
+
9
+ class GOESTripletDataset(Dataset):
10
+ """PyTorch Dataset for loading pre-processed Satellite TIR triplets.
11
+
12
+ Expects data to be stored as `.pt` files containing tensors of shape [3, 1, H, W],
13
+ representing Past, Present, and Future Brightness Temperature frames.
14
+ """
15
+
16
+ def __init__(self, data_dir: str, augment: bool = True):
17
+ self.data_dir = data_dir
18
+ self.augment = augment
19
+ self.triplet_files = sorted(
20
+ [f for f in os.listdir(data_dir) if f.endswith(".pt")]
21
+ )
22
+
23
+ def __len__(self) -> int:
24
+ return len(self.triplet_files)
25
+
26
+ def __getitem__(self, idx: int) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
27
+ file_path = os.path.join(self.data_dir, self.triplet_files[idx])
28
+ triplet = torch.load(file_path) # [3, 1, H, W]
29
+
30
+ img0 = triplet[0] # Past
31
+ gt = triplet[1] # Ground Truth / Present
32
+ img1 = triplet[2] # Future
33
+
34
+ if self.augment:
35
+ img0, img1, gt = augment_triplet(img0, img1, gt)
36
+
37
+ return img0, img1, gt
src/data/transformes.py CHANGED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ import torch
4
+ import torchvision.transforms.functional as TF
5
+
6
+
7
+ def augment_triplet(img0: torch.Tensor, img1: torch.Tensor, gt: torch.Tensor, crop_size: int = 256) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
8
+ """Applies identical spatial augmentations to all three frames in a triplet.
9
+
10
+ Ensures that the cloud motions remain physically consistent across the temporal sequence.
11
+
12
+ Args:
13
+ img0: Past frame tensor [C, H, W]
14
+ img1: Future frame tensor [C, H, W]
15
+ gt: Ground truth intermediate frame tensor [C, H, W]
16
+ crop_size: Final output dimension for height and width.
17
+
18
+ Returns:
19
+ Tuple of augmented tensors (img0, img1, gt).
20
+ """
21
+ _, h, w = img0.shape
22
+
23
+ # Random Spatial Cropping
24
+ top = random.randint(0, h - crop_size)
25
+ left = random.randint(0, w - crop_size)
26
+
27
+ img0 = TF.crop(img0, top, left, crop_size, crop_size)
28
+ img1 = TF.crop(img1, top, left, crop_size, crop_size)
29
+ gt = TF.crop(gt, top, left, crop_size, crop_size)
30
+
31
+ # Random Horizontal Flip
32
+ if random.random() > 0.5:
33
+ img0 = TF.hflip(img0)
34
+ img1 = TF.hflip(img1)
35
+ gt = TF.hflip(gt)
36
+
37
+ # Random Vertical Flip
38
+ if random.random() > 0.5:
39
+ img0 = TF.vflip(img0)
40
+ img1 = TF.vflip(img1)
41
+ gt = TF.vflip(gt)
42
+
43
+ # Random Dihedral Transformations
44
+ angles = [0, 90, 180, 270]
45
+ angle = random.choice(angles)
46
+ if angle > 0:
47
+ img0 = TF.rotate(img0, angle)
48
+ img1 = TF.rotate(img1, angle)
49
+ gt = TF.rotate(gt, angle)
50
+
51
+ return img0, img1, gt
tests/test_dataset.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import pytest
3
+ from src.data.transforms import augment_triplet
4
+ from src.data.dataset import GOESTripletDataset
5
+
6
+ def test_dataset(tmp_path):
7
+ # Setup mock data
8
+ tensor_data = torch.zeros((3, 1, 512, 512))
9
+ torch.save(tensor_data, tmp_path / "triplet_001.pt")
10
+
11
+ dataset = GOESTripletDataset(str(tmp_path), augment=False)
12
+ assert len(dataset) == 1
13
+
14
+ img0, img1, gt = dataset[0]
15
+ assert img0.shape == (1, 512, 512)
16
+ assert gt.shape == (1, 512, 512)
17
+
18
+ def test_augment_triplet():
19
+ img0 = torch.zeros((1, 512, 512))
20
+ img1 = torch.zeros((1, 512, 512))
21
+ gt = torch.zeros((1, 512, 512))
22
+
23
+ a_img0, a_img1, a_gt = augment_triplet(img0, img1, gt, crop_size=256)
24
+ assert a_img0.shape == (1, 256, 256)