Commit 1b555c5d authored by Manuel Günther's avatar Manuel Günther

Included the hand-labeled eye annotations into the SQL database.

parent 697db6fd
......@@ -9,7 +9,7 @@ from setuptools import setup, find_packages
setup(
name='xbob.db.banca',
version='1.0.3',
version='1.1.0',
description='BANCA Database Access API for Bob',
url='http://github.com/bioidiap/xbob.db.banca',
license='GPLv3',
......
......@@ -40,6 +40,30 @@ def add_files(session, imagedir, verbose):
for filename in file_list:
add_file(session, subdir, os.path.join(imagedir, filename), client_dict, verbose)
def add_annotations(session, annotdir, verbose):
"""Add files (and clients) to the BANCA 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_subworlds(session, verbose):
"""Adds splits in the world set, based on the client ids"""
......@@ -200,6 +224,7 @@ def create(args):
create_tables(args)
s = session_try_nolock(args.type, args.files[0], echo=(args.verbose > 2))
add_files(s, args.imagedir, args.verbose)
add_annotations(s, args.annotdir, args.verbose)
add_subworlds(s, args.verbose)
add_protocols(s, args.verbose)
s.commit()
......@@ -213,5 +238,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/banca/english/images/images/', help="Change the relative path to the directory containing the images of the BANCA database (defaults to %(default)s)")
parser.add_argument('-A', '--annotdir', metavar='DIR', default='/idiap/group/biometric/annotations/banca/english/images/annotations/', 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
......@@ -99,6 +99,35 @@ class File(Base, xbob.db.verification.utils.File):
self.shot_id = shot_id
self.session_id = session_id
class Annotation(Base):
"""Annotations of the BANCA 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):
"""BANCA protocols"""
......
......@@ -454,6 +454,27 @@ class Database(xbob.db.verification.utils.SQLiteDatabase, xbob.db.verification.u
zgroups.append('dev')
return self.objects(protocol, 'probe', model_ids, zgroups, None, languages)
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"""
......
......@@ -73,7 +73,23 @@ class BancaDatabaseTest(unittest.TestCase):
self.assertEqual(len(db.zobjects(groups=group, model_ids=model_id)), 105)
def test03_driver_api(self):
def test03_annotations(self):
# Tests that for all files the annotated eye positions exist and are in correct order
db = xbob.db.banca.Database()
for f in db.objects():
annotations = db.annotations(f.id)
self.assertTrue(annotations is not None)
self.assertEqual(len(annotations), 2)
self.assertTrue('leye' in annotations)
self.assertTrue('reye' in annotations)
self.assertEqual(len(annotations['reye']), 2)
self.assertEqual(len(annotations['leye']), 2)
# assert that the eye positions are not exchanged
self.assertGreater(annotations['leye'][1], annotations['reye'][1])
def test04_driver_api(self):
from bob.db.script.dbmanage import main
self.assertEqual(main('banca dumplist --self-test'.split()), 0)
......
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