Source code for pysteg.sql.imageset

#! /usr/bin/env python
## -*- coding: utf-8 -*-
## (C) 2012: Hans Georg Schaathun <georg@schaathun.net> 

"""
Functions to load image sets into the database and define
test and training sets.

This is rather crude and it may be better to consult the scripts
to see how the functions are used.
"""

from . import *
import os
import numpy.random as rnd
import numpy as np
from .aux import isDuplicateError
rnd.seed()
import ConfigParser 

__all__ = [ "loadImages", "similarTestSet", "makeTestSets",
      "groupTestSet", "dummyTestSet", ]

[docs]def loadImages( fn ): """ Define image sets based on a config file with the given filename fn. """ cfg = ConfigParser.SafeConfigParser( ) cfg.read( fn ) for s in cfg.sections(): kw = { "name" : s } for o in cfg.options(s): kw[o] = cfg.get(s,o) if kw.has_key("source"): kw["source"] = ImageSet.byName( kw["source"] ) try: S = ImageSet( **kw ) except Exception as e: print type(e) print e print "Not allowed to add ImageSet", kw["name"] pass else: submitImages(S) return
def submitImages( imgset ): """ Submit images to an ImageSet object imgset by reading the filenames directly from the file system. If source is given, it should be another ImageSet containing source images. The individual source images for each derived image is defined by the file basename and linked. """ verbosity = config.getVerbosity( "sql" ) dir = imgset.getPath() fl = os.listdir( dir ) ext = imgset.extension src = imgset.source for fn in fl: (fbase,fext) = fn.split( ".", 1 ) if ext != None and ext != fext: continue if src: source = src.getBasename( fbase ) if verbosity > 2: print "From", source img = Image( filename=fn, imageset=imgset, source=source ) else: img = Image( filename=fn, imageset=imgset ) if verbosity > 1: print img return
[docs]def similarTestSet( base, stego, name, incomplete=False ): """ Create a new TestSet based on base, but using stego images from stego instead. The same random selection is used as in bane. (Not tested.) """ T = TestSet( name=name ) for img in base.testimg: basename = img.getBasename() if img.label == 0: r = TestImage( image=img.image, imagesetID=T, label=0 ) print img.image print r else: ext = stego.extension try: st = Image.selectBy( imageset=stego, filename=basename+"."+ext ).getOne() except: if incomplete: print "Missing stego image:", basename else: raise else: r = TestImage( image=st, imagesetID=T, label=1 ) print st print r return T
[docs]def makeTestSets( clean, stego, name, testname=None, testsize=None, trainsize=None,skew=0.5 ): """ Given two image sets for clean images and steganograms respectively, training and test sets are constructed randomly. It is assumed that both clean and stego contain corresponding images with the same basename, and if a clean image is included, the corresponding stego images is excluded, and vice versa. """ if testname == None: testname = name + "_test" try: train = TestSet( name=name ) test = TestSet( name=testname ) except StandardError as e: if not isDuplicateError(e): raise print "Warning! Sets already existed" train = TestSet.byName( name ) test = TestSet.byName( testname ) return (train,test) # Catch errors here img = rnd.permutation(list(clean.images)) totalsize = len(img) if testsize == None and trainsize == None: testsize = np.floor( totalsize / 2 ) trainsize = np.ceil( totalsize / 2 ) if testsize != None and testsize <= 1: testsize = testsize*totalsize if trainsize != None and trainsize <= 1: testsize = testsize*totalsize if testsize == None: testsize = totalsize - trainsize if trainsize == None: trainsize = totalsize - testsize popTestSet( train, img[:trainsize], stego, skew ) popTestSet( test, img[trainsize:(testsize+trainsize)], stego, skew ) return (train,test)
[docs]def dummyTestSet( name, L ): """ Create a dummy TestSet by combining all images from every image set in L. All the test images are given the label 1. This is mainly intended to form a set of images for which classification scores can be calculated in bulk, and not as a test or training set as such. """ T = TestSet( name=name ) for ims in L: I = getImageSet(ims) popTestSet( T, list(I), None, 1 )
def filter( name, tset, L ): T = TestSet( name=name ) if not isinstance(tset,SQLObject): tset = getImageSet(tset) if isinstance(L,str): L = getImageSet(L) if isinstance(L,SQLObject): L = [ im.getBasename() for im in L ] for im in tset: if im.getBasename() in L: print TestImage( image=im(), imageset=T, label=im.label, response=im.response ) def popTestSet( set, images, stego, skew ): """Populate a Test or Training Set with images from a list. This is an auxiliary function for makeTestSets().""" N = len(images) N1 = N*skew print type(set), N, N1 for img in images[:N1]: TestImage( image=img, imagesetID=set, label=0 ) for img0 in images[N1:]: img = stego.getBasename( img0.getBasename() ) TestImage( image=img, imagesetID=set, label=1 )
[docs]def groupTestSet( set, name, feature, min=None, max=None, create=True, **kw ): """Return a new TestSet object with the given name, created by taking the images from set which satisfy min <= feature < max. If min or max is None, it poses no constraint. """ L = [ (im,im.getOneFeature(feature)) for im in set ] if max == None: c = lambda v : ( v >= min ) elif min == None: c = lambda v : v < max else: c = lambda v : v < max and v >= min V = [ v for (im,v) in L ] L = [ (im,v) for (im,v) in L if c(v) ] if create: tset = TestSet( name=name, **kw ) for (im,v) in L: im.copy(tset) return tset else: return len(L)