[io] io class for reading dlc h5 data files
This commit is contained in:
parent
ae277ce8fb
commit
2593f21f3a
0
etrack/io/__init__.py
Normal file
0
etrack/io/__init__.py
Normal file
78
etrack/io/dlc_data.py
Normal file
78
etrack/io/dlc_data.py
Normal file
@ -0,0 +1,78 @@
|
||||
import os
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import numbers as nb
|
||||
|
||||
from ..tracking_data import TrackingData
|
||||
|
||||
|
||||
class DLCReader(object):
|
||||
|
||||
def __init__(self, results_file, crop=(0, 0)) -> None:
|
||||
"""
|
||||
If the video data was cropped before tracking and the tracked positions are with respect to the cropped images, we may want to correct for this to convert the data back to absolute positions in the video frame.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
crop : 2-tuple
|
||||
tuple of (xoffset, yoffset)
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError if crop value is not a 2-tuple
|
||||
"""
|
||||
if not os.path.exists(results_file):
|
||||
raise ValueError("File %s does not exist!" % results_file)
|
||||
if not isinstance(crop, tuple) or len(crop) < 2:
|
||||
raise ValueError("Cropping info must be a 2-tuple of (x, y)")
|
||||
self._file_name = results_file
|
||||
self._crop = crop
|
||||
self._data_frame = pd.read_hdf(results_file)
|
||||
self._level_shape = self._data_frame.columns.levshape
|
||||
self._scorer = self._data_frame.columns.levels[0].values
|
||||
self._bodyparts = self._data_frame.columns.levels[1].values if self._level_shape[1] > 0 else []
|
||||
self._positions = self._data_frame.columns.levels[2].values if self._level_shape[2] > 0 else []
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
return self._file_name
|
||||
|
||||
@property
|
||||
def dataframe(self):
|
||||
return self._data_frame
|
||||
|
||||
@property
|
||||
def scorer(self):
|
||||
return self._scorer
|
||||
|
||||
@property
|
||||
def bodyparts(self):
|
||||
return self._bodyparts
|
||||
|
||||
def _correct_cropping(self, orgx, orgy):
|
||||
x = orgx + self._crop[0]
|
||||
y = orgy + self._crop[1]
|
||||
return x, y
|
||||
|
||||
def track(self, scorer=0, bodypart=0, framerate=30):
|
||||
if isinstance(scorer, nb.Number):
|
||||
sc = self._scorer[scorer]
|
||||
elif isinstance(scorer, str) and scorer in self._scorer:
|
||||
sc = scorer
|
||||
else:
|
||||
raise ValueError(f"Scorer {scorer} is not in dataframe!")
|
||||
if isinstance(bodypart, nb.Number):
|
||||
bp = self._bodyparts[bodypart]
|
||||
elif isinstance(bodypart, str) and bodypart in self._bodyparts:
|
||||
bp = bodypart
|
||||
else:
|
||||
raise ValueError(f"Body part {bodypart} is not in dataframe!")
|
||||
|
||||
x = np.asarray(self._data_frame[sc][bp]["x"] if "x" in self._positions else [])
|
||||
y = np.asarray(self._data_frame[sc][bp]["y"] if "y" in self._positions else [])
|
||||
x, y = self._correct_cropping(x, y)
|
||||
l = np.asarray(self._data_frame[sc][bp]["likelihood"] if "likelihood" in self._positions else [])
|
||||
|
||||
time = np.arange(len(x))/framerate
|
||||
|
||||
return TrackingData(x, y, time, l, bp, fps=framerate)
|
Loading…
Reference in New Issue
Block a user