Source code for bob.db.arface.models

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# @author: Manuel Guenther <Manuel.Guenther@idiap.ch>
# @date:   Wed Jul  4 14:12:51 CEST 2012
#
# Copyright (C) 2011-2013 Idiap Research Institute, Martigny, Switzerland
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program 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.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""Table models and functionality for the AR face database.
"""

import sqlalchemy
from sqlalchemy import Column, Integer, String, Boolean, ForeignKey, or_, and_, not_
from bob.db.base.sqlalchemy_migration import Enum, relationship
from sqlalchemy.orm import backref
from sqlalchemy.ext.declarative import declarative_base

import bob.db.base

import os

Base = declarative_base()


[docs]class Client(Base): """Information about the clients (identities) of the AR face database""" __tablename__ = 'client' # We define the possible values for the member variables as STATIC class # variables gender_choices = ('m', 'w') group_choices = ('world', 'dev', 'eval') id = Column(String(100), primary_key=True) gender = Column(Enum(*gender_choices)) sgroup = Column(Enum(*group_choices)) def __init__(self, id, group): self.id = id self.gender = id[0:1] self.sgroup = group def __repr__(self): return "<Client('%s')>" % self.id
[docs]class File(Base, bob.db.base.File): """Information about the files of the AR face database. Each file includes * the session (first, second) * the expression (neutral, smile, anger, scream) * the illumination (front, left, right, all) * the occlusion (none, sunglasses, scarf) * the client id """ __tablename__ = 'file' # We define the possible values for the member variables as STATIC class # variables session_choices = ('first', 'second') purpose_choices = ('enroll', 'probe') expression_choices = ('neutral', 'smile', 'anger', 'scream') illumination_choices = ('front', 'left', 'right', 'all') occlusion_choices = ('none', 'sunglasses', 'scarf') id = Column(String(100), primary_key=True) path = Column(String(100), unique=True) client_id = Column(String(100), ForeignKey('client.id')) session = Column(Enum(*session_choices)) purpose = Column(Enum(*purpose_choices)) expression = Column(Enum(*expression_choices)) illumination = Column(Enum(*illumination_choices)) occlusion = Column(Enum(*occlusion_choices)) # a back-reference from the client class to a list of files client = relationship("Client", backref=backref("files", order_by=id)) annotation = relationship( "Annotation", backref=backref("file"), uselist=False) def __init__(self, image_name): # call base class constructor bob.db.base.File.__init__(self, path=image_name, file_id=image_name) self.client_id = image_name[:5] # get shot id shot_id = int(os.path.splitext(image_name)[0][6:]) # automatically fill member variables according to shot id self.session = self.session_choices[int((shot_id - 1) / 13)] shot_id = (shot_id - 1) % 13 + 1 self.purpose = self.purpose_choices[0 if shot_id == 1 else 1] self.expression = self.expression_choices[ shot_id - 1] if shot_id in (2, 3, 4) else self.expression_choices[0] self.illumination = self.illumination_choices[shot_id - 4] if shot_id in (5, 6, 7) else \ self.illumination_choices[shot_id - 8] if shot_id in (9, 10) else \ self.illumination_choices[shot_id - 11] if shot_id in (12, 13) else \ self.illumination_choices[0] self.occlusion = self.occlusion_choices[1] if shot_id in (8, 9, 10) else \ self.occlusion_choices[2] if shot_id in (11, 12, 13) else \ self.occlusion_choices[0]
[docs]class Annotation(Base): """Annotations of the AR face 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)
[docs]class Protocol(Base): """The protocols of the AR face database.""" __tablename__ = 'protocol' protocol_choices = ('all', 'expression', 'illumination', 'occlusion', 'occlusion_and_illumination') id = Column(Integer, primary_key=True) name = Column(Enum(*protocol_choices)) session = Column(Enum(*File.session_choices), ForeignKey('file.session')) expression = Column(Enum(*File.expression_choices), ForeignKey('file.expression')) illumination = Column(Enum(*File.illumination_choices), ForeignKey('file.illumination')) occlusion = Column(Enum(*File.occlusion_choices), ForeignKey('file.occlusion')) def __init__(self, protocol, session, expression='neutral', illumination='front', occlusion='none'): self.name = protocol self.session = session self.expression = expression self.illumination = illumination self.occlusion = occlusion def __repr__(self): return "<Protocol('%s', '%s', '%s', '%s', '%s')>" % (self.name, self.session, self.expression, self.illumination, self.occlusion)