Commit a48e947b authored by Tiago de Freitas Pereira's avatar Tiago de Freitas Pereira
Browse files

Merge branch 'issue-8-remove-database-configuration' into 'master'

Issue 8 remove database configuration



See merge request !1
parents 5c565d4a dacf30d8
Pipeline #3737 passed with stages
in 107 minutes and 11 seconds
......@@ -2,7 +2,7 @@ from .utils import *
from . import preprocessor
from . import extractor
from . import algorithm
from . import database
Please register or sign in to reply
from . import test
def get_config():
......
#!/usr/bin/env python
from bob.bio.video.database import MobioBioDatabase
mobio_video_directory = "[YOUR_MOBIO_VIDEO_DIRECTORY]"
database = MobioBioDatabase(
original_directory=mobio_video_directory,
original_extension=".mp4",
protocol='male',
models_depend_on_protocol=True,
all_files_options={'subworld': 'twothirds-subsampled'},
extractor_training_options={'subworld': 'twothirds-subsampled'},
projector_training_options={'subworld': 'twothirds-subsampled'},
enroller_training_options={'subworld': 'twothirds-subsampled'},
)
#!/usr/bin/env python
from bob.bio.video.database import YoutubeBioDatabase
youtube_directory = "[YOUR_YOUTUBE_DIRECTORY]"
database = YoutubeBioDatabase(
original_directory=youtube_directory,
protocol='fold1',
models_depend_on_protocol=True,
training_depends_on_protocol=True,
all_files_options={'subworld': 'fivefolds'},
extractor_training_options={'subworld': 'fivefolds'},
projector_training_options={'subworld': 'fivefolds'},
enroller_training_options={'subworld': 'fivefolds'},
)
from .database import VideoBioFile
from .mobio import MobioBioDatabase
from .youtube import YoutubeBioDatabase
# gets sphinx autodoc done right - don't remove it
__all__ = [_ for _ in dir() if not _.startswith('_')]
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
# Wed 20 July 14:43:22 CEST 2016
"""
Verification API for bob.db.voxforge
"""
from bob.bio.base.database.file import BioFile
from bob.bio.video.utils.FrameSelector import FrameSelector
class VideoBioFile(BioFile):
def __init__(self, client_id, path, file_id):
"""
Initializes this File object with an File equivalent for
VoxForge database.
"""
super(VideoBioFile, self).__init__(client_id=client_id, path=path, file_id=file_id)
def load(self, directory=None, extension='.avi'):
return FrameSelector()(self.make_path(directory, extension))
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Amir Mohammadi <amir.mohammadi@idiap.ch>
# Wed 13 Jul 16:43:22 CEST 2016
"""
MOBIO database implementation of bob.bio.base.database.ZTDatabase interface.
It is an extension of an SQL-based database interface, which directly talks to Mobio database, for
verification experiments (good to use in bob.bio.base framework).
"""
from .database import VideoBioFile
from bob.bio.base.database import ZTBioDatabase, BioFile
class MobioBioDatabase(ZTBioDatabase):
"""
Implements verification API for querying Mobio database.
"""
def __init__(
self,
**kwargs
):
# call base class constructors to open a session to the database
super(MobioBioDatabase, self).__init__(name='mobio',
**kwargs)
from bob.db.mobio.query import Database as LowLevelDatabase
self.__db = LowLevelDatabase()
def model_ids_with_protocol(self, groups=None, protocol=None, gender=None):
return self.__db.model_ids(groups=groups, protocol=protocol, gender=gender)
def tmodel_ids_with_protocol(self, protocol=None, groups=None, **kwargs):
return self.__db.tmodel_ids(protocol=protocol, groups=groups, **kwargs)
def objects(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs):
retval = self.__db.objects(groups=groups, protocol=protocol, purposes=purposes, model_ids=model_ids, **kwargs)
return [VideoBioFile(f) for f in retval]
def tobjects(self, groups=None, protocol=None, model_ids=None, **kwargs):
retval = self.__db.tobjects(groups=groups, protocol=protocol, model_ids=model_ids, **kwargs)
return [VideoBioFile(f) for f in retval]
def zobjects(self, groups=None, protocol=None, **kwargs):
retval = self.__db.zobjects(groups=groups, protocol=protocol, **kwargs)
return [VideoBioFile(f) for f in retval]
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
# Sat 20 Aug 15:43:10 CEST 2016
"""
YOUTUBE database implementation of bob.bio.base.database.ZTDatabase interface.
It is an extension of an SQL-based database interface, which directly talks to YOUTUBE database, for
verification experiments (good to use in bob.bio.base framework).
"""
from .database import VideoBioFile
from bob.bio.base.database import ZTBioDatabase, BioFile
from bob.bio.video.utils import FrameContainer
import os
import bob.io.base
class YoutubeBioFile(VideoBioFile):
def load(self, directory=None, extension='.jpg'):
files = sorted(os.listdir(self.make_path(directory, '')))
fc = FrameContainer()
for f in files:
if extension == os.path.splitext(f)[1]:
file_name = os.path.join(self.make_path(directory, ''), f)
fc.add(os.path.basename(file_name), bob.io.base.load(file_name))
return fc
class YoutubeBioDatabase(ZTBioDatabase):
"""
Implements verification API for querying Youtube database.
"""
def __init__(
self,
**kwargs
):
# call base class constructors to open a session to the database
super(YoutubeBioDatabase, self).__init__(name='youtube',
**kwargs)
from bob.db.youtube.query import Database as LowLevelDatabase
self.__db = LowLevelDatabase()
def model_ids_with_protocol(self, groups=None, protocol=None, **kwargs):
return self.__db.model_ids(groups=groups, protocol=protocol)
def tmodel_ids_with_protocol(self, protocol=None, groups=None, **kwargs):
return self.__db.tmodel_ids(protocol=protocol, groups=groups, **kwargs)
def objects(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs):
retval = self.__db.objects(groups=groups, protocol=protocol, purposes=purposes, model_ids=model_ids, **kwargs)
return [YoutubeBioFile(client_id=f.client_id, path=f.path, file_id=f.id) for f in retval]
def tobjects(self, groups=None, protocol=None, model_ids=None, **kwargs):
retval = self.__db.tobjects(groups=groups, protocol=protocol, model_ids=model_ids, **kwargs)
return [YoutubeBioFile(client_id=f.client_id, path=f.path, file_id=f.id) for f in retval]
def zobjects(self, groups=None, protocol=None, **kwargs):
retval = self.__db.zobjects(groups=groups, protocol=protocol, **kwargs)
return [YoutubeBioFile(client_id=f.client_id, path=f.path, file_id=f.id) for f in retval]
......@@ -2,195 +2,174 @@
# vim: set fileencoding=utf-8 :
import bob.bio.base
import numpy
import glob
import os
import bob.io.base
from .. import utils
class Wrapper (bob.bio.base.preprocessor.Preprocessor):
"""Wrapper class to run image preprocessing algorithms on video data.
This class provides functionality to read original video data from several databases.
So far, the video content from :py:class:`bob.db.mobio` and the image list content from :py:class:`bob.db.youtube` are supported.
class Wrapper(bob.bio.base.preprocessor.Preprocessor):
"""Wrapper class to run image preprocessing algorithms on video data.
Furthermore, frames are extracted from these video data, and a ``preprocessor`` algorithm is applied on all selected frames.
The preprocessor can either be provided as a registered resource, i.e., one of :ref:`bob.bio.face.preprocessors`, or an instance of a preprocessing class.
Since most of the databases do not provide annotations for all frames of the videos, commonly the preprocessor needs to apply face detection.
This class provides functionality to read original video data from several databases.
So far, the video content from :py:class:`bob.db.mobio` and the image list content from :py:class:`bob.db.youtube` are supported.
The ``frame_selector`` can be chosen to select some frames from the video.
By default, a few frames spread over the whole video sequence are selected.
Furthermore, frames are extracted from these video data, and a ``preprocessor`` algorithm is applied on all selected frames.
The preprocessor can either be provided as a registered resource, i.e., one of :ref:`bob.bio.face.preprocessors`, or an instance of a preprocessing class.
Since most of the databases do not provide annotations for all frames of the videos, commonly the preprocessor needs to apply face detection.
The ``quality_function`` is used to assess the quality of the frame.
If no ``quality_function`` is given, the quality is based on the face detector, or simply left as ``None``.
So far, the quality of the frames are not used, but it is foreseen to select frames based on quality.
The ``frame_selector`` can be chosen to select some frames from the video.
By default, a few frames spread over the whole video sequence are selected.
**Parameters:**
The ``quality_function`` is used to assess the quality of the frame.
If no ``quality_function`` is given, the quality is based on the face detector, or simply left as ``None``.
So far, the quality of the frames are not used, but it is foreseen to select frames based on quality.
preprocessor : str or :py:class:`bob.bio.base.preprocessor.Preprocessor` instance
The preprocessor to be used to preprocess the frames.
**Parameters:**
frame_selector : :py:class:`bob.bio.video.FrameSelector`
A frame selector class to define, which frames of the video to use.
preprocessor : str or :py:class:`bob.bio.base.preprocessor.Preprocessor` instance
The preprocessor to be used to preprocess the frames.
quality_function : function or ``None``
A function assessing the quality of the preprocessed image.
If ``None``, no quality assessment is performed.
If the preprocessor contains a ``quality`` attribute, this is taken instead.
frame_selector : :py:class:`bob.bio.video.FrameSelector`
A frame selector class to define, which frames of the video to use.
compressed_io : bool
Use compression to write the resulting preprocessed HDF5 files.
This is experimental and might cause trouble.
Use this flag with care.
"""
quality_function : function or ``None``
A function assessing the quality of the preprocessed image.
If ``None``, no quality assessment is performed.
If the preprocessor contains a ``quality`` attribute, this is taken instead.
def __init__(self,
preprocessor = 'landmark-detect',
frame_selector = utils.FrameSelector(),
quality_function = None,
compressed_io = False
):
compressed_io : bool
Use compression to write the resulting preprocessed HDF5 files.
This is experimental and might cause trouble.
Use this flag with care.
# load preprocessor configuration
if isinstance(preprocessor, str):
self.preprocessor = bob.bio.base.load_resource(preprocessor, "preprocessor")
elif isinstance(preprocessor, bob.bio.base.preprocessor.Preprocessor):
self.preprocessor = preprocessor
else:
raise ValueError("The given preprocessor could not be interpreted")
read_original_data:
Function that loads the raw data.
If not explicitly defined the raw data will be loaded by :py:method:`bob.bio.base.database.VideoBioFile.load`
bob.bio.base.preprocessor.Preprocessor.__init__(
self,
preprocessor=preprocessor,
frame_selector=frame_selector,
compressed_io=compressed_io
)
"""
self.frame_selector = frame_selector
self.quality_function = quality_function
self.compressed_io = compressed_io
def __init__(self,
preprocessor='landmark-detect',
frame_selector=utils.FrameSelector(),
quality_function=None,
compressed_io=False,
read_original_data=lambda biofile, directory, extension: biofile.load(directory, extension)
):
# load preprocessor configuration
if isinstance(preprocessor, str):
self.preprocessor = bob.bio.base.load_resource(preprocessor, "preprocessor")
elif isinstance(preprocessor, bob.bio.base.preprocessor.Preprocessor):
self.preprocessor = preprocessor
else:
raise ValueError("The given preprocessor could not be interpreted")
def _check_data(self, frames):
"""Checks if the given video is in the desired format."""
assert isinstance(frames, utils.FrameContainer)
bob.bio.base.preprocessor.Preprocessor.__init__(
self,
preprocessor=preprocessor,
frame_selector=frame_selector,
compressed_io=compressed_io,
read_original_data=read_original_data
)
self.frame_selector = frame_selector
self.quality_function = quality_function
self.compressed_io = compressed_io
def __call__(self, frames, annotations = None):
"""__call__(frames, annotations = None) -> preprocessed
def _check_data(self, frames):
"""Checks if the given video is in the desired format."""
assert isinstance(frames, utils.FrameContainer)
Preprocesses the given frames using the desired ``preprocessor``.
def __call__(self, frames, annotations=None):
"""__call__(frames, annotations = None) -> preprocessed
Faces are extracted for all frames in the given frame container, using the ``preprocessor`` specified in the constructor.
Preprocesses the given frames using the desired ``preprocessor``.
If given, the annotations need to be in a dictionary.
The key is either the frame number (for video data) or the image name (for image list data).
The value is another dictionary, building the relation between facial landmark names and their location, e.g. ``{'leye' : (le_y, le_x), 'reye' : (re_y, re_x)}``
Faces are extracted for all frames in the given frame container, using the ``preprocessor`` specified in the constructor.
The annotations for the according frames, if present, are passed to the preprocessor.
Please assure that your database interface provides the annotations in the desired format.
If given, the annotations need to be in a dictionary.
The key is either the frame number (for video data) or the image name (for image list data).
The value is another dictionary, building the relation between facial landmark names and their location, e.g. ``{'leye' : (le_y, le_x), 'reye' : (re_y, re_x)}``
**Parameters:**
The annotations for the according frames, if present, are passed to the preprocessor.
Please assure that your database interface provides the annotations in the desired format.
frames : :py:class:`bob.bio.video.FrameContainer`
The pre-selected frames, as returned by :py:meth:`read_original_data`.
**Parameters:**
annotations : dict or ``None``
The annotations for the frames, if any.
frames : :py:class:`bob.bio.video.FrameContainer`
The pre-selected frames, as returned by :py:meth:`read_original_data`.
**Returns:**
annotations : dict or ``None``
The annotations for the frames, if any.
preprocessed : :py:class:`bob.bio.video.FrameContainer`
A frame container that contains the preprocessed frames.
"""
if not isinstance(frames, utils.FrameContainer):
frames = self.frame_selector(frames)
annots = None
fc = utils.FrameContainer()
for index, frame, _ in frames:
# if annotations are given, we take them
if annotations is not None: annots = annotations[index]
# preprocess image (by default: detect a face)
preprocessed = self.preprocessor(frame, annots)
if preprocessed is not None:
# compute the quality of the detection
if self.quality_function is not None:
quality = self.quality_function(preprocessed)
elif hasattr(self.preprocessor, 'quality'):
quality = self.preprocessor.quality
else:
quality = None
# add image to frame container
fc.add(index, preprocessed, quality)
return fc
**Returns:**
preprocessed : :py:class:`bob.bio.video.FrameContainer`
A frame container that contains the preprocessed frames.
"""
if not isinstance(frames, utils.FrameContainer):
frames = self.frame_selector(frames)
def read_original_data(self, data):
"""read_original_data(data) -> frames
annots = None
fc = utils.FrameContainer()
Reads the original data from file and selects some frames using the desired ``frame_selector``.
for index, frame, _ in frames:
# if annotations are given, we take them
if annotations is not None: annots = annotations[index]
Currently, two types of data is supported:
# preprocess image (by default: detect a face)
preprocessed = self.preprocessor(frame, annots)
if preprocessed is not None:
# compute the quality of the detection
if self.quality_function is not None:
quality = self.quality_function(preprocessed)
elif hasattr(self.preprocessor, 'quality'):
quality = self.preprocessor.quality
else:
quality = None
# add image to frame container
fc.add(index, preprocessed, quality)
1. video data, which is stored in a 3D or 4D :py:class:`numpy.ndarray`, which will be read using :py:func:`bob.io.base.load`
2. image lists, which is given as a list of strings of image file names. Each image will be read with :py:func:`bob.io.base.load`
return fc
**Parameters:**
data : 3D or 4D :py:class:`numpy.ndarray`, or [str]
The original data to read.
def read_data(self, filename):
"""read_data(filename) -> frames
**Returns:**
frames : :py:class:`bob.bio.video.FrameContainer`
The selected frames, stored in a frame container.
"""
return self.frame_selector(data)
Reads the preprocessed data from file and returns them in a frame container.
The preprocessors ``read_data`` function is used to read the data for each frame.
**Parameters:**
def read_data(self, filename):
"""read_data(filename) -> frames
filename : str
The name of the preprocessed data file.
Reads the preprocessed data from file and returns them in a frame container.
The preprocessors ``read_data`` function is used to read the data for each frame.
**Returns:**
**Parameters:**
filename : str
The name of the preprocessed data file.
**Returns:**
frames : :py:class:`bob.bio.video.FrameContainer`
The read frames, stored in a frame container.
"""
if self.compressed_io:
return utils.load_compressed(filename, self.preprocessor.read_data)
else:
return utils.FrameContainer(bob.io.base.HDF5File(filename), self.preprocessor.read_data)
frames : :py:class:`bob.bio.video.FrameContainer`
The read frames, stored in a frame container.
"""
if self.compressed_io:
return utils.load_compressed(filename, self.preprocessor.read_data)
else:
return utils.FrameContainer(bob.io.base.HDF5File(filename), self.preprocessor.read_data)
def write_data(self, frames, filename):
"""Writes the preprocessed data to file.
def write_data(self, frames, filename):
"""Writes the preprocessed data to file.
The preprocessors ``write_data`` function is used to write the data for each frame.
The preprocessors ``write_data`` function is used to write the data for each frame.
**Parameters:**
**Parameters:**
frames : :py:class:`bob.bio.video.FrameContainer`
The preprocessed frames, as returned by the :py:meth:`__call__` function.
frames : :py:class:`bob.bio.video.FrameContainer`
The preprocessed frames, as returned by the :py:meth:`__call__` function.
filename : str
The name of the preprocessed data file to write.
"""
self._check_data(frames)
filename : str
The name of the preprocessed data file to write.
"""
self._check_data(frames)
if self.compressed_io:
return utils.save_compressed(frames, filename, self.preprocessor.write_data)
else:
frames.save(bob.io.base.HDF5File(filename, 'w'), self.preprocessor.write_data)
if self.compressed_io:
return utils.save_compressed(frames, filename, self.preprocessor.write_data)
else:
frames.save(bob.io.base.HDF5File(filename, 'w'), self.preprocessor.write_data)
from bob.bio.db import ZTBioDatabase
from bob.bio.base.database import ZTBioDatabase
from bob.bio.base.test.utils import atnt_database_directory
from bob.bio.base.database.file import BioFile
from bob.bio.video.database import VideoBioFile
from bob.bio.video.utils import FrameContainer
import bob.io.base
import os
class DummyBioFile(VideoBioFile):
def load(self, directory=None, extension='.pgm'):
file_name = self.make_path(directory, extension)
fc = FrameContainer()
fc.add(os.path.basename(file_name), bob.io.base.load(file_name))
return fc
class DummyDatabase(ZTBioDatabase):
......@@ -17,11 +30,14 @@ class DummyDatabase(ZTBioDatabase):
import bob.db.atnt
self.__db = bob.db.atnt.Database()
def _make_bio(self, files):
return [DummyBioFile(client_id=f.client_id, path=f.path, file_id=f.id) for f in files]
def model_ids_with_protocol(self, groups=None, protocol=None, **kwargs):
return self.__db.model_ids(groups, protocol)
def objects(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs):
return self.__db.objects(model_ids, groups, purposes, protocol, **kwargs)
return self._make_bio(self.__db.objects(model_ids, groups, purposes, protocol, **kwargs))
def tobjects(self, groups=None, protocol=None, model_ids=None, **kwargs):
return []
......@@ -38,10 +54,6 @@ class DummyDatabase(ZTBioDatabase):
def z_probe_files(self, group='dev'):
return self.probe_files(None, group)
# override all_files to return a one-element lists of files
def all_files(self, groups):
return [[n] for n in super(DummyDatabase, self).all_files(groups)]
Please register or sign in to reply
def file_names(self, files, directory, extension):
if isinstance(files[0], list):
files = list(list(zip(*files))[0])
......
......@@ -9,70 +9,86 @@ import bob.io.video
import bob.bio.base
import bob.bio.video
import bob.db.base
import pkg_resources
from bob.bio.video.test.dummy.database import DummyBioFile
regenerate_refs = False
def test_annotations():
# use annotations to grep
image_files = [pkg_resources.resource_filename("bob.bio.face.test", "data/testimage.jpg")]
annotations = {os.path.basename(image_files[0]) : bob.db.base.read_annotation_file(pkg_resources.resource_filename("bob.bio.face.test", "data/testimage.pos"), 'named')}
original_path = pkg_resources.resource_filename("bob.bio.face.test", "")
image_files = DummyBioFile(client_id=1, file_id=1, path="data/testimage")
# use annotations to grep
annotations = {os.path.basename(image_files.make_path(original_path, ".jpg")): bob.db.base.read_annotation_file(
pkg_resources.resource_filename("bob.bio.face.test", "data/testimage.pos"), 'named')}
# video preprocessor using a face crop preprocessor
frame_selector = bob.