Source code for bob.db.scface.models

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Laurent El Shafey <laurent.el-shafey@idiap.ch>
#
# 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 SCFace database.
"""

import bob.db.base.utils
from sqlalchemy import Table, Column, Integer, Boolean, String, 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

Base = declarative_base()

subworld_client_association = Table('subworld_client_association', Base.metadata,
  Column('subworld_id', Integer, ForeignKey('subworld.id')),
  Column('client_id',  Integer, ForeignKey('client.id')))

protocolPurpose_file_association = Table('protocolPurpose_file_association', Base.metadata,
  Column('protocolPurpose_id', Integer, ForeignKey('protocolPurpose.id')),
  Column('file_id',  Integer, ForeignKey('file.id')))

[docs]class Client(Base): """Database clients, marked by an integer identifier and the group they belong to""" __tablename__ = 'client' # Key identifier for the client id = Column(Integer, primary_key=True) # Group to which the client belongs to group_choices = ('dev','eval','world') sgroup = Column(Enum(*group_choices)) # do NOT use group (SQL keyword) # Birthyear of the client birthyear = Column(Integer) # Gender to which the client belongs to gender_choices = ('m','f') gender = Column(Enum(*gender_choices)) # Does he has a beard? beard = Column(Boolean) # Does he has a moustache? moustache = Column(Boolean) # Does he has glasses? glasses = Column(Boolean) def __init__(self, id, group, birthyear, gender, beard, moustache, glasses): self.id = id self.sgroup = group self.birthyear = birthyear self.gender = gender self.beard = beard self.moustache = moustache self.glasses = glasses def __repr__(self): return "Client(%d, '%s')" % (self.id, self.sgroup)
[docs]class Subworld(Base): """Database clients belonging to the world group are split in two disjoint subworlds, onethird and twothirds""" __tablename__ = 'subworld' # Key identifier for this Subworld object id = Column(Integer, primary_key=True) # Subworld to which the client belongs to name = Column(String(20), unique=True) # for Python: A direct link to the client clients = relationship("Client", secondary=subworld_client_association, backref=backref("subworld", order_by=id)) def __init__(self, name): self.name = name def __repr__(self): return "Subworld('%s')" % (self.name)
[docs]class File(Base, bob.db.base.File): """Generic file container""" __tablename__ = 'file' # Key identifier for the file id = Column(Integer, primary_key=True) # Key identifier of the client associated with this file client_id = Column(Integer, ForeignKey('client.id')) # for SQL # Unique path to this file inside the database path = Column(String(100), unique=True) # Camera identifier camera = Column(String(8)) # Distance identifier distance = Column(Integer) # For Python: A direct link to the client object that this file belongs to client = relationship("Client", backref=backref("files", order_by=id)) annotation = relationship("Annotation", backref=backref("file", order_by=id, uselist=False), uselist=False) def __init__(self, client_id, path, camera, distance): # call base class constructor bob.db.base.File.__init__(self, path = path) self.client_id = client_id # set the remaining information of the file self.camera = camera self.distance = distance
[docs]class Annotation(Base): """Annotations of the SC face database consists of the left and right eye positions as well as the nose tip and the center of the mouth. 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) n_x = Column(Integer) # nose tip n_y = Column(Integer) m_x = Column(Integer) # mouth center m_y = Column(Integer) def __init__(self, file_id, annotations): self.file_id = file_id assert len(annotations) == 8 self.re_x = int(annotations[0]) self.re_y = int(annotations[1]) self.le_x = int(annotations[2]) self.le_y = int(annotations[3]) self.n_x = int(annotations[4]) self.n_y = int(annotations[5]) self.m_x = int(annotations[6]) self.m_y = int(annotations[7]) 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), 'nose' : (self.n_y, self.n_x), 'mouth' : (self.m_y, self.m_x) } def __repr__(self): return "<Annotation('%s': 'reye'=%dx%d, 'leye'=%dx%d, 'nose'=%dx%d, 'mouth'=%dx%d)>" % (self.file_id, self.re_y, self.re_x, self.le_y, self.le_x,self.n_y, self.n_x, self.m_y, self.m_x)
[docs]class Protocol(Base): """SCface protocols""" __tablename__ = 'protocol' # Unique identifier for this protocol object id = Column(Integer, primary_key=True) # Name of the protocol associated with this object name = Column(String(20), unique=True) def __init__(self, name): self.name = name def __repr__(self): return "Protocol('%s')" % (self.name,)
[docs]class ProtocolPurpose(Base): """SCface protocol purposes""" __tablename__ = 'protocolPurpose' # Unique identifier for this protocol purpose object id = Column(Integer, primary_key=True) # Id of the protocol associated with this protocol purpose object protocol_id = Column(Integer, ForeignKey('protocol.id')) # for SQL # Group associated with this protocol purpose object group_choices = ('world', 'dev', 'eval') sgroup = Column(Enum(*group_choices)) # Purpose associated with this protocol purpose object purpose_choices = ('train', 'enroll', 'probe') purpose = Column(Enum(*purpose_choices)) # For Python: A direct link to the Protocol object that this ProtocolPurpose belongs to protocol = relationship("Protocol", backref=backref("purposes", order_by=id)) # For Python: A direct link to the File objects associated with this ProtcolPurpose files = relationship("File", secondary=protocolPurpose_file_association, backref=backref("protocol_purposes", order_by=id)) def __init__(self, protocol_id, sgroup, purpose): self.protocol_id = protocol_id self.sgroup = sgroup self.purpose = purpose def __repr__(self): return "ProtocolPurpose('%s', '%s', '%s')" % (self.protocol.name, self.sgroup, self.purpose)