Commit 3558cd46 authored by Philip ABBET's avatar Philip ABBET
Browse files

Add putvein/3

parent f1b34bab
This diff is collapsed.
###############################################################################
# #
# 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 numpy as np
import bob.io.base
import bob.io.image
import bob.db.putvein
import bob.ip.color
import os
class View:
def setup(self,
root_folder,
outputs,
parameters,
force_start_index=None,
force_end_index=None):
self.root_folder = os.path.join(root_folder, '')
self.outputs = outputs
self.parameters = parameters
self.db = bob.db.putvein.Database()
self.objs = sorted(self.db.objects(protocol=self.parameters['protocol'],
purposes=self.parameters.get('purpose', None),
groups=[self.parameters['group']],
kinds=[self.parameters['kind']]
),
key=lambda x: x.client_id)
self.next_index = 0
self.force_start_index = force_start_index
self.force_end_index = force_end_index
# Retrieve only 'useful' data
# End index
if self.force_end_index is not None:
self.objs = self.objs[:self.force_end_index+1]
# Start index
if self.force_start_index is not None:
self.objs = self.objs[self.force_start_index:]
self.next_index = self.force_start_index
else:
self.force_start_index = 0
self.previous_client_id = -1
return True
def done(self):
return (self.next_index-self.force_start_index >= len(self.objs))
def next(self):
obj = self.objs[self.next_index-self.force_start_index]
# Please pay attention - we can use CLIENT ID as long as we don't use
# same client both hand data in the same protocol. Currently this
# doesn't happen.
if self.outputs['client_id'].isConnected():
client_id = obj.get_client_id()
if client_id != self.previous_client_id:
# Search for the end index
end_index = self.next_index
while end_index + 1 - self.force_start_index < len(self.objs):
end_index += 1
obj2 = self.objs[end_index - self.force_start_index]
if obj2.get_client_id() != client_id:
break
self.outputs['client_id'].write({'value':
np.uint64(client_id)},
end_index)
self.previous_client_id = client_id
if self.outputs['image'].isConnected():
"""
The image returned by the ``bob.db.putvein`` is RGB (with shape
(3, 768, 1024)). This method converts image to a greyscale
(shape (768, 1024)) and then rotates image by 270 deg so that
images can be used with ``bob.bio.vein`` algorythms designed for
the ``bob.db.biowave_v1`` database.
Output images dimentions - (1024, 768).
"""
color_image = obj.load(self.root_folder)
grayscale_image = bob.ip.color.rgb_to_gray(color_image)
grayscale_image = np.rot90(grayscale_image, k=3)
data = {
'value': grayscale_image
}
self.outputs['image'].write(data, self.next_index)
self.next_index += 1
return True
class TemplateView:
# Reasoning: Each client may have a number of models in certain databases.
# So, each model receives an unique identifier. Those identifiers are
# linked to the client identifier and contain a number of images to
# generated the model from.
def setup(self,
root_folder,
outputs,
parameters,
force_start_index=None,
force_end_index=None):
self.root_folder = os.path.join(root_folder, '')
self.outputs = outputs
self.parameters = parameters
self.db = bob.db.putvein.Database()
self.template_ids = \
sorted(self.db.model_ids(protocol=self.parameters['protocol'],
groups=[self.parameters['group']],
kinds=[self.parameters['kind']]
))
self.objs = None
self.current_template_index = 0
self.current_obj_index = 0
self.next_index = 0
self.force_start_index = force_start_index
self.force_end_index = force_end_index
# We don't know how many objects we will have, so we can't operate with
# self.force_end_index.
if self.force_start_index is None:
self.force_start_index = 0
# Example taxen from atnt/3 - idea to iterate through ``next`` method
# to get indexes right
while self.next_index < self.force_start_index:
self.next()
return True
def done(self):
# return (self.next_index-self.force_start_index >= len(self.objs))
return ((self.current_template_index >= len(self.template_ids)) or
(self.force_end_index is not None and
self.force_end_index < self.next_index))
def next(self):
if self.objs is None:
# probe for the specific objects concerning a given client
self.objs = \
sorted(self.db.objects(protocol=self.parameters['protocol'],
purposes=self.parameters.get('purpose',
None),
groups=[self.parameters['group']],
kinds=[self.parameters['kind']],
model_ids=[self.template_ids[self.current_template_index]]),
key=lambda x: x.id)
if (self.force_start_index <= self.next_index and
(self.force_end_index is None or
self.force_end_index >= self.next_index)):
if self.outputs['model_id'].isConnected():
# for this database the
# ``self.template_ids[self.current_template_index]`` is the
# ``model_id``:
model_id = self.template_ids[self.current_template_index]
model_id = model_id.encode('utf-8')
self.outputs['model_id'].write({'text':
model_id},
self.next_index+len(self.objs)-1)
if self.outputs['client_id'].isConnected():
client_id = self.objs[0].get_client_id()
self.outputs['client_id'].write({'value':
np.uint64(client_id)},
self.next_index+len(self.objs)-1)
obj = self.objs[self.current_obj_index]
if self.outputs['image'].isConnected():
# This line is taken from the "atnt/3" database's view. It seams
# that this could cause problems, if model has N images, but
# ``self.force_end_index`` /= N*M, where M -- Natural number:
if (self.force_start_index <= self.next_index and
(self.force_end_index is None or
self.force_end_index >= self.next_index)):
# No need to test if output is connected:
# if self.outputs['image'].isConnected():
"""
The image returned by the ``bob.db.putvein`` is RGB (with shape
(3, 768, 1024)). This method converts image to a greyscale
(shape (768, 1024)) and then rotates image by 270 deg so that
images can be used with ``bob.bio.vein`` algorythms designed
for the ``bob.db.biowave_v1`` database.
Output images dimentions - (1024, 768).
"""
color_image = obj.load(self.root_folder)
grayscale_image = bob.ip.color.rgb_to_gray(color_image)
grayscale_image = np.rot90(grayscale_image, k=3)
data = {
'value': grayscale_image
}
self.outputs['image'].write(data, self.next_index)
self.next_index += 1
self.current_obj_index += 1
else:
self.next_index += len(self.objs)
self.current_obj_index = len(self.objs)
if self.current_obj_index == len(self.objs):
self.objs = None
self.current_obj_index = 0
self.current_template_index += 1
return True
"""
# test bob.db.putvein object compatibility with BEAT
import bob.db.putvein
db = bob.db.putvein.Database()
files = db.objects(protocol="RL_4", kinds="wrist", groups="dev", purposes="probe")
objects = sorted(files, key=lambda x: x.client_id)
for nr in range(len(files)):
print("{}-{}, sorted - {}-{}".format(files[nr].client_id, files[nr].nr, objects[nr].client_id, objects[nr].nr))
print(files == objects)
"""
.. Copyright (c) 2016 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/. ..
The PUT Vein Database
---------------------
Changelog
=========
* **Version 1**, 10/Feb/2016:
- Initial release
* **Version 2**, 10/Feb/2017:
- Major update to make database compatible with BIOWAVE database toolchains
* **Version 3**, 16/Oct/2017:
- Bugfix: Incorrect usage of the BEAT synchronization mechanism
Description
===========
PUT Vein pattern database consists of 2400 images presenting human vein
patterns. Half of images contains a palmar vein pattern (1200 images) and
another half contains a wrist vein pattern (another 1200 images). Data was
acquired from both hands of 50 students, with means it has a 100 different
patterns for palm and wrist region. Pictures ware taken in 3 series, 4 pictures
each, with at least one week interval between each series. In case of palm
region volunteers were asked to put his/her hand on the device to cover
acquisition window, in way that line below their fingers coincident with its
edge. No additional positioning systems ware used. In case of wrist region only
construction allowing to place palm and wrist in comfortable way was used to
help position a hand.
Original images have **768 x 1024** resolution and are saved as 24-bit bitmap.
Database consist of 2 main sections: hand and wrist, with are further divided
in persons. Each person folder has sub-sections for left and right hand, which
are separated into series.
More information about the original database - `PUT Vein database
<http://biometrics.put.poznan.pl/vein-dataset/>`_.
In order to enable to use the database with BIOWAVE toolchains, this database
implementation converts image to a grey-scale (shape (768, 1024)) and then
rotates images by 270 deg so that vein pattern in wrist images would appear
vertical (wrist's part closer to the palm would appear at the top of the image)
In this implementation we use both - original 50 client x 2 hand data - in the
database clients with IDs between ``1`` and ``50`` - and also - mirrored
file representations (left hand / palm data mirrored to look like right hand
data and vice versa) - clients with IDs between ``51`` and ``100``.
Protocols
=========
Currently (as on 10.02.2017) there are 10x2 protocols, they also match the
protocols in ``bob.bio.vein``:
- ``palm-L_4``,
- ``palm-R_4``,
- ``palm-RL_4``,
- ``palm-LR_4``,
- ``palm-R_BEAT_4``,
- ``palm-L_1``,
- ``palm-R_1``,
- ``palm-RL_1``,
- ``palm-LR_1``,
- ``palm-R_BEAT_1``,
- ``wrist-L_4``,
- ``wrist-R_4``,
- ``wrist-RL_4``,
- ``wrist-LR_4``,
- ``wrist-R_BEAT_4``,
- ``wrist-L_1``,
- ``wrist-R_1``,
- ``wrist-RL_1``,
- ``wrist-LR_1``,
- ``wrist-R_BEAT_1``.
Protocols (except the ``BEAT`` protocols) still contains the original protocol
(``L``, ``R``, ``RL``, ``LR``) data, the difference is, whether each enroll
model is constructed using all 4 hand's images (protocol name ends with ``4``),
or each enroll image is used as a model (corresponding protocol names ends with
``1``).
The original protocols consists of following data, ``world`` purpose dataset
consists of the **same** data, as ``dev`` purpose dataset, so won't be
separately described:
+-------------+-----------------------------------------+-------------------------------------------+
|**protocol** | ``dev`` | ``eval`` |
+-------------+-----------------------------------------+-------------------------------------------+
| L | IDs 1-25, un-mirrored left hand images | IDs 26-50, un-mirrored left hand images |
+-------------+-----------------------------------------+-------------------------------------------+
| R | IDs 1-25, un-mirrored right hand images | IDs 26-50, un-mirrored right hand images |
+-------------+-----------------------------------------+-------------------------------------------+
| RL | IDs 1-50, un-mirrored right hand images |IDs 51-100, mirrored left hand images |
| | |(to represent right hand) |
+-------------+-----------------------------------------+-------------------------------------------+
| LR | IDs 1-50, un-mirrored left hand images |IDs 51-100, mirrored right hand images |
| | |(to represent left hand) |
+-------------+-----------------------------------------+-------------------------------------------+
The new test protocols (ends with ``R_BEAT_1`` and ``R_BEAT_4``) are intended
for use with ``bob.bio.vein`` and ``BEAT`` platform for quick tests, if
necessary. Both protocols consist of such data:
+-------------+---------------------------------------------------------+------------------------------------------------------------+
|**protocol** | ``dev`` | ``eval`` |
+-------------+---------------------------------------------------------+------------------------------------------------------------+
| R_BEAT | IDs ``1``, ``2``, un-mirrored right hand / wrist images | IDs ``26``, ``27``, un-mirrored right hand / wrist images |
+-------------+---------------------------------------------------------+------------------------------------------------------------+
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment