diff --git a/bob/bio/face/config/database/ijbc.py b/bob/bio/face/config/database/ijbc.py new file mode 100644 index 0000000000000000000000000000000000000000..bafb762bd15d57d0953f66537ca0870184000fa2 --- /dev/null +++ b/bob/bio/face/config/database/ijbc.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +from bob.bio.face.database import IJBCBioDatabase + +ijbc_directory = "[YOUR_IJBC_DIRECTORY]" + +ijbc_11 = IJBCBioDatabase( + original_directory=ijbc_directory, + protocol='1:1' +) + +ijbc_covariates = IJBCBioDatabase( + original_directory=ijbc_directory, + protocol='Covariates' +) diff --git a/bob/bio/face/database/__init__.py b/bob/bio/face/database/__init__.py index dadc5651d1bae6f2635852c2270cc2fd500f972a..252f570562ac6d50025152cbd6f666a4f77a25ee 100644 --- a/bob/bio/face/database/__init__.py +++ b/bob/bio/face/database/__init__.py @@ -13,6 +13,7 @@ from .lfw import LFWBioDatabase from .multipie import MultipieBioDatabase from .ijba import IJBABioDatabase from .ijbb import IJBBBioDatabase +from .ijbc import IJBCBioDatabase from .xm2vts import XM2VTSBioDatabase from .frgc import FRGCBioDatabase from .scface import SCFaceBioDatabase @@ -49,6 +50,7 @@ __appropriate__( MultipieBioDatabase, IJBABioDatabase, IJBBBioDatabase, + IJBCBioDatabase, XM2VTSBioDatabase, FRGCBioDatabase, SCFaceBioDatabase, diff --git a/bob/bio/face/database/ijbc.py b/bob/bio/face/database/ijbc.py new file mode 100644 index 0000000000000000000000000000000000000000..b5790d38f1911ff7fb01d762a413bce6ad19df26 --- /dev/null +++ b/bob/bio/face/database/ijbc.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 + +""" + IJBC database implementation of bob.bio.base.database.BioDatabase interface. + It is an extension of the database interface, which directly talks to IJBC 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 IJBCBioFile(FaceBioFile): + def __init__(self, f): + super(IJBCBioFile, 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 IJBCBioFileSet(BioFileSet): + def __init__(self, template): + super(IJBCBioFileSet, self).__init__(file_set_id=template.id, files=[ + IJBCBioFile(f) for f in template.files], path=template.path) + + +class IJBCBioDatabase(BioDatabase): + """ + IJBC 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 IJBC 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.ijbc.query import Database as LowLevelDatabase + self._db = LowLevelDatabase( + original_directory) + + # call base class constructors to open a session to the database + super(IJBCBioDatabase, self).__init__( + name='ijbc', + 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 [IJBCBioFile(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 [IJBCBioFileSet(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(self.protocol, 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 d49bdffc978074d0c065c58b9574266de6951742..bc8b8b9bece2142c997187d3d22345d0a128c66f 100644 --- a/bob/bio/face/test/test_databases.py +++ b/bob/bio/face/test/test_databases.py @@ -373,3 +373,20 @@ def test_ijbb(): except IOError as e: raise SkipTest( "The annotations could not be queried; probably the annotation files are missing. Here is the error: '%s'" % e) + + +@db_available('ijbc') +def test_ijbc(): + database = bob.bio.base.load_resource( + 'ijbc-11', '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/conda/meta.yaml b/conda/meta.yaml index 52ab3ba2e75e597ddd8464f9f57845a18f0ff76c..6c76ca5fb1832848f2b02b735f32019062edf669 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -74,6 +74,7 @@ test: - bob.db.frgc - bob.db.gbu - bob.db.ijba + - bob.db.ijbc - bob.db.lfw - bob.db.mobio - bob.db.msu_mfsd_mod diff --git a/setup.py b/setup.py index c5c65897887811ea492320705955fdda881d88a6..1d257edc2ee2292f1c0c4cd3efd89f3e5bdf906d 100644 --- a/setup.py +++ b/setup.py @@ -117,6 +117,10 @@ setup( 'gbu = bob.bio.face.config.database.gbu:database', 'ijba = bob.bio.face.config.database.ijba:database', 'ijbb = bob.bio.face.config.database.ijbb:database', + + 'ijbc-11 = bob.bio.face.config.database.ijbc:ijbc_11', + 'ijbc-covariates = bob.bio.face.config.database.ijbc:ijbc_covariates', + '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', diff --git a/test-requirements.txt b/test-requirements.txt index dd96b98a6cb28c259b8a7b8c96e285c47d284a9a..51d044c0f6cdb7fbd37ee1e38a277e24df6407cd 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -6,6 +6,7 @@ bob.db.caspeal bob.db.frgc bob.db.gbu bob.db.ijba +bob.db.ijbc bob.db.lfw bob.db.mobio bob.db.msu_mfsd_mod diff --git a/version.txt b/version.txt index 95998eb0bc9af3abaaaa4701ab5fd6edfc9d8238..d1e43136d8e58b0066ca8971d323d48a04a60d1d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -3.4.1b0 \ No newline at end of file +3.4.1b0