How do I wrap my own recordings?#
If you have your own recordings on disk and want to make use of Tonic for quick dataloading and applying transformations, then you can wrap them in a custom class.
The easiest option is to make use of a torchvision DatasetFolder class. If that doesn’t apply in your case, you can write your own class, where you provide a minimum set of methods __init__
, __getitem__
and __len__
and you are good to go. This notebook is about a template class that reads event recordings from local numpy files. We’ll start by creating some dummy files.
import numpy as np
from tonic import Dataset, transforms
sensor_size = (200, 100, 2)
n_recordings = 10
def create_random_input(
sensor_size=sensor_size,
n_events=10000,
dtype=np.dtype([("x", int), ("y", int), ("t", int), ("p", int)]),
):
events = np.zeros(n_events, dtype=dtype)
events["x"] = np.random.rand(n_events) * sensor_size[0]
events["y"] = np.random.rand(n_events) * sensor_size[1]
events["p"] = np.random.rand(n_events) * sensor_size[2]
events["t"] = np.sort(np.random.rand(n_events) * 1e6)
return events
[
np.save(f"../tutorials/data/recording{i}.npy", create_random_input())
for i in range(n_recordings)
];
class MyRecordings(Dataset):
sensor_size = (
200,
100,
2,
) # the sensor size of the event camera or the number of channels of the silicon cochlear that was used
ordering = (
"xytp" # the order in which your event channels are provided in your recordings
)
def __init__(
self,
train=True,
transform=None,
target_transform=None,
):
super(MyRecordings, self).__init__(
save_to='./', transform=transform, target_transform=target_transform
)
self.train = train
# replace the strings with your training/testing file locations or pass as an argument
if train:
self.filenames = [
f"../tutorials/data/recording{i}.npy" for i in range(n_recordings)
]
else:
raise NotImplementedError
def __getitem__(self, index):
events = np.load(self.filenames[index])
if self.transform is not None:
events = self.transform(events)
return events
def __len__(self):
return len(self.filenames)
Depending on the format of your recording files, your implementation might look a bit different. Oftentimes you will have a separate file for each recording. Or you might want to also load some image or IMU data. You can have a look at already existing datasets for some inspiration. :class:DVSGesture
loads from multiple numpy files, :class:DAVISDATA
or :class:VPR
load events and other data from rosbag files, :class:NCARS
loads eventstream files and :class:ASLDVS
reads from matlab files.
Afterwards you can call certain samples from the dataset or use a DataLoader wrapper, which will make use of __getitem__
and __len__
functions internally.
dataset = MyRecordings(train=True, transform=transforms.NumpyAsType(int))
events = dataset[5]
import torch
dataloader = torch.utils.data.DataLoader(dataset, shuffle=True)
events = next(iter(dataloader))
print(events)
tensor([[[ 196, 59, 71, 1],
[ 6, 34, 74, 1],
[ 12, 90, 238, 0],
...,
[ 158, 74, 999640, 1],
[ 167, 7, 999838, 0],
[ 199, 84, 999989, 0]]])