Source code for bob.bio.video.utils.FrameContainer

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :

import bob.bio.base
import numpy

import logging
logger = logging.getLogger("bob.bio.video")

[docs]class FrameContainer: """A class for reading, manipulating and saving video content. """ def __init__(self, hdf5 = None, load_function = bob.bio.base.load): self._frames = [] if hdf5 is not None: self.load(hdf5, load_function) def __len__(self): return len(self._frames) def __iter__(self): """Generator that returns the 3-tuple (frame_id, data, quality) for each frame.""" # don't sort for frame in self._frames: yield frame def __getitem__(self, i): """Indexer (mostly used in tests).""" return self._frames[i]
[docs] def add(self, frame_id, frame, quality = None): """Adds the frame with the given id and the given quality.""" self._frames.append((str(frame_id), frame, quality))
[docs] def load(self, hdf5, load_function = bob.bio.base.load): self._frames = [] # Read content (frames) from HDF5File for path in hdf5.sub_groups(relative=True, recursive=False): # extract frame_id if path[:6] == 'Frame_': frame_id = str(path[6:]) hdf5.cd(path) # Read data data = load_function(hdf5) # read quality, if present quality = hdf5.read("FrameQuality") if hdf5.has_key("FrameQuality") else None self.add(frame_id, data, quality) hdf5.cd("..") if not len(self): raise IOError("Could not load data as a Frame Container from file %s" % hdf5.filename)
[docs] def save(self, hdf5, save_function = bob.bio.base.save): """ Save the content to the given HDF5 File. The contained data will be written using the given save_function.""" if not len(self): logger.warn("Saving empty FrameContainer '%s'", hdf5.filename) for frame_id, data, quality in self: hdf5.create_group("Frame_%s" % frame_id) hdf5.cd("Frame_%s" % frame_id) save_function(data, hdf5) if quality is not None: hdf5.set("FrameQuality", quality) hdf5.cd("..")
[docs] def is_similar_to(self, other): if len(self) != len(other): return False for a,b in zip(self, other): if a[0] != b[0]: return False if abs(a[2] - b[2]) > 1e-8: return False if not numpy.allclose(a[1], b[1]): return False return True
[docs] def as_array(self): """Returns the data of frames as a numpy array. Returns ------- numpy.ndarray The frames are returned as an array with the shape of (n_frames, ...) like a video. """ def _reader(frame): # Each frame is assumed to be an image here. We make it a single frame # video here by expanding its dimensions. This way it can be used with # the vstack_features function. return frame[1][None, ...] return bob.bio.base.vstack_features(_reader, self._frames, same_size=True)
[docs]def save_compressed(frame_container, filename, save_function, create_link=True): hdf5 = bob.bio.base.open_compressed(filename, 'w') frame_container.save(hdf5, save_function) bob.bio.base.close_compressed(filename, hdf5, create_link=create_link) del hdf5
[docs]def load_compressed(filename, load_function): hdf5 = bob.bio.base.open_compressed(filename, 'r') fc = FrameContainer(hdf5, load_function) bob.bio.base.close_compressed(filename, hdf5) del hdf5 return fc