Commit 83f4fde0 authored by Tiago de Freitas Pereira's avatar Tiago de Freitas Pereira

Merge branch 'csv-database' into 'master'

Porting databases to the CSV interface

See merge request !91
parents 10ca24c0 7d55c8ab
Pipeline #46763 failed with stages
in 40 minutes and 59 seconds
#!/usr/bin/env python
from bob.bio.face.database import MobioBioDatabase
from bob.bio.base.pipelines.vanilla_biometrics import DatabaseConnector
from bob.extension import rc
database = DatabaseConnector(
MobioBioDatabase(
original_directory=rc["bob.db.mobio.directory"],
annotation_directory=rc["bob.db.mobio.annotation_directory"],
original_extension=".png",
protocol="mobile0-male",
)
)
database.allow_scoring_with_all_biometric_references = True
mobio_image_directory = rc["bob.db.mobio.directory"]
mobio_annotation_directory = rc["bob.db.mobio.annotation_directory"]
allow_scoring_with_all_biometric_references = True
annotation_type = "eyes-center"
fixed_positions = None
mobio_image = DatabaseConnector(
MobioBioDatabase(
original_directory=mobio_image_directory,
original_extension=".png",
annotation_directory=mobio_annotation_directory,
annotation_type="eyecenter",
protocol="male",
models_depend_on_protocol=True,
),
allow_scoring_with_all_biometric_references=allow_scoring_with_all_biometric_references,
annotation_type=annotation_type,
fixed_positions=fixed_positions,
)
mobio_male = DatabaseConnector(
MobioBioDatabase(
original_directory=mobio_image_directory,
original_extension=".png",
annotation_directory=mobio_annotation_directory,
annotation_type="eyecenter",
protocol="male",
models_depend_on_protocol=True,
all_files_options={"gender": "male"},
extractor_training_options={"gender": "male"},
projector_training_options={"gender": "male"},
enroller_training_options={"gender": "male"},
z_probe_options={"gender": "male"},
),
allow_scoring_with_all_biometric_references=allow_scoring_with_all_biometric_references,
annotation_type=annotation_type,
fixed_positions=fixed_positions,
)
mobio_female = DatabaseConnector(
MobioBioDatabase(
original_directory=mobio_image_directory,
original_extension=".png",
annotation_directory=mobio_annotation_directory,
annotation_type="eyecenter",
protocol="female",
models_depend_on_protocol=True,
all_files_options={"gender": "female"},
extractor_training_options={"gender": "female"},
projector_training_options={"gender": "female"},
enroller_training_options={"gender": "female"},
z_probe_options={"gender": "female"},
),
allow_scoring_with_all_biometric_references=allow_scoring_with_all_biometric_references,
annotation_type=annotation_type,
fixed_positions=fixed_positions,
)
#!/usr/bin/env python
from bob.bio.face.database import MobioBioDatabase
from bob.bio.base.pipelines.vanilla_biometrics import DatabaseConnector
from bob.extension import rc
database = DatabaseConnector(
MobioBioDatabase(
original_directory=rc["bob.db.mobio.directory"],
annotation_directory=rc["bob.db.mobio.annotation_directory"],
original_extension=".png",
protocol="mobile0-male-female",
),
annotation_type = "eyes-center",
fixed_positions = None
)
from bob.bio.face.database import MobioDatabase
database = MobioDatabase(protocol="mobile0-male-female")
#!/usr/bin/env python
from bob.bio.face.database import MobioBioDatabase
from bob.bio.base.pipelines.vanilla_biometrics import DatabaseConnector
from bob.extension import rc
database = DatabaseConnector(
MobioBioDatabase(
original_directory=rc["bob.db.mobio.directory"],
annotation_directory=rc["bob.db.mobio.annotation_directory"],
original_extension=".png",
protocol="mobile0-male",
),
annotation_type = "eyes-center",
fixed_positions = None
)
from bob.bio.face.database import MobioDatabase
database = MobioDatabase(protocol="mobile0-male")
#!/usr/bin/env python
from bob.bio.face.database import MultipieBioDatabase
from bob.bio.base.pipelines.vanilla_biometrics import DatabaseConnector
from bob.extension import rc
from bob.bio.face.database import MultipieDatabase
multipie_image_directory = rc["bob.db.multipie.directory"]
multipie_annotation_directory = rc["bob.db.multipie.annotations"]
database = DatabaseConnector(
MultipieBioDatabase(
original_directory=multipie_image_directory,
annotation_directory=multipie_annotation_directory,
protocol="U",
training_depends_on_protocol=True,
)
)
database = MultipieDatabase(protocol="U")
#!/usr/bin/env python
from bob.bio.face.database import MultipieDatabase
from bob.bio.face.database import MultipieBioDatabase
from bob.bio.base.pipelines.vanilla_biometrics import DatabaseConnector
from bob.extension import rc
# here, we only want to have the cameras that are used in the P protocol
cameras = (
"24_0",
"01_0",
"20_0",
"19_0",
"04_1",
"05_0",
"05_1",
"14_0",
"13_0",
"08_0",
"09_0",
"12_0",
"11_0",
)
multipie_image_directory = rc["bob.db.multipie.directory"]
multipie_annotation_directory = rc["bob.db.multipie.annotations"]
database = DatabaseConnector(
MultipieBioDatabase(
original_directory=multipie_image_directory,
annotation_directory=multipie_annotation_directory,
protocol="P",
training_depends_on_protocol=True,
all_files_options={"cameras": cameras},
extractor_training_options={"cameras": cameras},
projector_training_options={
"cameras": cameras,
"world_sampling": 3,
"world_first": True,
},
enroller_training_options={"cameras": cameras},
)
)
database = MultipieDatabase(protocol="P")
......@@ -2,13 +2,13 @@
# vim: set fileencoding=utf-8 :
from .database import FaceBioFile
from .mobio import MobioBioDatabase
from .mobio import MobioDatabase
from .replay import ReplayBioDatabase
from .atnt import AtntBioDatabase
from .gbu import GBUBioDatabase
from .arface import ARFaceBioDatabase
from .lfw import LFWBioDatabase
from .multipie import MultipieBioDatabase
from .multipie import MultipieDatabase
from .ijbc import IJBCBioDatabase
from .replaymobile import ReplayMobileBioDatabase
from .fargo import FargoBioDatabase
......@@ -35,13 +35,13 @@ def __appropriate__(*args):
__appropriate__(
FaceBioFile,
MobioBioDatabase,
MobioDatabase,
ReplayBioDatabase,
AtntBioDatabase,
GBUBioDatabase,
ARFaceBioDatabase,
LFWBioDatabase,
MultipieBioDatabase,
MultipieDatabase,
IJBCBioDatabase,
ReplayMobileBioDatabase,
FargoBioDatabase,
......
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Amir Mohammadi <amir.mohammadi@idiap.ch>
# Wed 13 Jul 16:43:22 CEST 2016
# Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
"""
MOBIO database implementation of bob.bio.base.database.ZTBioDatabase 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).
MOBIO database implementation
"""
from bob.bio.base.database import (
CSVDataset,
CSVDatasetZTNorm,
)
from bob.pipelines.datasets import CSVToSampleLoader
from bob.bio.face.database.sample_loaders import EyesAnnotations
from bob.extension import rc
from bob.extension.download import get_file
import bob.io.base
from sklearn.pipeline import make_pipeline
from .database import FaceBioFile
from bob.bio.base.database import ZTBioDatabase
class MobioBioFile(FaceBioFile):
"""FaceBioFile implementation of the Mobio Database"""
def __init__(self, f):
super(MobioBioFile, self).__init__(client_id=f.client_id, path=f.path, file_id=f.id)
self._f = f
class MobioBioDatabase(ZTBioDatabase):
"""
MOBIO database implementation of bob.bio.base.database.ZTBioDatabase 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).
class MobioDatabase(CSVDatasetZTNorm):
"""
The MOBIO dataset is a video database containing bimodal data (face/speaker).
It is composed by 152 people (split in the two genders male and female), mostly Europeans, split in 5 sessions (few weeks time lapse between sessions).
The database was recorded using two types of mobile devices: mobile phones (NOKIA N93i) and laptop
computers(standard 2008 MacBook).
For face recognition images are used instead of videos.
One image was extracted from each video by choosing the video frame after 10 seconds.
The eye positions were manually labelled and distributed with the database.
For more information check:
.. code-block:: latex
@article{McCool_IET_BMT_2013,
title = {Session variability modelling for face authentication},
author = {McCool, Chris and Wallace, Roy and McLaren, Mitchell and El Shafey, Laurent and Marcel, S{\'{e}}bastien},
month = sep,
journal = {IET Biometrics},
volume = {2},
number = {3},
year = {2013},
pages = {117-129},
issn = {2047-4938},
doi = {10.1049/iet-bmt.2012.0059},
}
def __init__(
self,
original_directory=None,
original_extension=None,
annotation_directory=None,
annotation_extension='.pos',
**kwargs
):
from bob.db.mobio.query import Database as LowLevelDatabase
self._db = LowLevelDatabase(original_directory, original_extension,
annotation_directory, annotation_extension)
# call base class constructors to open a session to the database
super(MobioBioDatabase, self).__init__(
name='mobio',
original_directory=original_directory,
original_extension=original_extension,
annotation_directory=annotation_directory,
annotation_extension=annotation_extension,
**kwargs)
@property
def original_directory(self):
return self._db.original_directory
@original_directory.setter
def original_directory(self, value):
self._db.original_directory = value
@property
def annotation_directory(self):
return self._db.annotation_directory
@annotation_directory.setter
def annotation_directory(self, value):
self._db.annotation_directory = value
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 [MobioBioFile(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 [MobioBioFile(f) for f in retval]
def zobjects(self, groups=None, protocol=None, **kwargs):
retval = self._db.zobjects(groups=groups, protocol=protocol, **kwargs)
return [MobioBioFile(f) for f in retval]
def annotations(self, myfile):
return self._db.annotations(myfile._f)
def groups(self, protocol=None, **kwargs):
return self._db.groups(protocol=protocol)
"""
def __init__(self, protocol):
# Downloading model if not exists
urls = [
"https://www.idiap.ch/software/bob/databases/latest/mobio.tar.gz",
"http://www.idiap.ch/software/bob/databases/latest/mobio.tar.gz",
]
filename = get_file("mobio.tar.gz", urls)
self.annotation_type = "eyes-center"
self.fixed_positions = None
database = CSVDataset(
filename,
protocol,
csv_to_sample_loader=make_pipeline(
CSVToSampleLoader(
data_loader=bob.io.base.load,
dataset_original_directory=rc["bob.db.mobio.directory"]
if rc["bob.db.mobio.directory"]
else "",
extension=".png",
),
EyesAnnotations(),
),
)
super().__init__(database)
# def zprobes(self, proportion=0.20):
# return super().zprobes(proportion=proportion)
@staticmethod
def protocols():
# TODO: Until we have (if we have) a function that dumps the protocols, let's use this one.
return [
"laptop1-female",
"laptop_mobile1-female",
"mobile0-female",
"mobile0-male-female",
"mobile1-male",
"laptop1-male",
"laptop_mobile1-male",
"mobile0-male",
"mobile1-female",
]
#!/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
"""
Multipie database implementation of bob.bio.base.database.Database interface.
It is an extension of an SQL-based database interface, which directly talks to Multipie database, for
verification experiments (good to use in bob.bio.base framework).
Multipie database implementation
"""
from .database import FaceBioFile
from bob.bio.base.database import ZTBioDatabase
from bob.bio.base.database import CSVDataset
from bob.pipelines.datasets import CSVToSampleLoader
from bob.bio.face.database.sample_loaders import MultiposeAnnotations
from bob.extension import rc
from bob.extension.download import get_file
import bob.io.base
from sklearn.pipeline import make_pipeline
class MultipieBioFile(FaceBioFile):
def __init__(self, f):
super(MultipieBioFile, self).__init__(client_id=f.client_id, path=f.path, file_id=f.id)
self._f = f
class MultipieBioDatabase(ZTBioDatabase):
class MultipieDatabase(CSVDataset):
"""
Multipie database implementation of bob.bio.base.database.Database interface.
It is an extension of an SQL-based database interface, which directly talks to Multipie database, for
verification experiments (good to use in bob.bio.base framework).
The Multipie database..
"""
def __init__(
self,
original_directory=None,
original_extension='.png',
annotation_directory=None,
annotation_extension='.pos',
**kwargs
):
from bob.db.multipie.query import Database as LowLevelDatabase
self._db = LowLevelDatabase(original_directory,
original_extension,
annotation_directory,
annotation_extension)
# call base class constructors to open a session to the database
super(MultipieBioDatabase, self).__init__(
name='multipie',
original_directory=original_directory,
original_extension=original_extension,
annotation_directory=annotation_directory,
annotation_extension=annotation_extension,
**kwargs)
@property
def original_directory(self):
return self._db.original_directory
@original_directory.setter
def original_directory(self, value):
self._db.original_directory = value
def model_ids_with_protocol(self, groups=None, protocol=None, **kwargs):
return self._db.model_ids(groups=groups, protocol=protocol)
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 [MultipieBioFile(f) for f in retval]
def tmodel_ids_with_protocol(self, protocol=None, groups=None, **kwargs):
return self._db.tmodel_ids(protocol=protocol, groups=groups, **kwargs)
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 [MultipieBioFile(f) for f in retval]
def zobjects(self, groups=None, protocol=None, **kwargs):
retval = self._db.zobjects(groups=groups, protocol=protocol, **kwargs)
return [MultipieBioFile(f) for f in retval]
def annotations(self, myfile):
return self._db.annotations(myfile._f)
def __init__(self, protocol):
# Downloading model if not exists
urls = [
"https://www.idiap.ch/software/bob/databases/latest/multipie.tar.gz",
"http://www.idiap.ch/software/bob/databases/latest/multipie.tar.gz",
]
filename = get_file("multipie.tar.gz", urls)
self.annotation_type = ["eyes-center", "left-profile", "right-profile"]
self.fixed_positions = None
super().__init__(
filename,
protocol,
csv_to_sample_loader=make_pipeline(
CSVToSampleLoader(
data_loader=bob.io.base.load,
dataset_original_directory=rc["bob.db.multipie.directory"]
if rc["bob.db.multipie.directory"]
else "",
extension=".png",
),
MultiposeAnnotations(),
),
)
@staticmethod
def protocols():
# TODO: Until we have (if we have) a function that dumps the protocols, let's use this one.
return [
"P240",
"P191",
"P130",
"G",
"P010",
"P041",
"P051",
"P050",
"M",
"P110",
"P",
"P140",
"U",
"P200",
"E",
"P190",
"P120",
"P080",
"P081",
"P090",
]
......@@ -8,6 +8,13 @@ from bob.pipelines import DelayedSample, Sample, SampleSet
from sklearn.base import TransformerMixin, BaseEstimator
def find_attribute(x, attribute):
if hasattr(x, attribute):
return getattr(x, attribute)
else:
ValueError(f"Attribute not found in the dataset: {attribute}")
class EyesAnnotations(TransformerMixin, BaseEstimator):
def fit(self, X, y=None):
return self
......@@ -23,12 +30,6 @@ class EyesAnnotations(TransformerMixin, BaseEstimator):
Convert leye_x, leye_y, reye_x, reye_y attributes to `annotations = (leye, reye)`
"""
def find_attribute(x, attribute):
if hasattr(x, attribute):
return getattr(x, attribute)
else:
ValueError(f"Attribute not found in the dataset: {attribute}")
annotated_samples = []
for x in X:
eyes = {
......@@ -47,3 +48,85 @@ class EyesAnnotations(TransformerMixin, BaseEstimator):
annotated_samples.append(sample)
return annotated_samples
class MultiposeAnnotations(TransformerMixin, BaseEstimator):
def fit(self, X, y=None):
return self
def _more_tags(self):
return {
"stateless": True,
"requires_fit": False,
}
def transform(self, X):
annotated_samples = []
for x in X:
annotations = dict()
if find_attribute(x, "leye_x") != "" and find_attribute(x, "reye_x") != "":
# Normal profile
annotations = {
"leye": (
float(find_attribute(x, "leye_x")),
float(find_attribute(x, "leye_y")),
),
"reye": (
float(find_attribute(x, "reye_x")),
float(find_attribute(x, "reye_y")),
),
}
elif (
find_attribute(x, "leye_x") != "" and find_attribute(x, "reye_x") == ""
):
# Left profile
annotations = {
"leye": (
float(find_attribute(x, "leye_x")),
float(find_attribute(x, "leye_y")),
),
"mouth": (
float(find_attribute(x, "mouthl_x")),
float(find_attribute(x, "mouthl_y")),
),
}
elif (
find_attribute(x, "leye_x") == "" and find_attribute(x, "reye_x") != ""
):
# Right profile
annotations = {
"reye": (
float(find_attribute(x, "reye_x")),
float(find_attribute(x, "reye_y")),
),
"mouth": (
float(find_attribute(x, "mouthr_x")),
float(find_attribute(x, "mouthr_y")),
),
}
else:
raise ValueError("Annotations not available")
sample = DelayedSample(x._load, parent=x, annotations=annotations)
[
delattr(sample, a)
for a in [
"reye_x",
"reye_y",
"leye_x",
"leye_y",
"nose_x",
"nose_y",
"mouthr_x",
"mouthr_y",
"mouthl_x",
"mouthl_y",
"chin_x",
"chin_y",
]
]
annotated_samples.append(sample)
return annotated_samples
......@@ -156,74 +156,58 @@ def test_lfw():
)
@db_available("mobio")
def test_mobio():
database = bob.bio.base.load_resource(
"mobio-image", "database", preferred_package="bob.bio.face"
)
try:
check_database_zt(database, models_depend=True)
check_database_zt(database, protocol="female", models_depend=True)
check_database_zt(
bob.bio.base.load_resource(
"mobio-male", "database", preferred_package="bob.bio.face"
),
models_depend=True,
)
check_database_zt(
bob.bio.base.load_resource(
"mobio-female", "database", preferred_package="bob.bio.face"
),
models_depend=True,
)
except IOError as e:
raise SkipTest(
"The database could not be queried; probably the db.sql3 file is missing. Here is the error: '%s'"
% e
)
from bob.bio.face.database import MobioDatabase
try:
_check_annotations(database, limit_files=1000)
except IOError as e:
raise SkipTest(
"The annotations could not be queried; probably the annotation files are missing. Here is the error: '%s'"
% e
)
protocols = MobioDatabase.protocols()
for p in protocols:
database = MobioDatabase(protocol=p)
assert len(database.background_model_samples()) > 0
assert len(database.treferences()) > 0
assert len(database.zprobes()) > 0
assert len(database.references(group="dev")) > 0
assert len(database.probes(group="dev")) > 0
assert len(database.references(group="eval")) > 0
assert len(database.probes(group="eval")) > 0
# Sanity check on mobio-male
database = MobioDatabase(protocol="mobile0-male")
assert len(database.treferences()) == 8