Source code for bob.db.casme2.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
#
# @modifying_author: Abdullahi Adamu <research.abdullah@gmail.com>
#
# 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 CASME2 database adopted from the
"""

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 CASME2 database""" __tablename__ = 'client' # Group to which the client belongs to # NOTES: though this groups have been defined, due to the imbalanced nature of the dataset, its advised to combine all # the groups into one, perform dataset imabalance correction and then perform #group_choices = ('dev', 'eval', 'world'); id = Column(Integer, primary_key=True); #The subject ID as in the file #sgroup = Column(Enum(*group_choices)); def __init__(self, id): self.id = id #self.sgroup = sgroup; def __repr__(self): return "Client<(%d, '%s')>" % (self.id)
#return "Client<(%d, '%s', '%s')>" % (self.id, self.sgroup)
[docs]class File(Base,bob.db.base.File ): """ NOTE:this interface is the variant of the CASME2 database which does not use the video files, but rather the ones converted into frames of images. (i.e. the ones in the "CROPPED" folder). As such, this folder is supposed to be an abstract representation of the video file - in this case, its a fodler containing the video frames. This is represent the video file directory containing the frames. * the emotions ('happiness', 'repression', 'disgust', 'surprise', 'sadness', 'others') for the client * the client id, in this case, each file is a frame in the video """ __tablename__ = 'file' # The definitions of the various emotions/expressions from the micro-expression databse in CASME2 emotion_choices = ('happiness', 'repression', 'disgust', 'surprise', 'sadness', 'fear', 'others'); ###### COLUMNS ######### id = Column(Integer, primary_key=True,autoincrement= True); #path to the file directory, in this case - its the path to the folder containing the frames path = Column(String); #directory containing the video frames for the CASME2 database #client in the file client_id = Column(Integer, ForeignKey('client.id')); #emotion expressed in the file emotion = Column(Enum(*emotion_choices)); #onset of the emotion onset = Column(Integer); #apex of the emotion apex = Column(Integer); #offset of the emotions offset = Column(Integer); ##### RELATIONSHIPS ##### # a back-reference from the client class to a list of files client = relationship("Client", backref=backref("files", order_by=id)) def __init__(self, client_id, path, emotion, onset, apex, offset): # call base class constructor bob.db.base.File.__init__(self, path = path) self.client_id = client_id; self.path = path; self.emotion = emotion; #emotion self.onset =onset; #onset self.apex = apex; #apex self.offset = offset; #offset def __repr__(self): return "<File(filename:'%s', Client_id:'%s, emotion:'%s', onset: %d, apex: %d, offset: %d)>" % ( self.path,self.client_id, self.emotion, self.onset, self.apex, self.offset );
[docs]class Frame(Base, bob.db.base.File): """ This is represents the frames in the video file (in this case, contained in the folder) It contains the sequence of frames for each file recorded for the subjects in CASME2 """ __tablename__ = 'frame' id = Column(Integer, primary_key=True, autoincrement= True); client_id = Column(Integer, ForeignKey('client.id')); # the client id the fram belongs to frame_no = Column('frame_no', Integer); # the frame number file_id = Column(Integer,ForeignKey("file.id")); #file id the frame belongs to filename = Column(String) # the filename of the jpeg image file - i.e. the frame itself. # a back-reference from the client class to a list of files files = relationship("File", backref=backref("frames", order_by=frame_no)) def __init__(self, path,client_id, file_id, frame_no, filename): # call base class constructor bob.db.base.File.__init__(self, path = path) self.client_id = client_id #set the variables self.file_id = file_id; self.frame_no = frame_no; self.filename = filename; def __repr__(self): #returns representation in string form return "Frame<(file_id: %d, frame_no: %d)>" % (self.file_id, self.frame_no);
class ActionUnits(Base): __tablename__ = 'actionunits' #In this part, we describe the facial action units. There is a prefix attached to the action unit which describes # the side of the face which the action unit is activated. For example AU2L, means action unit 2 on the left part of # the face, # R - Right side of the face # L - Left side of the face #In addition to that, -1 is used for the apex column of one of the subjects which is supposed to represent an undecided', # or unavailable option. id = Column(Integer, primary_key= True, autoincrement= True); file_id = Column(Integer, ForeignKey('file.id')); actionunit = Column(String); actionunits = relationship("File", backref=backref("actionunits", order_by=id)); def __repr__(self): return "<ActionUnit(file_id: %d, value: %s)" % (self.file_id, self.actionunit);
[docs]class Protocol(Base): """The protocols of the CASME2 database.""" __tablename__ = 'protocol' protocol_choices = [] for i in range(1,27): protocol_choices.append("fold_{0}".format(str(i))) #id = Column(Integer, primary_key=True, autoincrement= True) name = Column(Enum(*protocol_choices), primary_key=True) def __init__(self, protocol): self.name = protocol def __repr__(self): return "<Protocol('%s')>" % ( self.name)
class ClientxProtocol(Base): """Cross table between client and protocol.""" __tablename__ = 'clientXprotocol' groups = ('train','test') id = Column(Integer, primary_key=True, autoincrement= True) client_id = Column(Integer, ForeignKey('client.id')); # the client id the fram belongs to protocol_id = Column(String, ForeignKey('protocol.name')); # the protocol id the fram belongs to group = Column(Enum(*groups)) #The purpose of the client def __init__(self, client_id, protocol_id, group): self.protocol_id = protocol_id self.client_id = client_id self.group = group def __repr__(self): return "<ClientxProtocol('%s','%s','%s')>" % ( self.protocol_id, self.client_id, self.group)