diff --git a/advanced/databases/livdet2013/3.json b/advanced/databases/livdet2013/3.json new file mode 100644 index 0000000000000000000000000000000000000000..a3a1fa8e8b8b12a4ee9e32ff5b69663356177bbc --- /dev/null +++ b/advanced/databases/livdet2013/3.json @@ -0,0 +1,164 @@ +{ + "description": "The LivDet 2013 Fingerprint Liveness Database", + "root_folder": "/idiap/resource/database/LivDet/LivDet2013", + "protocols": [ + { + "name": "Biometrika", + "template": "simple_fingerprint_antispoofing", + "sets": [ + { + "name": "train", + "template": "train", + "view": "All", + "parameters": { + "protocol": "Biometrika", + "group": "train" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + }, + { + "name": "test", + "template": "test", + "view": "All", + "parameters": { + "protocol": "Biometrika", + "group": "test" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + } + ] + }, + { + "name": "Italdata", + "template": "simple_fingerprint_antispoofing", + "sets": [ + { + "name": "train", + "template": "train", + "view": "All", + "parameters": { + "protocol": "Italdata", + "group": "train" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + }, + { + "name": "test", + "template": "test", + "view": "All", + "parameters": { + "protocol": "Italdata", + "group": "test" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + } + ] + }, + { + "name": "CrossMatch", + "template": "simple_fingerprint_antispoofing", + "sets": [ + { + "name": "train", + "template": "train", + "view": "All", + "parameters": { + "protocol": "CrossMatch", + "group": "train" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + }, + { + "name": "test", + "template": "test", + "view": "All", + "parameters": { + "protocol": "CrossMatch", + "group": "test" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + } + ] + }, + { + "name": "Swipe", + "template": "simple_fingerprint_antispoofing", + "sets": [ + { + "name": "train", + "template": "train", + "view": "All", + "parameters": { + "protocol": "Swipe", + "group": "train" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + }, + { + "name": "test", + "template": "test", + "view": "All", + "parameters": { + "protocol": "Swipe", + "group": "test" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + } + ] + }, + { + "name": "Full", + "template": "simple_fingerprint_antispoofing", + "sets": [ + { + "name": "train", + "template": "train", + "view": "All", + "parameters": { + "group": "train" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + }, + { + "name": "test", + "template": "test", + "view": "All", + "parameters": { + "group": "test" + }, + "outputs": { + "image": "{{ system_user.username }}/array_3d_uint8/1", + "spoof": "{{ system_user.username }}/boolean/1" + } + } + ] + } + ] +} diff --git a/advanced/databases/livdet2013/3.py b/advanced/databases/livdet2013/3.py new file mode 100644 index 0000000000000000000000000000000000000000..96f17f271f8461747ac43947eefe7ae2d1d5ae74 --- /dev/null +++ b/advanced/databases/livdet2013/3.py @@ -0,0 +1,163 @@ +############################################################################### +# # +# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/ # +# Contact: beat.support@idiap.ch # +# # +# This file is part of the beat.examples module of the BEAT platform. # +# # +# Commercial License Usage # +# Licensees holding valid commercial BEAT licenses may use this file in # +# accordance with the terms contained in a written agreement between you # +# and Idiap. For further information contact tto@idiap.ch # +# # +# Alternatively, this file may be used under the terms of the GNU Affero # +# Public License version 3 as published by the Free Software and appearing # +# in the file LICENSE.AGPL included in the packaging of this file. # +# The BEAT platform is distributed in the hope that it will be useful, but # +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # +# or FITNESS FOR A PARTICULAR PURPOSE. # +# # +# You should have received a copy of the GNU Affero Public License along # +# with the BEAT platform. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### + +import os +import numpy as np +import bob.io.base +import bob.io.image +from bob.db.livdet2013 import Database + + +#---------------------------------------------------------- + + +def get_spoof_end_index(objs, spoof, spoof_start_index, + start_index, end_index): + spoof_end_index = spoof_start_index + + while spoof_end_index + 1 <= end_index: + obj = objs[spoof_end_index + 1 - start_index] + + if obj.is_live() != spoof: + return spoof_end_index + + spoof_end_index += 1 + + return end_index + + +#---------------------------------------------------------- + + +class All: + """Outputs: + - image: "{{ system_user.username }}/array_3d_uint8/1" + - spoof: "{{ system_user.username }}/boolean/1" + + Several "image" are associated with a given "spoof". + + --------------- --------------- --------------- --------------- + | image | | image | | image | | image | + --------------- --------------- --------------- --------------- + ------------------------------- ------------------------------ + | spoof | | spoof | + ------------------------------- ------------------------------ + """ + + def setup(self, root_folder, outputs, parameters, force_start_index=None, + force_end_index=None): + + # Initialisations + self.root_folder = root_folder + self.outputs = outputs + + # Open the database and load the objects to provide via the outputs + self.db = Database() + + self.objs = self.db.objects(protocols=parameters.get('protocol'), + groups=parameters['group'], + classes=parameters.get('class')) + + # Determine the range of indices that must be provided + self.start_index = force_start_index if force_start_index is not None else 0 + self.end_index = force_end_index if force_end_index is not None else len(self.objs) - 1 + + self.objs = self.objs[self.start_index : self.end_index + 1] + + self.next_index = self.start_index + + return True + + + def done(self, last_data_index): + return last_data_index >= self.end_index + + + def next(self): + obj = self.objs[self.next_index - self.start_index] + + # Output: spoof (only provide data when the spoof change) + if self.outputs['spoof'].isConnected() and \ + self.outputs['spoof'].last_written_data_index < self.next_index: + + spoof_end_index = get_spoof_end_index(self.objs, obj.is_live(), + self.next_index, + self.start_index, + self.end_index) + + self.outputs['spoof'].write( + { + 'value': obj.is_live() + }, + spoof_end_index + ) + + # Output: image (provide data at each iteration) + if self.outputs['image'].isConnected(): + self.outputs['image'].write( + { + 'value': bob.io.base.load(obj.make_path(self.root_folder)) + }, + self.next_index + ) + + # Determine the next data index that must be provided + self.next_index = 1 + min([ x.last_written_data_index for x in self.outputs + if x.isConnected() ] + ) + + return True + + +#---------------------------------------------------------- + + +def setup_tests(): + # Install a mock load function for the images + def mock_load(root_folder): + return np.ndarray((3, 10, 20), dtype=np.uint8) + + bob.io.base.load = mock_load + + +#---------------------------------------------------------- + + +# Test the behavior of the views (on fake data) +if __name__ == '__main__': + + setup_tests() + + from beat.backend.python.database import DatabaseTester + + DatabaseTester('All', All, + [ + 'image', + 'spoof', + ], + parameters=dict( + protocol='Biometrika', + group='train', + ), + ) diff --git a/advanced/databases/livdet2013/3.rst b/advanced/databases/livdet2013/3.rst new file mode 100644 index 0000000000000000000000000000000000000000..dfc9af8a013f78fded4b2efc76e5d08e7c9a2c96 --- /dev/null +++ b/advanced/databases/livdet2013/3.rst @@ -0,0 +1,71 @@ +.. Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/ .. +.. Contact: beat.support@idiap.ch .. +.. .. +.. This file is part of the beat.examples module of the BEAT platform. .. +.. .. +.. Commercial License Usage .. +.. Licensees holding valid commercial BEAT licenses may use this file in .. +.. accordance with the terms contained in a written agreement between you .. +.. and Idiap. For further information contact tto@idiap.ch .. +.. .. +.. Alternatively, this file may be used under the terms of the GNU Affero .. +.. Public License version 3 as published by the Free Software and appearing .. +.. in the file LICENSE.AGPL included in the packaging of this file. .. +.. The BEAT platform is distributed in the hope that it will be useful, but .. +.. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY .. +.. or FITNESS FOR A PARTICULAR PURPOSE. .. +.. .. +.. You should have received a copy of the GNU Affero Public License along .. +.. with the BEAT platform. If not, see http://www.gnu.org/licenses/. .. + + +=========================================== + LivDet 2013 Fingerprint Liveness Database +=========================================== + + +Changelog +========= + +* **Version 3**, 31/Oct/2017: + + - Port to beat.backend.python v1.4.2 + +* **Version 2**, 26/Jan/2016: + + - Port to Bob v2 + +* **Version 1**, 17/Sep/2015: + + - Initial release + + +Description +=========== + + +The LivDet 2013 `Fingerprint Liveness Database <http://livdet.org>`_ +[Ghiani2013]_ is a fingerprint liveness database which consists of four +sub-sets, which contain live and fake fingerprint images from four capture +devices. Images have been collected by a consensual approach and using +different materials for the artificial reproduction of the fingerprint +(gelatine, silicone, play-doh, ecoflex, body double, wood glue). + + +Data Set +======== + +========== =============== ========= ========== ============ ============ + Scanner Model Res (dpi) Image size Live samples Fake samples +========== =============== ========= ========== ============ ============ +Biometrika FX2000 569 312x372 2000 2000 +Italdata ET10 500 640x480 2000 2000 +Crossmatch L SCAN GUARDIAN 500 640x480 2500 2000 +Swipe 96 2374 1979 +========== =============== ========= ========== ============ ============ + + +References +========== + +.. [Ghiani2013] L.Ghiani, D.Yambay, V.Mura, S.Tocco, G.L.Marcialis, F.Roli, and S.Schuckers, LivDet 2013 - Fingerprint Liveness Detection Competition 2013, 6th IAPR/IEEE Int. Conf. on Biometrics, June, 4-7, 2013, Madrid (Spain).