diff --git a/bob/bio/face/config/database/ijbb.py b/bob/bio/face/config/database/ijbb.py new file mode 100644 index 0000000000000000000000000000000000000000..24cae9ad16ee3ed09526867c22802ddf737732f9 --- /dev/null +++ b/bob/bio/face/config/database/ijbb.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +from bob.bio.face.database import IJBBBioDatabase + +ijbb_directory = "[YOUR_IJBB_DIRECTORY]" + +database = IJBBBioDatabase( + original_directory=ijbb_directory, + protocol='1:1' +) diff --git a/bob/bio/face/database/__init__.py b/bob/bio/face/database/__init__.py index c36d765ae1b69d54363ed3050e87b05998523d2d..dadc5651d1bae6f2635852c2270cc2fd500f972a 100644 --- a/bob/bio/face/database/__init__.py +++ b/bob/bio/face/database/__init__.py @@ -12,6 +12,7 @@ from .caspeal import CaspealBioDatabase from .lfw import LFWBioDatabase from .multipie import MultipieBioDatabase from .ijba import IJBABioDatabase +from .ijbb import IJBBBioDatabase from .xm2vts import XM2VTSBioDatabase from .frgc import FRGCBioDatabase from .scface import SCFaceBioDatabase @@ -47,6 +48,7 @@ __appropriate__( LFWBioDatabase, MultipieBioDatabase, IJBABioDatabase, + IJBBBioDatabase, XM2VTSBioDatabase, FRGCBioDatabase, SCFaceBioDatabase, diff --git a/bob/bio/face/database/ijbb.py b/bob/bio/face/database/ijbb.py new file mode 100644 index 0000000000000000000000000000000000000000..804f25d23ff6d618d624a0cadb104a6706d3774c --- /dev/null +++ b/bob/bio/face/database/ijbb.py @@ -0,0 +1,107 @@ +#!/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 + +""" + IJBB database implementation of bob.bio.base.database.BioDatabase interface. + It is an extension of the database interface, which directly talks to IJBB database, for + verification experiments (good to use in bob.bio.base framework). +""" + +from .database import FaceBioFile +from bob.bio.base.database import BioDatabase, BioFileSet +import os +import bob.io.image + + +class IJBBBioFile(FaceBioFile): + def __init__(self, f): + super(IJBBBioFile, self).__init__( + client_id=f.client_id, path=f.path, file_id=f.id) + self.f = f + + def load(self, directory, extension=None, add_client_id=False): + return bob.io.image.load(self.make_path(directory, self.f.extension, add_client_id)) + + def make_path(self, directory, extension, add_client_id=True): + if add_client_id: + # add client ID to the path, so that a unique path is generated + # (there might be several identities in each physical file) + path = "%s-%s%s" % (self.path, self.client_id, extension or '') + else: + # do not add the client ID to be able to obtain the original image file + path = "%s%s" % (self.path, extension or '') + return str(os.path.join(directory or '', path)) + + +class IJBBBioFileSet(BioFileSet): + def __init__(self, template): + super(IJBBBioFileSet, self).__init__(file_set_id=template.id, files=[ + IJBBBioFile(f) for f in template.files], path=template.path) + + +class IJBBBioDatabase(BioDatabase): + """ + IJBB database implementation of :py:class:`bob.bio.base.database.BioDatabase` interface. + It is an extension of an SQL-based database interface, which directly talks to IJBB database, for + verification experiments (good to use in bob.bio.base framework). + """ + + def __init__( + self, + original_directory=None, + annotation_directory=None, + original_extension=None, + **kwargs + ): + from bob.db.ijbb.query import Database as LowLevelDatabase + self._db = LowLevelDatabase( + original_directory) + + # call base class constructors to open a session to the database + super(IJBBBioDatabase, self).__init__( + name='ijbb', + models_depend_on_protocol=True, + training_depends_on_protocol=True, + original_directory=original_directory, + annotation_directory=annotation_directory, + original_extension=original_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 uses_probe_file_sets(self): + return True + + def model_ids_with_protocol(self, groups=None, protocol="1:1", **kwargs): + return self._db.model_ids(groups=groups, protocol=protocol) + + def objects(self, groups=None, protocol="1:1", purposes=None, model_ids=None, **kwargs): + return [IJBBBioFile(f) for f in self._db.objects(groups=groups, protocol=protocol, purposes=purposes, model_ids=model_ids, **kwargs)] + + def object_sets(self, groups=None, protocol="1:1", purposes=None, model_ids=None): + return [IJBBBioFileSet(t) for t in self._db.object_sets(groups=groups, protocol=protocol, purposes=purposes, model_ids=model_ids)] + + def annotations(self, biofile): + return self._db.annotations(biofile.f) + + def client_id_from_model_id(self, model_id, group='dev'): + return self._db.get_client_id_from_model_id(model_id) + + def original_file_names(self, files): + return [f.make_path(self.original_directory, f.f.extension, False) for f in files] diff --git a/bob/bio/face/test/test_databases.py b/bob/bio/face/test/test_databases.py index 4bd90c4ede29f8426432f8a98006c3b4e394c559..d49bdffc978074d0c065c58b9574266de6951742 100644 --- a/bob/bio/face/test/test_databases.py +++ b/bob/bio/face/test/test_databases.py @@ -150,10 +150,10 @@ def test_ijba(): database = bob.bio.base.load_resource( 'ijba', 'database', preferred_package='bob.bio.face') try: - check_database(database,models_depend=True, training_depends=True) + check_database(database, models_depend=True, training_depends=True) except IOError as e: raise SkipTest( - "The database could not queried; probably the db.sql3 file is missing. Here is the error: '%s'" % e) + "The database could not queried. Here is the error: '%s'" % e) try: _check_annotations(database, topleft=True, limit_files=1000) except IOError as e: @@ -357,3 +357,19 @@ def test_msu_mfsd_mod_spoof(): raise SkipTest( "The annotations could not be queried; probably the annotation " "files are missing. Here is the error: '%s'" % e) + + +@db_available('ijbb') +def test_ijbb(): + database = bob.bio.base.load_resource( + 'ijbb', 'database', preferred_package='bob.bio.face') + try: + check_database(database, models_depend=True, training_depends=True) + except IOError as e: + raise SkipTest( + "The database could not queried; Here is the error: '%s'" % e) + try: + _check_annotations(database, topleft=True, 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) diff --git a/setup.py b/setup.py index 18a9859f1fe906caf03108a13227470ad9d069a3..e0e5768d9cc0d6326553634cf47a3e230eea933d 100644 --- a/setup.py +++ b/setup.py @@ -116,6 +116,7 @@ setup( 'frgc = bob.bio.face.config.database.frgc:database', 'gbu = bob.bio.face.config.database.gbu:database', 'ijba = bob.bio.face.config.database.ijba:database', + 'ijbb = bob.bio.face.config.database.ijbb:database', 'lfw-restricted = bob.bio.face.config.database.lfw_restricted:database', 'lfw-unrestricted = bob.bio.face.config.database.lfw_unrestricted:database', 'mobio-image = bob.bio.face.config.database.mobio:mobio_image',