From c8c06b23623343976efc7555f5902245d827f56e Mon Sep 17 00:00:00 2001 From: Manuel Guenther <manuel.guenther@idiap.ch> Date: Wed, 3 Jun 2015 17:37:55 +0200 Subject: [PATCH] Added baselines script; lots of small corrections --- bob/bio/face/__init__.py | 1 + bob/bio/face/algorithm/GaborJet.py | 2 +- bob/bio/face/config/algorithm/bic_jets.py | 25 ++ bob/bio/face/config/database/xm2vts.py | 2 +- .../face/config/preprocessor/face_detect.py | 15 + .../config/preprocessor/face_detect_eyes.py | 7 - ...tion_eyes.py => histogram_equalization.py} | 4 + bob/bio/face/config/preprocessor/inorm_lbp.py | 12 + .../config/preprocessor/inorm_lbp_eyes.py | 5 - ...t_image_eyes.py => self_quotient_image.py} | 4 + .../{tan_triggs_eyes.py => tan_triggs.py} | 4 + bob/bio/face/script/__init__.py | 0 bob/bio/face/script/baselines.py | 345 ++++++++++++++++++ bob/bio/face/test/test_preprocessors.py | 18 +- bob/bio/face/test/test_scripts.py | 23 ++ buildout.cfg | 3 + setup.py | 22 +- 17 files changed, 463 insertions(+), 29 deletions(-) create mode 100644 bob/bio/face/config/algorithm/bic_jets.py create mode 100644 bob/bio/face/config/preprocessor/face_detect.py delete mode 100644 bob/bio/face/config/preprocessor/face_detect_eyes.py rename bob/bio/face/config/preprocessor/{histogram_equalization_eyes.py => histogram_equalization.py} (55%) create mode 100644 bob/bio/face/config/preprocessor/inorm_lbp.py delete mode 100644 bob/bio/face/config/preprocessor/inorm_lbp_eyes.py rename bob/bio/face/config/preprocessor/{self_quotient_image_eyes.py => self_quotient_image.py} (55%) rename bob/bio/face/config/preprocessor/{tan_triggs_eyes.py => tan_triggs.py} (56%) create mode 100644 bob/bio/face/script/__init__.py create mode 100755 bob/bio/face/script/baselines.py create mode 100644 bob/bio/face/test/test_scripts.py diff --git a/bob/bio/face/__init__.py b/bob/bio/face/__init__.py index e672118f..18ff674f 100644 --- a/bob/bio/face/__init__.py +++ b/bob/bio/face/__init__.py @@ -1,6 +1,7 @@ from . import preprocessor from . import extractor from . import algorithm +from . import script from . import test diff --git a/bob/bio/face/algorithm/GaborJet.py b/bob/bio/face/algorithm/GaborJet.py index 7499d5f4..36cc2cc0 100644 --- a/bob/bio/face/algorithm/GaborJet.py +++ b/bob/bio/face/algorithm/GaborJet.py @@ -105,7 +105,7 @@ class GaborJet (Algorithm): return [[bob.ip.gabor.Jet(jets_per_node[n])] for n in range(len(jets_per_node))] - def save_model(self, model, model_file): + def write_model(self, model, model_file): """Saves the enrolled model of Gabor jets to file.""" f = bob.io.base.HDF5File(model_file, 'w') # several model graphs diff --git a/bob/bio/face/config/algorithm/bic_jets.py b/bob/bio/face/config/algorithm/bic_jets.py new file mode 100644 index 00000000..af566992 --- /dev/null +++ b/bob/bio/face/config/algorithm/bic_jets.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import bob.bio.base +import bob.ip.gabor + +similarity_function = bob.ip.gabor.Similarity("PhaseDiffPlusCanberra", bob.ip.gabor.Transform()) + +def gabor_jet_similarities(f1, f2): + """Computes the similarity vector between two Gabor graph features""" + assert len(f1) == len(f2) + return [similarity_function(f1[i], f2[i]) for i in range(len(f1))] + + +algorithm = bob.bio.base.algorithm.BIC( + # measure to compare two features in input space + comparison_function = gabor_jet_similarities, + # load and save functions + read_function = bob.ip.gabor.load_jets, + write_function = bob.ip.gabor.save_jets, + # Limit the number of training pairs + maximum_training_pair_count = 1000000, + # Dimensions of intrapersonal and extrapersonal subspaces + subspace_dimensions = (20, 20), + multiple_model_scoring = 'max' +) diff --git a/bob/bio/face/config/database/xm2vts.py b/bob/bio/face/config/database/xm2vts.py index b75a1950..5e802052 100644 --- a/bob/bio/face/config/database/xm2vts.py +++ b/bob/bio/face/config/database/xm2vts.py @@ -3,7 +3,7 @@ import bob.db.xm2vts import bob.bio.base -xm2vts_directory = "[YOUR_XM2VTS_IMAGE_DIRECTORY]" +xm2vts_directory = "[YOUR_XM2VTS_DIRECTORY]" # setup for XM2VTS database = bob.bio.base.database.DatabaseBob( diff --git a/bob/bio/face/config/preprocessor/face_detect.py b/bob/bio/face/config/preprocessor/face_detect.py new file mode 100644 index 00000000..1b6e0d4d --- /dev/null +++ b/bob/bio/face/config/preprocessor/face_detect.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import bob.bio.face + +# Detects the face and eye landmarks crops it using the detected eyes +preprocessor = bob.bio.face.preprocessor.FaceDetect( + face_cropper = 'face-crop-eyes', + use_flandmark = True +) + +# Detects the face amd crops it without eye detection +preprocessor_no_eyes = bob.bio.face.preprocessor.FaceDetect( + face_cropper = 'face-crop-eyes', + use_flandmark = False +) diff --git a/bob/bio/face/config/preprocessor/face_detect_eyes.py b/bob/bio/face/config/preprocessor/face_detect_eyes.py deleted file mode 100644 index b11d96fc..00000000 --- a/bob/bio/face/config/preprocessor/face_detect_eyes.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python - -import bob.bio.face - -preprocessor = bob.bio.face.preprocessor.FaceDetect( - face_cropper = 'face-crop-eyes' -) diff --git a/bob/bio/face/config/preprocessor/histogram_equalization_eyes.py b/bob/bio/face/config/preprocessor/histogram_equalization.py similarity index 55% rename from bob/bio/face/config/preprocessor/histogram_equalization_eyes.py rename to bob/bio/face/config/preprocessor/histogram_equalization.py index 9a1c4b6f..96bad0ad 100644 --- a/bob/bio/face/config/preprocessor/histogram_equalization_eyes.py +++ b/bob/bio/face/config/preprocessor/histogram_equalization.py @@ -3,3 +3,7 @@ import bob.bio.face preprocessor = bob.bio.face.preprocessor.HistogramEqualization( face_cropper = 'face-crop-eyes' ) + +preprocessor_no_crop = bob.bio.face.preprocessor.HistogramEqualization( + face_cropper = None +) diff --git a/bob/bio/face/config/preprocessor/inorm_lbp.py b/bob/bio/face/config/preprocessor/inorm_lbp.py new file mode 100644 index 00000000..702dd288 --- /dev/null +++ b/bob/bio/face/config/preprocessor/inorm_lbp.py @@ -0,0 +1,12 @@ +import bob.bio.face +import numpy + +preprocessor = bob.bio.face.preprocessor.INormLBP( + face_cropper = 'face-crop-eyes', + dtype = numpy.float64 +) + +preprocessor_no_crop = bob.bio.face.preprocessor.INormLBP( + face_cropper = None, + dtype = numpy.float64 +) diff --git a/bob/bio/face/config/preprocessor/inorm_lbp_eyes.py b/bob/bio/face/config/preprocessor/inorm_lbp_eyes.py deleted file mode 100644 index 8920acec..00000000 --- a/bob/bio/face/config/preprocessor/inorm_lbp_eyes.py +++ /dev/null @@ -1,5 +0,0 @@ -import bob.bio.face - -preprocessor = bob.bio.face.preprocessor.INormLBP( - face_cropper = 'face-crop-eyes' -) diff --git a/bob/bio/face/config/preprocessor/self_quotient_image_eyes.py b/bob/bio/face/config/preprocessor/self_quotient_image.py similarity index 55% rename from bob/bio/face/config/preprocessor/self_quotient_image_eyes.py rename to bob/bio/face/config/preprocessor/self_quotient_image.py index 6726cd51..286f954f 100644 --- a/bob/bio/face/config/preprocessor/self_quotient_image_eyes.py +++ b/bob/bio/face/config/preprocessor/self_quotient_image.py @@ -3,3 +3,7 @@ import bob.bio.face preprocessor = bob.bio.face.preprocessor.SelfQuotientImage( face_cropper = 'face-crop-eyes' ) + +preprocessor_no_crop = bob.bio.face.preprocessor.SelfQuotientImage( + face_cropper = None +) diff --git a/bob/bio/face/config/preprocessor/tan_triggs_eyes.py b/bob/bio/face/config/preprocessor/tan_triggs.py similarity index 56% rename from bob/bio/face/config/preprocessor/tan_triggs_eyes.py rename to bob/bio/face/config/preprocessor/tan_triggs.py index 5ba8afe6..faf64fd1 100644 --- a/bob/bio/face/config/preprocessor/tan_triggs_eyes.py +++ b/bob/bio/face/config/preprocessor/tan_triggs.py @@ -3,3 +3,7 @@ import bob.bio.face preprocessor = bob.bio.face.preprocessor.TanTriggs( face_cropper = 'face-crop-eyes' ) + +preprocessor_no_crop = bob.bio.face.preprocessor.TanTriggs( + face_cropper = None +) diff --git a/bob/bio/face/script/__init__.py b/bob/bio/face/script/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/bob/bio/face/script/baselines.py b/bob/bio/face/script/baselines.py new file mode 100755 index 00000000..82af9051 --- /dev/null +++ b/bob/bio/face/script/baselines.py @@ -0,0 +1,345 @@ +#!../bin/python +from __future__ import print_function + +import subprocess +import os +import sys +import argparse + +import bob.bio.base + +import bob.core +logger = bob.core.log.setup("bob.bio.face") + +# This is the default set of algorithms that can be run using this script. +all_databases = bob.bio.base.resource_keys('database') +# check, which databases can actually be assessed +available_databases = [] + +for database in all_databases: + try: + bob.bio.base.load_resource(database, 'database') + available_databases.append(database) + except: + pass + +# collect all algorithms that we provide baselines for +all_algorithms = ['eigenface', 'lda', 'gabor-graph', 'lgbphs', 'plda', 'bic'] + +try: + # try if GMM-based algorithms are available + bob.bio.base.load_resource('gmm', 'algorithm') + bob.bio.base.load_resource('isv', 'algorithm') + bob.bio.base.load_resource('ivector', 'algorithm') + all_algorithms += ['gmm', 'isv', 'ivector'] +except: + print("Could not load the GMM-based algorithms. Did you specify bob.bio.gmm in your config file?") + +try: + # try if the CSU extension is enabled + bob.bio.base.load_resource('lrpca', 'algorithm') + bob.bio.base.load_resource('lda-ir', 'algorithm') + all_algorithms += ['lrpca', 'lda-ir'] +except: + print("Could not load the algorithms from the CSU resources. Did you specify bob.bio.csu in your config file?") + + +def command_line_arguments(command_line_parameters): + """Defines the command line parameters that are accepted.""" + + # create parser + parser = argparse.ArgumentParser(description='Execute baseline algorithms with default parameters', formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + # add parameters + # - the algorithm to execute + parser.add_argument('-a', '--algorithms', choices = all_algorithms, default = ('eigenface',), nargs = '+', help = 'Select one (or more) algorithms that you want to execute.') + parser.add_argument('--all', action = 'store_true', help = 'Select all algorithms.') + # - the database to choose + parser.add_argument('-d', '--database', choices = available_databases, default = 'atnt', help = 'The database on which the baseline algorithm is executed.') + # - the database to choose + parser.add_argument('-b', '--baseline-directory', default = 'baselines', help = 'The sub-directory, where the baseline results are stored.') + # - the directory to write + parser.add_argument('-f', '--directory', help = 'The directory to write the data of the experiment into. If not specified, the default directories of the verify.py script are used (see ./bin/verify.py --help).') + + # - use the Idiap grid -- option is only useful if you are at Idiap + parser.add_argument('-g', '--grid', action = 'store_true', help = 'Execute the algorithm in the SGE grid.') + # - run in parallel on the local machine + parser.add_argument('-l', '--parallel', type=int, help = 'Run the algorithms in parallel on the local machine, using the given number of parallel threads') + # - perform ZT-normalization + parser.add_argument('-z', '--zt-norm', action = 'store_true', help = 'Compute the ZT norm for the files (might not be availabe for all databases).') + + # - just print? + parser.add_argument('-q', '--dry-run', action = 'store_true', help = 'Just print the commands, but do not execute them.') + + # - evaluate the algorithm (after it has finished) + parser.add_argument('-e', '--evaluate', nargs='+', choices = ('EER', 'HTER', 'ROC', 'DET', 'CMC', 'RR'), help = 'Evaluate the results of the algorithms (instead of running them) using the given evaluation techniques.') + + # - other parameters that are passed to the underlying script + parser.add_argument('parameters', nargs = argparse.REMAINDER, help = 'Parameters directly passed to the ./bin/verify.py script.') + + bob.core.log.add_command_line_option(parser) + args = parser.parse_args(command_line_parameters) + if args.all: + args.algorithms = all_algorithms + + bob.core.log.set_verbosity_level(logger, args.verbose) + + return args + + +# In these functions, some default experiments are prepared. +# An experiment consists of three configuration files: +# - The features to be extracted +# - The algorithm to be run +# - The grid configuration that it requires (only used when the --grid option is chosen) + +CONFIGURATIONS = { + 'eigenface' : dict( + preprocessor = ('face-crop-eyes', 'base'), + extractor = 'linearize', + algorithm = 'pca', + ), + + 'lda': dict( + preprocessor = ('face-crop-eyes', 'base'), + extractor = 'eigenface', + algorithm = 'lda', + ), + + 'plda': dict( + preprocessor = ('face-crop-eyes', 'base'), + extractor = 'linearize', + algorithm = 'pca+plda', + grid = 'demanding' + ), + + 'gabor-graph': dict( + preprocessor = ('inorm-lbp-crop', 'inorm-lbp'), + extractor = 'grid-graph', + algorithm = 'gabor-jet', + ), + + 'lgbphs': dict( + preprocessor = ('tan-triggs-crop', 'tan-triggs'), + extractor = 'lgbphs', + algorithm = 'lgbphs', + ), + + 'bic': dict( + preprocessor = ('face-crop-eyes', 'base'), + extractor = 'grid-graph', + algorithm = 'bic-jets', + grid = 'demanding' + ), + + 'gmm': dict( + preprocessor = ('tan-triggs-crop', 'tan-triggs'), + extractor = 'dct-blocks', + algorithm = 'gmm', + grid = 'demanding', + script = './bin/verify_gmm.py' + ), + + 'isv': dict( + preprocessor = ('tan-triggs-crop', 'tan-triggs'), + extractor = 'dct-blocks', + algorithm = 'isv', + grid = 'demanding', + script = './bin/verify_isv.py' + ), + + 'ivector': dict( + preprocessor = ('tan-triggs-crop', 'tan-triggs'), + extractor = 'dct-blocks', + algorithm = 'ivector', + grid = 'demanding', + script = './bin/verify_ivector.py' + ), + + 'lrpca': dict( + preprocessor = ('lrpca', None), + extractor = 'lrpca', + algorithm = 'lrpca' + ), + + 'lda-ir': dict( + preprocessor = ('lda-ir', None), + extractor = 'lda-ir', + algorithm = 'lda-ir' + ) +} + +def main(command_line_parameters = None): + + # Collect command line arguments + args = command_line_arguments(command_line_parameters) + + # Check the database configuration file + has_eyes = args.database != 'atnt' + has_zt_norm = args.database in ('banca', 'mobio', 'multipie', 'scface') + has_eval = args.database in ('banca', 'mobio', 'multipie', 'scface', 'xm2vts') + + if not args.evaluate: + + # execution of the job is requested + for algorithm in args.algorithms: + logger.info("Executing algorithm '%s'", algorithm) + + # get the setup for the desired algorithm + import copy + setup = copy.deepcopy(CONFIGURATIONS[algorithm]) + if 'grid' not in setup: setup['grid'] = 'grid' + if 'script' not in setup or (not args.grid and args.parallel is None): setup['script'] = './bin/verify.py' + + # select the preprocessor + setup['preprocessor'] = setup['preprocessor'][0 if has_eyes else 1] + if setup['preprocessor'] is None: + logger.warn("Skipping algorithm '%s' since no preprocessor is found that matches the given databases' '%s' configuration", algorithm, args.database) + + + # this is the default sub-directory that is used + sub_directory = os.path.join(args.baseline_directory, algorithm) + + # create the command to the faceverify script + command = [ + setup['script'], + '--database', args.database, + '--preprocessor', setup['preprocessor'], + '--extractor', setup['extractor'], + '--algorithm', setup['algorithm'], + '--sub-directory', sub_directory + ] + + # add grid argument, if available + if args.grid: + command += ['--grid', setup['grid'], '--stop-on-failure'] + + if args.parallel is not None: + command += ['--grid', 'bob.bio.base.grid.Grid("local", number_of_parallel_processes=%d)' % args.parallel, '--run-local-scheduler', '--stop-on-failure'] + + # compute ZT-norm if the database provides this setup + if has_zt_norm and args.zt_norm: + command += ['--zt-norm'] + + # compute results for both 'dev' and 'eval' group if the database provides these + if has_eval: + command += ['--groups', 'dev', 'eval'] + + # set the directories, if desired; we set both directories to be identical. + if args.directory is not None: + command += ['--temp-directory', os.path.join(args.directory, args.database), '--result-directory', os.path.join(args.directory, args.database)] + + # set the verbosity level + if args.verbose: + command += ['-' + 'v'*args.verbose] + + # add the command line arguments that were specified on command line + if args.parameters: + command += args.parameters[1:] + + # print the command so that it can easily be re-issued + logger.info("Executing command:\n%s", bob.bio.base.tools.command_line(command)) + +# import ipdb; ipdb.set_trace() + # run the command + if not args.dry_run: + subprocess.call(command) + + else: + # call the evaluate script with the desired parameters + + # get the base directory of the results + is_idiap = os.path.isdir("/idiap") + if args.directory is None: + args.directory = "/idiap/user/%s/%s" % (os.environ["USER"], args.database) if is_idiap else "results" + if not os.path.exists(args.directory): + if not args.dry_run: + raise IOError("The result directory '%s' cannot be found. Please specify the --directory as it was specified during execution of the algorithms." % args.directory) + + # get the result directory of the database + result_dir = os.path.join(args.directory, args.baseline_directory) + if not os.path.exists(result_dir): + if not args.dry_run: + raise IOError("The result directory '%s' for the desired database cannot be found. Did you already run the experiments for this database?" % result_dir) + + # iterate over the algorithms and collect the result files + result_dev = [] + result_eval = [] + result_zt_dev = [] + result_zt_eval = [] + legends = [] + + # evaluate the results + for algorithm in args.algorithms: + if not os.path.exists(os.path.join(result_dir, algorithm)): + logger.warn("Skipping algorithm '%s' since the results cannot be found.", algorithm) + continue + protocols = [d for d in os.listdir(os.path.join(result_dir, algorithm)) if os.path.isdir(os.path.join(result_dir, algorithm, d))] + if not len(protocols): + logger.warn("Skipping algorithm '%s' since the results cannot be found.", algorithm) + continue + if len(protocols) > 1: + logger.warn("There are several protocols found in directory '%s'. Here, we use protocol '%s'.", os.path.join(result_dir, algorithm), protocols[0]) + + nonorm_sub_dir = os.path.join(algorithm, protocols[0], 'nonorm') + ztnorm_sub_dir = os.path.join(algorithm, protocols[0], 'ztnorm') + + # collect the resulting files + if os.path.exists(os.path.join(result_dir, nonorm_sub_dir, 'scores-dev')): + result_dev.append(os.path.join(nonorm_sub_dir, 'scores-dev')) + legends.append(algorithm) + + if has_eval and os.path.exists(os.path.join(result_dir, nonorm_sub_dir, 'scores-eval')): + result_eval.append(os.path.join(nonorm_sub_dir, 'scores-eval')) + + if has_zt_norm: + if os.path.exists(os.path.join(result_dir, ztnorm_sub_dir, 'scores-dev')): + result_zt_dev.append(os.path.join(ztnorm_sub_dir, 'scores-dev')) + if has_eval and os.path.exists(os.path.join(result_dir, ztnorm_sub_dir, 'scores-eval')): + result_zt_eval.append(os.path.join(ztnorm_sub_dir, 'scores-eval')) + + # check if we have found some results + if not result_dev: + logger.warn("No result files were detected -- skipping evaluation.") + return + + # call the evaluate script + base_command = ['./bin/evaluate.py', '--directory', result_dir, '--legends'] + legends + if 'EER' in args.evaluate: + base_command += ['--criterion', 'EER'] + elif 'HTER' in args.evaluate: + base_command += ['--criterion', 'HTER'] + if 'ROC' in args.evaluate: + base_command += ['--roc', 'ROCxxx.pdf'] + if 'DET' in args.evaluate: + base_command += ['--det', 'DETxxx.pdf'] + if 'CMC' in args.evaluate: + base_command += ['--cmc', 'CMCxxx.pdf'] + if 'RR' in args.evaluate: + base_command += ['--rr'] + if args.verbose: + base_command += ['-' + 'v'*args.verbose] + + # first, run the nonorm evaluation + if result_zt_dev: + command = [cmd.replace('xxx','_dev') for cmd in base_command] + else: + command = [cmd.replace('xxx','') for cmd in base_command] + command += ['--dev-files'] + result_dev + if result_eval: + command += ['--eval-files'] + result_eval + + logger.info("Executing command:\n%s", bob.bio.base.tools.command_line(command)) + if not args.dry_run: + subprocess.call(command) + + # now, also run the ZT norm evaluation, if available + if result_zt_dev: + command = [cmd.replace('xxx','_eval') for cmd in base_command] + command += ['--dev-files'] + result_zt_dev + if result_zt_eval: + command += ['--eval-files'] + result_zt_eval + + logger.info("Executing command:\n%s", bob.bio.base.tools.command_line(command)) + if not args.dry_run: + subprocess.call(command) diff --git a/bob/bio/face/test/test_preprocessors.py b/bob/bio/face/test/test_preprocessors.py index 79a7e597..7b92a30e 100644 --- a/bob/bio/face/test/test_preprocessors.py +++ b/bob/bio/face/test/test_preprocessors.py @@ -30,6 +30,7 @@ regenerate_refs = False import bob.bio.base import bob.bio.face +import bob.db.verification.utils def _compare(data, reference, write_function = bob.bio.base.save, read_function = bob.bio.base.load): @@ -86,10 +87,11 @@ def test_face_crop(): def test_face_detect(): image, annotation = _image(), None - cropper = bob.bio.base.load_resource('face-detect-eyes', 'preprocessor') + cropper = bob.bio.base.load_resource('face-detect', 'preprocessor') assert isinstance(cropper, bob.bio.face.preprocessor.FaceDetect) assert isinstance(cropper, bob.bio.face.preprocessor.Base) assert isinstance(cropper, bob.bio.base.preprocessor.Preprocessor) + assert cropper.flandmark is None # execute face detector reference = pkg_resources.resource_filename('bob.bio.face.test', 'data/detected.hdf5') @@ -103,11 +105,11 @@ def test_face_detect(): assert abs(cropper.quality - 33.1136586) < 1e-5 # execute face detector with tan-triggs - cropper = bob.bio.face.preprocessor.TanTriggs(face_cropper='face-detect-eyes') + cropper = bob.bio.face.preprocessor.TanTriggs(face_cropper='landmark-detect') preprocessed = cropper(image, annotation) # load reference and perform Tan-Triggs - detected = bob.bio.base.load(pkg_resources.resource_filename('bob.bio.face.test', 'data/detected.hdf5')) - tan_triggs = bob.bio.face.preprocessor.TanTriggs(face_cropper=None) + detected = bob.bio.base.load(pkg_resources.resource_filename('bob.bio.face.test', 'data/flandmark.hdf5')) + tan_triggs = bob.bio.base.load_resource('tan-triggs', 'preprocessor') reference = tan_triggs(detected) assert numpy.allclose(preprocessed, reference, atol=1e-5) @@ -116,7 +118,7 @@ def test_tan_triggs(): # read input image, annotation = _image(), _annotation() - preprocessor = bob.bio.base.load_resource('tan-triggs-eyes', 'preprocessor') + preprocessor = bob.bio.base.load_resource('tan-triggs-crop', 'preprocessor') assert isinstance(preprocessor, bob.bio.face.preprocessor.TanTriggs) assert isinstance(preprocessor, bob.bio.face.preprocessor.Base) assert isinstance(preprocessor, bob.bio.base.preprocessor.Preprocessor) @@ -135,7 +137,7 @@ def test_inorm_lbp(): # read input image, annotation = _image(), _annotation() - preprocessor = bob.bio.base.load_resource('inorm-lbp-eyes', 'preprocessor') + preprocessor = bob.bio.base.load_resource('inorm-lbp-crop', 'preprocessor') assert isinstance(preprocessor, bob.bio.face.preprocessor.INormLBP) assert isinstance(preprocessor, bob.bio.face.preprocessor.Base) assert isinstance(preprocessor, bob.bio.base.preprocessor.Preprocessor) @@ -148,7 +150,7 @@ def test_heq(): # read input image, annotation = _image(), _annotation() - preprocessor = bob.bio.base.load_resource('histogram-eyes', 'preprocessor') + preprocessor = bob.bio.base.load_resource('histogram-crop', 'preprocessor') assert isinstance(preprocessor, bob.bio.face.preprocessor.HistogramEqualization) assert isinstance(preprocessor, bob.bio.face.preprocessor.Base) assert isinstance(preprocessor, bob.bio.base.preprocessor.Preprocessor) @@ -161,7 +163,7 @@ def test_sqi(): # read input image, annotation = _image(), _annotation() - preprocessor = bob.bio.base.load_resource('self-quotient-eyes', 'preprocessor') + preprocessor = bob.bio.base.load_resource('self-quotient-crop', 'preprocessor') assert isinstance(preprocessor, bob.bio.face.preprocessor.SelfQuotientImage) assert isinstance(preprocessor, bob.bio.face.preprocessor.Base) assert isinstance(preprocessor, bob.bio.base.preprocessor.Preprocessor) diff --git a/bob/bio/face/test/test_scripts.py b/bob/bio/face/test/test_scripts.py new file mode 100644 index 00000000..3bf9c9b5 --- /dev/null +++ b/bob/bio/face/test/test_scripts.py @@ -0,0 +1,23 @@ +import bob.bio.base.test.utils +import bob.bio.face + +@bob.bio.base.test.utils.grid_available +def test_baselines(): + # test that all of the baselines would execute + from bob.bio.face.script.baselines import available_databases, all_algorithms, main + + for database in available_databases: + parameters = ['-d', database, '--dry-run', '-vv'] + main(parameters) + parameters.append('--grid') + main(parameters) + parameters.extend(['-e', 'HTER']) + main(parameters) + + for algorithm in all_algorithms: + parameters = ['-a', algorithm, '--dry-run', '-vv'] + main(parameters) + parameters.append('-g') + main(parameters) + parameters.extend(['-e', 'HTER']) + main(parameters) diff --git a/buildout.cfg b/buildout.cfg index fac435de..736bf25c 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -5,6 +5,7 @@ [buildout] parts = scripts eggs = bob.bio.face + bob.bio.gmm bob.db.arface bob.db.banca bob.db.caspeal @@ -40,6 +41,7 @@ develop = src/bob.extension src/bob.db.verification.filelist src/bob.db.atnt src/bob.bio.base + src/bob.bio.gmm src/bob.learn.boosting src/bob.ip.facedetect src/bob.ip.flandmark @@ -81,6 +83,7 @@ bob.db.verification.utils = git https://github.com/bioidiap/bob.db.verification. bob.db.verification.filelist = git https://github.com/bioidiap/bob.db.verification.filelist bob.db.atnt = git https://github.com/bioidiap/bob.db.atnt bob.bio.base = git https://github.com/bioidiap/bob.bio.base +bob.bio.gmm = git https://github.com/bioidiap/bob.bio.gmm bob.learn.boosting = git https://github.com/bioidiap/bob.learn.boosting bob.ip.facedetect = git https://github.com/bioidiap/bob.ip.facedetect bob.ip.flandmark = git https://github.com/bioidiap/bob.ip.flandmark diff --git a/setup.py b/setup.py index 9e516f8d..a5299b0b 100644 --- a/setup.py +++ b/setup.py @@ -33,10 +33,10 @@ # allows you to test your package with new python dependencies w/o requiring # administrative interventions. -from setuptools import setup, find_packages, dist +from setuptools import setup, dist dist.Distribution(dict(setup_requires=['bob.extension'])) -from bob.extension.utils import load_requirements +from bob.extension.utils import load_requirements, find_packages install_requires = load_requirements() # The only thing we do in this file is to call the setup() function with all @@ -103,6 +103,7 @@ setup( # scripts should be declared using this entry: 'console_scripts' : [ + 'baselines.py = bob.bio.face.script.baselines:main' ], 'bob.bio.database': [ @@ -127,12 +128,18 @@ setup( 'bob.bio.preprocessor': [ 'base = bob.bio.face.config.preprocessor.base:preprocessor', # simple color conversion 'face-crop-eyes = bob.bio.face.config.preprocessor.face_crop_eyes:preprocessor', # face crop - 'inorm-lbp-eyes = bob.bio.face.config.preprocessor.inorm_lbp_eyes:preprocessor', # face crop + inorm-lbp - 'tan-triggs-eyes = bob.bio.face.config.preprocessor.tan_triggs_eyes:preprocessor', # face crop + inorm-lbp - 'histogram-eyes = bob.bio.face.config.preprocessor.histogram_equalization_eyes:preprocessor', # face crop + inorm-lbp - 'self-quotient-eyes= bob.bio.face.config.preprocessor.self_quotient_image_eyes:preprocessor', # face crop + inorm-lbp + 'inorm-lbp-crop = bob.bio.face.config.preprocessor.inorm_lbp:preprocessor', # face crop + inorm-lbp + 'tan-triggs-crop = bob.bio.face.config.preprocessor.tan_triggs:preprocessor', # face crop + Tan&Triggs + 'histogram-crop = bob.bio.face.config.preprocessor.histogram_equalization:preprocessor', # face crop + histogram equalization + 'self-quotient-crop= bob.bio.face.config.preprocessor.self_quotient_image:preprocessor', # face crop + self quotient image + 'landmark-detect = bob.bio.face.config.preprocessor.face_detect:preprocessor', # face detection + landmark detection + cropping + 'face-detect = bob.bio.face.config.preprocessor.face_detect:preprocessor_no_eyes', # face detection + cropping + + 'inorm-lbp = bob.bio.face.config.preprocessor.inorm_lbp:preprocessor_no_crop', # inorm-lbp w/o face-crop + 'tan-triggs = bob.bio.face.config.preprocessor.tan_triggs:preprocessor_no_crop', # Tan&Triggs w/o face-crop + 'histogram = bob.bio.face.config.preprocessor.histogram_equalization:preprocessor_no_crop', # histogram equalization w/o face-crop + 'self-quotient = bob.bio.face.config.preprocessor.self_quotient_image:preprocessor_no_crop', # self quotient image w/o face-crop - 'face-detect-eyes = bob.bio.face.config.preprocessor.face_detect_eyes:preprocessor', # face detection + cropping ], 'bob.bio.extractor': [ @@ -145,6 +152,7 @@ setup( 'bob.bio.algorithm': [ 'gabor-jet = bob.bio.face.config.algorithm.gabor_jet:algorithm', # Gabor jet comparison 'lgbphs = bob.bio.face.config.algorithm.lgbphs:algorithm', # LGBPHS histograms + 'bic-jets = bob.bio.face.config.algorithm.bic_jets:algorithm', # BIC on gabor jets ], }, -- GitLab