Commit f7531212 authored by Manuel Günther's avatar Manuel Günther

Integrated eye annotations.

parent 86317b81
......@@ -88,6 +88,29 @@ def add_files(session, imagedir, verbose):
basename, extension = os.path.splitext(filename)
add_file(session, basename, camera, verbose)
def add_annotations(session, annotdir, verbose):
"""Reads the annotation files and adds the annotations to the .sql3 database."""
def read_annotation(filename, file_id):
# read the eye positions, which are stored as four integers in one line
line = open(filename, 'r').readline()
positions = line.split()
assert len(positions) == 4
return Annotation(file_id, positions)
# iterate though all stored images and try to access the annotations
session.flush()
if verbose: print("Adding annotations...")
files = session.query(File)
for f in files:
annot_file = f.make_path(annotdir, '.pos')
if os.path.exists(annot_file):
if verbose>1: print(" Adding annotation '%s'..." %(annot_file, ))
session.add(read_annotation(annot_file, f.id))
else:
print("Could not locate annotation file '%s'" % annot_file)
def add_protocols(session, verbose):
"""Adds protocols"""
......@@ -180,6 +203,7 @@ def create(args):
s = session_try_nolock(args.type, args.files[0], echo=(args.verbose > 2))
add_clients(s, args.verbose)
add_files(s, args.imagedir, args.verbose)
add_annotations(s, args.annotdir, args.verbose)
add_protocols(s, args.verbose)
s.commit()
s.close()
......@@ -192,5 +216,6 @@ def add_command(subparsers):
parser.add_argument('-R', '--recreate', action='store_true', help="If set, I'll first erase the current database")
parser.add_argument('-v', '--verbose', action='count', help="Do SQL operations in a verbose way")
parser.add_argument('-D', '--imagedir', metavar='DIR', default='/idiap/group/biometric/databases/biosecure/', help="Change the relative path to the directory containing the images of the Biosecure database.")
parser.add_argument('-A', '--annotdir', metavar='DIR', default='/idiap/group/biometric/annotations/biosecure/EyesPosition', help="Change the relative path to the directory containing the annotations of the BANCA database (defaults to %(default)s)")
parser.set_defaults(func=create) #action
......@@ -84,6 +84,37 @@ class File(Base, bob.db.verification.utils.File):
self.camera = camera
self.shot_id = shot_id
class Annotation(Base):
"""Annotations of the BioSecure database consists only of the left and right eye positions.
There is exactly one annotation for each file."""
__tablename__ = 'annotation'
id = Column(Integer, primary_key=True)
file_id = Column(Integer, ForeignKey('file.id'))
le_x = Column(Integer) # left eye
le_y = Column(Integer)
re_x = Column(Integer) # right eye
re_y = Column(Integer)
def __init__(self, file_id, eyes):
self.file_id = file_id
assert len(eyes) == 4
self.re_x = int(eyes[0])
self.re_y = int(eyes[1])
self.le_x = int(eyes[2])
self.le_y = int(eyes[3])
def __call__(self):
"""Returns the annotations of this database in a dictionary: {'reye' : (re_y, re_x), 'leye' : (le_y, le_x)}."""
return {'reye' : (self.re_y, self.re_x), 'leye' : (self.le_y, self.le_x) }
def __repr__(self):
return "<Annotation('%s': 'reye'=%dx%d, 'leye'=%dx%d)>" % (self.file_id, self.re_y, self.re_x, self.le_y, self.le_x)
class Protocol(Base):
"""Biosecure protocols"""
......
......@@ -204,6 +204,27 @@ class Database(bob.db.verification.utils.SQLiteDatabase):
return list(set(retval)) # To remove duplicates
def annotations(self, file_id):
"""Returns the annotations for the image with the given file id.
Keyword Parameters:
file_id
The id of the File object to retrieve the annotations for.
Returns: the eye annotations as a dictionary {'reye':(y,x), 'leye':(y,x)}.
"""
self.assert_validity()
query = self.query(Annotation).join(File).filter(File.id==file_id)
assert query.count() == 1
annotation = query.first()
# return the annotations as returned by the call function of the Annotation object
return annotation()
def protocol_names(self):
"""Returns all registered protocol names"""
......
......@@ -58,6 +58,22 @@ def test_objects():
# TODO: more specific tests
@db_available
def test_annotations():
# Tests that for all files the annotated eye positions exist and are in correct order
db = bob.db.biosecure.Database()
for f in db.objects():
annotations = db.annotations(f.id)
assert annotations is not None
assert len(annotations) == 2
assert 'leye' in annotations
assert 'reye' in annotations
assert len(annotations['reye']) == 2
assert len(annotations['leye']) == 2
# assert that the eye positions are not exchanged
assert annotations['leye'][1] > annotations['reye'][1]
@db_available
def test_driver_api():
......
......@@ -11,6 +11,24 @@
Documentation
-------------
This package contains the face verification protocol for the DS2 Still face image part of the BioSecure database.
The images themselves are not provided in this package, they can be obtained via: http://biosecure.it-sudparis.eu/AB
Included in this package, there are eye annotations that were automatically detected using the `VeriLook SDK 4.0 from Neurotechnology <http://www.neurotechnology.com/verilook.html>`_.
When you use the annotations in a scientific publication, please cite::
@INPROCEEDINGS {marta14FaceBF,
author = {M. Gomez-Barrero and C. Rathgeb and J. Galbally and J. Fierrez and C. Busch},
title = {Protected Facial Biometric Templates Based on Local Gabor Patterns and Adaptive Bloom Filters},
booktitle = {Proc. IAPR/IEEE Int. Conf. on Pattern Recognition, ICPR},
month = {August},
pages = {4483-4488},
year = {2014},
}
.. toctree::
:maxdepth: 2
......
Markdown is supported
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