diff --git a/bob/bio/face/config/database/ijbc.py b/bob/bio/face/config/database/ijbc.py new file mode 100644 index 0000000000000000000000000000000000000000..6f410fd4191be9e7ca45f93f6727153a541b7fac --- /dev/null +++ b/bob/bio/face/config/database/ijbc.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +from bob.bio.face.database import IJBCBioDatabase + +ijbc_directory = "[YOUR_IJBC_DIRECTORY]" + +database = IJBCBioDatabase( + original_directory=ijbc_directory, + protocol='1:1' +) 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..d7f4381f70f7e30dd35ca08a87425288e14ebd7f 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', '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 4e408a42b6fbc9415bb1a6ddf1115348fefa3c52..ec19f16277d90cb152568c57da6b1ff2188f8618 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -76,6 +76,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 05079868fb561109918f32b5b1b53a12f20e4a82..efc501a2ecf85ecbe05ee6bba0ff92af4bc88375 100644 --- a/setup.py +++ b/setup.py @@ -117,6 +117,7 @@ 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 = bob.bio.face.config.database.ijbc: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', 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