Source code for bob.db.lfw.models

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# @author: Manuel Guenther <Manuel.Guenther@idiap.ch>
# @date: Thu May 24 10:41:42 CEST 2012
#
# Copyright (C) 2011-2012 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 LFW 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 LFW database.""" __tablename__ = 'client' id = Column(String(100), primary_key=True) def __init__(self, name): self.id = name def __lt__(self, other): """This function defines the order on the Client objects. Client objects are always ordered by their ID, in ascending order.""" return self.id < other.id def __repr__(self): return "<Client('%s')>" % self.id
[docs]class Annotation(Base): __tablename__ = 'annotation' annotation_type_choices = ('funneled', 'idiap') id = Column(Integer, primary_key=True) file_id = Column(Integer, ForeignKey('file.id')) annotation_type = Column(Enum(*annotation_type_choices)) annotations = Column(String(500)) def __init__(self, file_id, annotation_type, annotations): self.file_id = file_id assert annotation_type in self.annotation_type_choices self.annotation_type = annotation_type self.annotations = annotations def _extract_funneled(self): """Interprets the annotation string as if it came from the funneled images.""" splits = self.annotations.rstrip().split() assert len(splits) == 18 locations = ['reyeo', 'reyei', 'leyei', 'leyeo', 'noser', 'noset', 'nosel', 'mouthr', 'mouthl'] annotations = dict([(locations[i], (float(splits[2*i+1]), float(splits[2*i]))) for i in range(9)]) # add eye center annotations as the center between the eye corners annotations['leye'] = ((annotations['leyei'][0] + annotations['leyeo'][0])/2., (annotations['leyei'][1] + annotations['leyeo'][1])/2.) annotations['reye'] = ((annotations['reyei'][0] + annotations['reyeo'][0])/2., (annotations['reyei'][1] + annotations['reyeo'][1])/2.) return annotations def _extract_idiap(self): """Interprets the annotation string as if it came from the Idiap annotations.""" lines = self.annotations.rstrip().split('\n') annotations = {} for line in lines: splits = line.rstrip().split() if len(splits) == 2: # keyword annotation annotations[splits[0]] = splits[1] elif len(splits) == 3: # location annotation annotations[int(splits[0])] = (int(splits[2]), int(splits[1])) if 3 in annotations: annotations['reye'] = annotations[3] if 8 in annotations: annotations['leye'] = annotations[8] return annotations def __call__(self): """Interprets the annotation string and return a dictionary from location to (y,x), e.g. {'reye':(re_y, re_x), 'leye':(le_y,le_x)}""" if self.annotation_type == 'funneled': return self._extract_funneled() else: return self._extract_idiap()
def filename(client_id, shot_id): return client_id + "_" + "0"*(4-len(str(shot_id))) + str(shot_id)
[docs]class File(Base, bob.db.base.File): """Information about the files of the LFW database.""" __tablename__ = 'file' # Unique key identifier for the file; here we use strings id = Column(Integer, primary_key=True) # Unique name identifier for the file name = Column(String(100), unique=True) # Identifier for the client client_id = Column(String(100), ForeignKey('client.id')) # Unique path to this file inside the database path = Column(String(100)) # Identifier for the current image number of the client shot_id = Column(Integer) # a back-reference from file to client client = relationship("Client", backref=backref("files", order_by=id)) # many-to-one relationship between annotations and files annotations = relationship("Annotation", backref=backref("file", order_by=id, uselist=False)) def __init__(self, client_id, shot_id): # call base class constructor fn = filename(client_id, shot_id) bob.db.base.File.__init__(self, path = os.path.join(client_id, fn)) self.client_id = client_id self.shot_id = shot_id self.name = fn
[docs]class People(Base): """Information about the people (as given in the people.txt file) of the LFW database.""" __tablename__ = 'people' id = Column(Integer, primary_key=True) protocol = Column(Enum('train', 'test', 'fold1', 'fold2', 'fold3', 'fold4', 'fold5', 'fold6', 'fold7', 'fold8', 'fold9', 'fold10', 'view2')) file_id = Column(String(100), ForeignKey('file.id')) def __init__(self, protocol, file_id): self.protocol = protocol self.file_id = file_id def __repr__(self): return "<People('%s', '%s')>" % (self.protocol, self.file_id)
[docs]class Pair(Base): """Information of the pairs (as given in the pairs.txt files) of the LFW database.""" __tablename__ = 'pair' id = Column(Integer, primary_key=True) # train and test for view1, the folds for view2 protocol = Column(Enum('train', 'test', 'fold1', 'fold2', 'fold3', 'fold4', 'fold5', 'fold6', 'fold7', 'fold8', 'fold9', 'fold10', 'view2')) enroll_file_id = Column(String(100), ForeignKey('file.id')) probe_file_id = Column(String(100), ForeignKey('file.id')) enroll_file = relationship("File", backref=backref("enroll_files", order_by=id), primaryjoin="Pair.enroll_file_id==File.id") probe_file = relationship("File", backref=backref("probe_files", order_by=id), primaryjoin="Pair.probe_file_id==File.id") is_match = Column(Boolean) def __init__(self, protocol, enroll_file_id, probe_file_id, is_match): self.protocol = protocol self.enroll_file_id = enroll_file_id self.probe_file_id = probe_file_id self.is_match = is_match def __repr__(self): return "<Pair('%s', '%s', '%s', '%d')>" % (self.protocol, self.enroll_file_id, self.probe_file_id, 1 if self.is_match else 0)