#! /usr/bin/env python
## -*- coding: utf-8 -*-
## (C) 2012: Hans Georg Schaathun <georg@schaathun.net>
"""
This modules provide functions to define new features, feature
vectors, and feature sets, including feature level fusion.
The functions :func:`fsconfig` and :func:`fvconfig` read
definitions from a config file and enter them into the database.
"""
import ConfigParser
from . import *
from pysteg.features import *
__all__ = [ "fsconfig", "fvconfig" ]
def getFeatureCollection(key):
"""Look up a feature collection by key. If the key is itself
an SQLObject, this is returned as is. Otherwise, the FeatureVector
object is tried first, and then the FeatureSet table. At last,
the Feature table is checked, and if the key matches a feature,
this is returned as a singleton list."""
if isinstance(key,SQLObject):
return key
try:
return FeatureVector.byKey( key )
except:
pass
try:
return FeatureSet.byKey( key )
except:
return [ Feature.byKey( key ) ]
return f
def _idxgen(T,d):
R = range(-T,T+1)
if d == 1: return [ (i,) for i in R ]
else:
return [ x + (i,) for x in _idxgen(T,d-1) for i in R ]
def _add2d(fs,x,y):
L = [ fs.key + "(%s,%s)" % (i,j) for i in range(x) for j in range(y) ]
for key in L:
Feature( cat=fs, key=key )
return
def addmatrix(fs,limit,dim):
if dim == 1: return _add1d(fs,limit)
if dim == 2: return _add2d(fs,limit,limit)
raise TypeError, "Undefined dimension %s (%s)" % ( dim, type(dim) )
def _addsym(fs,T,d):
for idx in _idxgen(T,d):
key = fs.key + str(idx).replace(" ","")
Feature( cat=fs, key=key )
return
def _add1d(fs,N):
for i in xrange(N):
Feature( cat=fs, key=fs.key+"(%s)" % (i,) )
return
def _addNames(fs,l):
for n in l:
Feature( cat=fs, key=n )
return
[docs]def fsconfig( fn ):
"""
Define feature sets based on a config file with the given filename fn.
"""
cfg = ConfigParser.SafeConfigParser( )
cfg.read( fn )
for s in cfg.sections():
kw = { "key" : s }
kw["func"] = cfg.get(s,"func")
try:
kw["description"] = cfg.get(s,"description")
kw["jpeg"] = eval(cfg.get(s,"jpeg"))
except ConfigParser.NoOptionError:
pass
scheme = cfg.get(s,"scheme")
if scheme == "named":
kw["matrix"] = False
kw["symidx"] = False
addFeatures = lambda : _addNames(fs,eval(kw["func"])(None))
elif scheme == "2d":
kw["matrix"] = True
kw["symidx"] = False
(x,y) = eval(cfg.get(s,"limit"))
addFeatures = lambda : _add2d(fs,x,y)
elif scheme == "matrix":
kw["matrix"] = True
kw["symidx"] = False
limit = eval(cfg.get(s,"limit"))
dim = eval(cfg.get(s,"dimension"))
addFeatures = lambda : addmatrix(fs, limit, dim)
elif scheme == "sym":
kw["matrix"] = True
kw["symidx"] = True
limit = eval(cfg.get(s,"limit"))
dim = eval(cfg.get(s,"dimension"))
addFeatures = lambda : _addsym(fs,limit,dim)
else:
raise ConfigError, "Unknown scheme"
try:
fs = FeatureSet( **kw )
except Exception as e:
print type(e)
print e
print "Not allowed to add FeatureSet", kw["key"]
pass
else:
addFeatures()
return
[docs]def fvconfig( fn ):
"""
Define feature vectors based on a config file with the given filename fn.
"""
cfg = ConfigParser.SafeConfigParser( )
cfg.read( fn )
for s in cfg.sections():
kw = { "key" : s }
features = None
for o in cfg.options(s):
if o == "features":
features = cfg.get(s,o).split()
elif o == "dim":
kw["dim"] = int(cfg.get(s,o))
else:
kw[o] = cfg.get(s,o)
if features == None:
raise ConfigError, "No features defined."
try:
fv = FeatureVector( **kw )
except Exception as e:
print type(e)
print e
print "Not allowed to add FeatureVector", kw["key"]
pass
else:
for fkey in features:
if fkey == "": continue
fs = getFeatureCollection(fkey)
for f in fs: fv.addFeature(f)
return