diff --git a/README.rst b/README.rst index 36fcf86233a80c8eb1d54f9f6f0c9735c0dc73d6..d0ffe7a11cf6ba84655d6238a6ac0cb8e515d99b 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,4 @@ .. vim: set fileencoding=utf-8 : -.. Andre Anjos <andre.anjos@idiap.ch> .. Fri 08 Jul 2016 15:38:56 CEST .. image:: http://img.shields.io/badge/docs-stable-yellow.png diff --git a/bob/bio/vein/algorithms/HammingDistance.py b/bob/bio/vein/algorithms/HammingDistance.py deleted file mode 100644 index 0a3b0be93c992e459c0628238b0fa9ecaec1720a..0000000000000000000000000000000000000000 --- a/bob/bio/vein/algorithms/HammingDistance.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> - -import bob.ip.base -import bob.sp - -import numpy -import math -import scipy.signal - -from facereclib.tools.Tool import Tool - -class MiuraMatch (Tool): - """Finger vein matching: match ratio based on - N. Miura, A. Nagasaka, and T. Miyatake. Feature extraction of finger vein patterns based on repeated line tracking and its application - to personal identification. Machine Vision and Applications, Vol. 15, Num. 4, pp. 194--203, 2004 - """ - - def __init__( - self, - # some similarity functions might need a GaborWaveletTransform class, so we have to provide the parameters here as well... - ch = 8, # Maximum search displacement in y-direction - cw = 5, # Maximum search displacement in x-direction - gpu = False, - ): - - # call base class constructor - Tool.__init__( - self, - - ch = ch, - cw = cw, - - multiple_model_scoring = None, - multiple_probe_scoring = None - ) - - self.ch = ch - self.cw = cw - self.gpu = gpu - - def enroll(self, enroll_features): - """Enrolls the model by computing an average graph for each model""" - # return the generated model - return numpy.vstack(enroll_features) - - - def score(self, model, probe): - """Computes the score of the probe and the model - Return score - Value between 0 and 0.5, larger value is better match - """ - I=probe.astype(numpy.float64) - R=model.astype(numpy.float64) - h, w = R.shape - crop_R = R[self.ch:h-self.ch, self.cw:w-self.cw] - rotate_R = numpy.zeros((crop_R.shape[0], crop_R.shape[1])) - bob.ip.base.rotate(crop_R, rotate_R, 180) - #FFT for scoring! - #Nm=bob.sp.ifft(bob.sp.fft(I)*bob.sp.fft(rotate_R)) - if self.gpu == True: - import xbob.cusp - Nm = xbob.cusp.conv(I, rotate_R); - else: - Nm = scipy.signal.convolve2d(I, rotate_R, 'valid'); - t0, s0 = numpy.unravel_index(Nm.argmax(), Nm.shape) - Nmm = Nm[t0,s0] - #Nmm = Nm.max() - #mi = numpy.argwhere(Nmm == Nm) - #t0, s0 = mi.flatten()[:2] - score = Nmm/(sum(sum(crop_R)) + sum(sum(I[t0:t0+h-2*self.ch, s0:s0+w-2*self.cw]))) - return score - diff --git a/bob/bio/vein/algorithms/MiuraMatch.py b/bob/bio/vein/algorithms/MiuraMatch.py index a764b36958112d5377d174e51a169797867b5f3e..499d157e7720c65f125b025aeff5161b7233b91d 100644 --- a/bob/bio/vein/algorithms/MiuraMatch.py +++ b/bob/bio/vein/algorithms/MiuraMatch.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> import bob.sp import bob.ip.base @@ -9,24 +8,27 @@ import numpy import math import scipy.signal -from facereclib.tools.Tool import Tool +from bob.bio.base.algorithm import Algorithm -class MiuraMatch (Tool): - """Finger vein matching: match ratio based on - N. Miura, A. Nagasaka, and T. Miyatake. Feature extraction of finger vein patterns based on repeated line tracking and its application - to personal identification. Machine Vision and Applications, Vol. 15, Num. 4, pp. 194--203, 2004 + +class MiuraMatch (Algorithm): + """Finger vein matching: match ratio + + Based on N. Miura, A. Nagasaka, and T. Miyatake. Feature extraction of finger + vein patterns based on repeated line tracking and its application to personal + identification. Machine Vision and Applications, Vol. 15, Num. 4, pp. + 194--203, 2004 """ - def __init__( - self, + def __init__(self, # some similarity functions might need a GaborWaveletTransform class, so we have to provide the parameters here as well... ch = 8, # Maximum search displacement in y-direction cw = 5, # Maximum search displacement in x-direction gpu = False, - ): + ): # call base class constructor - Tool.__init__( + Algorithm.__init__( self, ch = ch, @@ -40,8 +42,10 @@ class MiuraMatch (Tool): self.cw = cw self.gpu = gpu + def enroll(self, enroll_features): """Enrolls the model by computing an average graph for each model""" + # return the generated model #import ipdb; ipdb.set_trace() return numpy.array(enroll_features) @@ -52,7 +56,7 @@ class MiuraMatch (Tool): size_t = numpy.array(t.shape) size_a = numpy.array(a.shape) outsize = size_t + size_a - 1 - + # Determine 2D cross correlation in Fourier domain taux = numpy.zeros(outsize) taux[0:size_t[0],0:size_t[1]] = t @@ -60,12 +64,12 @@ class MiuraMatch (Tool): aaux = numpy.zeros(outsize) aaux[0:size_a[0],0:size_a[1]] = a Fa = bob.sp.fft(aaux.astype(numpy.complex128)) - + convta = numpy.real(bob.sp.ifft(Ft*Fa)) - + [w, h] = size_t-size_a+1 output = convta[size_a[0]-1:size_a[0]-1+w, size_a[1]-1:size_a[1]-1+h] - + return output @@ -75,12 +79,12 @@ class MiuraMatch (Tool): """ #print model.shape #print probe.shape - + I=probe.astype(numpy.float64) - - if len(model.shape) == 2: + + if len(model.shape) == 2: model = numpy.array([model]) - + n_models = model.shape[0] scores = [] @@ -90,7 +94,7 @@ class MiuraMatch (Tool): crop_R = R[self.ch:h-self.ch, self.cw:w-self.cw] rotate_R = numpy.zeros((crop_R.shape[0], crop_R.shape[1])) bob.ip.base.rotate(crop_R, rotate_R, 180) - #FFT for scoring! + #FFT for scoring! #Nm=bob.sp.ifft(bob.sp.fft(I)*bob.sp.fft(rotate_R)) if self.gpu == True: Nm = self.convfft(I, rotate_R) @@ -99,13 +103,12 @@ class MiuraMatch (Tool): else: Nm = self.convfft(I, rotate_R) #Nm2 = scipy.signal.convolve2d(I, rotate_R, 'valid') - + t0, s0 = numpy.unravel_index(Nm.argmax(), Nm.shape) Nmm = Nm[t0,s0] #Nmm = Nm.max() - #mi = numpy.argwhere(Nmm == Nm) + #mi = numpy.argwhere(Nmm == Nm) #t0, s0 = mi.flatten()[:2] scores.append(Nmm/(sum(sum(crop_R)) + sum(sum(I[t0:t0+h-2*self.ch, s0:s0+w-2*self.cw])))) - + return numpy.mean(scores) - diff --git a/bob/bio/vein/algorithms/__init__.py b/bob/bio/vein/algorithms/__init__.py index 39b7cfd63de56b68a43ce05dfa21a69e0f5f53cc..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/bob/bio/vein/algorithms/__init__.py +++ b/bob/bio/vein/algorithms/__init__.py @@ -1,6 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : - -"""Tool chain for computing verification scores""" - -from MiuraMatch import MiuraMatch diff --git a/bob/bio/vein/configurations/__init__.py b/bob/bio/vein/configurations/__init__.py index d12867102ba4c3d430e56ba2e60c223f99c60f4e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/bob/bio/vein/configurations/__init__.py +++ b/bob/bio/vein/configurations/__init__.py @@ -1,11 +0,0 @@ -#!/usr/bin/env python -# Pedro Tome <Pedro.Tome@idiap.ch> - -"""Configuration files for different steps of the fingervein recognition tool chain""" - -import databases -import preprocessing -import features -import tools -import grid - diff --git a/bob/bio/vein/configurations/algorithms.py b/bob/bio/vein/configurations/algorithms.py index f894d3faf6c20ec8be170f8c77f1180e1614868e..483949bc96261bdb48c58912aca095fa7264e92f 100644 --- a/bob/bio/vein/configurations/algorithms.py +++ b/bob/bio/vein/configurations/algorithms.py @@ -1,41 +1,11 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -import facereclib - -from .. import tools as fingervein_tools - -huangwl_tool = fingervein_tools.MiuraMatch( - ch = 18, - cw = 28, -) - -huangwl_gpu_tool = fingervein_tools.MiuraMatch( - ch = 18, - cw = 28, - gpu = True, -) - - -miuramax_tool = fingervein_tools.MiuraMatch( - ch = 80, - cw = 90, -) - -miuramax_gpu_tool = fingervein_tools.MiuraMatch( - ch = 80, - cw = 90, - gpu = True, -) - -miurarlt_tool = fingervein_tools.MiuraMatch( - ch = 65, - cw = 55, -) - -miurarlt_gpu_tool = fingervein_tools.MiuraMatch( - ch = 65, - cw = 55, - gpu = True, -) - +from ..algorithms import MiuraMatch + +huangwl_tool = MiuraMatch(ch=18, cw=28) +huangwl_gpu_tool = MiuraMatch(ch=18, cw=28, gpu=True) +miuramax_tool = MiuraMatch(ch=80, cw=90) +miuramax_gpu_tool = MiuraMatch(ch=80, cw=90, gpu=True) +miurarlt_tool = MiuraMatch(ch=65, cw=55) +miurarlt_gpu_tool = MiuraMatch(ch=65, cw=55, gpu=True) diff --git a/bob/bio/vein/configurations/databases/__init__.py b/bob/bio/vein/configurations/databases/__init__.py index 053e9ef1a679c3751c301ae55d5f0670d3b0c404..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/bob/bio/vein/configurations/databases/__init__.py +++ b/bob/bio/vein/configurations/databases/__init__.py @@ -1,5 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <pedro.tome@idiap.ch> - -"""Configuration files for image databases""" diff --git a/bob/bio/vein/configurations/databases/utfvp.py b/bob/bio/vein/configurations/databases/utfvp.py index e9d34f5b700b72b90b6a04fa2a3628570b6e9850..dec39689f25e4fe14b98baa3747ae871020da9f2 100644 --- a/bob/bio/vein/configurations/databases/utfvp.py +++ b/bob/bio/vein/configurations/databases/utfvp.py @@ -1,14 +1,16 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : import bob.db.utfvp -import facereclib + +from bob.bio.base.database import DatabaseBob utfvp_directory = "/idiap/resource/database/UTFVP/data/" -database = facereclib.databases.DatabaseBob( +database = DatabaseBob( database = bob.db.utfvp.Database( original_directory = utfvp_directory, original_extension = ".png" - ), - name = 'utfvp', -) + ), + name = 'utfvp', + ) diff --git a/bob/bio/vein/configurations/databases/vera.py b/bob/bio/vein/configurations/databases/vera.py index f75194a892a9453442bb275457ffe832eeba2289..ddb1db55ae32979af5ad572ed00ca88bc8cebc2a 100644 --- a/bob/bio/vein/configurations/databases/vera.py +++ b/bob/bio/vein/configurations/databases/vera.py @@ -1,14 +1,16 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : import bob.db.vera -import facereclib + +from bob.bio.base.database import DatabaseBob vera_directory = "/idiap/project/vera" -database = facereclib.databases.DatabaseBob( +database = DatabaseBob( database = bob.db.vera.Database( original_directory = vera_directory, - original_extension = ".png", - ), + original_extension = ".png", + ), name = 'vera', -) \ No newline at end of file + ) diff --git a/bob/bio/vein/configurations/extractors/__init__.py b/bob/bio/vein/configurations/extractors/__init__.py index 81bb3b11a660a84f7bbd74e56fa4632dc35640bd..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/bob/bio/vein/configurations/extractors/__init__.py +++ b/bob/bio/vein/configurations/extractors/__init__.py @@ -1,5 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> - -"""Configuration files for feature extractors""" diff --git a/bob/bio/vein/configurations/extractors/lbp.py b/bob/bio/vein/configurations/extractors/lbp.py index 0df8b7118d80da6745fd9cbf81b49758be30d220..7d39059424674b7d05f7f10fb5592c7f7b21c12e 100644 --- a/bob/bio/vein/configurations/extractors/lbp.py +++ b/bob/bio/vein/configurations/extractors/lbp.py @@ -1,8 +1,7 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.fingervein +from ...extractors import LocalBinaryPatterns # Parameters @@ -18,25 +17,24 @@ LBP_CIRCULAR = True LBP_ROTATION_INVARIANT = False LBP_COMPARE_TO_AVERAGE = False LBP_ADD_AVERAGE = False + # histogram options SPARSE_HISTOGRAM = False SPLIT_HISTOGRAM = None - #Define feature extractor -feature_extractor = bob.fingervein.features.LocalBinaryPatterns( - block_size = BLOCK_SIZE, # one or two parameters for block size - block_overlap = BLOCK_OVERLAP, # one or two parameters for block overlap - lbp_radius = LBP_RADIUS, - lbp_neighbor_count = LBP_NEIGHBOR_COUNT, - lbp_uniform = LBP_UNIFORM, - lbp_circular = LBP_CIRCULAR, - lbp_rotation_invariant = LBP_ROTATION_INVARIANT, - lbp_compare_to_average = LBP_COMPARE_TO_AVERAGE, - lbp_add_average = LBP_ADD_AVERAGE, +feature_extractor = LocalBinaryPatterns( + block_size=BLOCK_SIZE, # one or two parameters for block size + block_overlap=BLOCK_OVERLAP, # one or two parameters for block overlap + lbp_radius=LBP_RADIUS, + lbp_neighbor_count=LBP_NEIGHBOR_COUNT, + lbp_uniform=LBP_UNIFORM, + lbp_circular=LBP_CIRCULAR, + lbp_rotation_invariant=LBP_ROTATION_INVARIANT, + lbp_compare_to_average=LBP_COMPARE_TO_AVERAGE, + lbp_add_average=LBP_ADD_AVERAGE, # histogram options - sparse_histogram = SPARSE_HISTOGRAM, - split_histogram = SPLIT_HISTOGRAM + sparse_histogram=SPARSE_HISTOGRAM, + split_histogram=SPLIT_HISTOGRAM ) - diff --git a/bob/bio/vein/configurations/extractors/maximum_curvature.py b/bob/bio/vein/configurations/extractors/maximum_curvature.py index 43cf925430a938dcae9f3691b633f02a0ae430dc..4721738dce36f7b292065752ae7956136fdbd24b 100644 --- a/bob/bio/vein/configurations/extractors/maximum_curvature.py +++ b/bob/bio/vein/configurations/extractors/maximum_curvature.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.fingervein +from ...extractors import LocalBinaryPatterns -# Parameters + +# Parameters SIGMA_DERIVATES = 5 #Sigma used for determining derivatives GPU_ACCELERATION = False @@ -13,6 +13,6 @@ GPU_ACCELERATION = False feature_extractor = bob.fingervein.features.MaximumCurvature( sigma = SIGMA_DERIVATES, gpu = GPU_ACCELERATION - + ) diff --git a/bob/bio/vein/configurations/extractors/normalised_crosscorr.py b/bob/bio/vein/configurations/extractors/normalised_crosscorr.py index dee948ffe8a871e08c33d49cc604347276d9776b..310ae25bdb625cb4894e2cea777a860c81e2b4f1 100644 --- a/bob/bio/vein/configurations/extractors/normalised_crosscorr.py +++ b/bob/bio/vein/configurations/extractors/normalised_crosscorr.py @@ -1,13 +1,6 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.fingervein - -# Parameters - -#Define feature extractor -feature_extractor = bob.fingervein.features.NormalisedCrossCorrelation( - -) +from ...extractors import NormalisedCrossCorrelation +feature_extractor = bob.fingervein.features.NormalisedCrossCorrelation() diff --git a/bob/bio/vein/configurations/extractors/repeated_line_tracking.py b/bob/bio/vein/configurations/extractors/repeated_line_tracking.py index f581bf767cdb0902b697f7df4466858827c0e667..0d22b40228e1567f71d07012b9b3013ebaec32d1 100644 --- a/bob/bio/vein/configurations/extractors/repeated_line_tracking.py +++ b/bob/bio/vein/configurations/extractors/repeated_line_tracking.py @@ -1,19 +1,20 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.fingervein +from ...extractors import RepeatedLineTracking -# Parameters -NUMBER_ITERATIONS = 3000 # Maximum number of iterations -DISTANCE_R = 1 # Distance between tracking point and cross section of the profile -PROFILE_WIDTH = 21 # Width of profile +# Maximum number of iterations +NUMBER_ITERATIONS = 3000 +# Distance between tracking point and cross section of profile +DISTANCE_R = 1 -#Define feature extractor -feature_extractor = bob.fingervein.features.RepeatedLineTracking( - iterations = NUMBER_ITERATIONS, - r = DISTANCE_R, - profile_w = PROFILE_WIDTH -) +# Width of profile +PROFILE_WIDTH = 21 + +feature_extractor = RepeatedLineTracking( + iterations=NUMBER_ITERATIONS, + r=DISTANCE_R, + profile_w=PROFILE_WIDTH + ) diff --git a/bob/bio/vein/configurations/extractors/wide_line_detector.py b/bob/bio/vein/configurations/extractors/wide_line_detector.py index f1b868d0b8959ece730779782dd054f358e786fb..80e33b59e620fb084353957bcafedcf13c97b100 100644 --- a/bob/bio/vein/configurations/extractors/wide_line_detector.py +++ b/bob/bio/vein/configurations/extractors/wide_line_detector.py @@ -1,20 +1,19 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> import bob.fingervein # Parameters RADIUS_NEIGHBOURHOOD_REGION = 5 # Radius of the circular neighbourhood region -NEIGHBOURHOOD_THRESHOLD = 1 -SUM_NEIGHBOURHOOD = 41 #Sum of neigbourhood threshold +NEIGHBOURHOOD_THRESHOLD = 1 +SUM_NEIGHBOURHOOD = 41 #Sum of neigbourhood threshold RESCALE = True #Define feature extractor feature_extractor = bob.fingervein.features.WideLineDetector( - radius = RADIUS_NEIGHBOURHOOD_REGION, + radius = RADIUS_NEIGHBOURHOOD_REGION, threshold = NEIGHBOURHOOD_THRESHOLD, - g = SUM_NEIGHBOURHOOD, - rescale = RESCALE + g = SUM_NEIGHBOURHOOD, + rescale = RESCALE ) diff --git a/bob/bio/vein/configurations/grid/__init__.py b/bob/bio/vein/configurations/grid/__init__.py index 0a07e79c040ada55ae8800c51e4298e8504e3159..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/bob/bio/vein/configurations/grid/__init__.py +++ b/bob/bio/vein/configurations/grid/__init__.py @@ -1,5 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> - -"""Configuration files for SGE grid executions""" diff --git a/bob/bio/vein/configurations/grid/demanding.py b/bob/bio/vein/configurations/grid/demanding.py index 1b13438907e8051839f5626c8b0053fe9bd95b65..475c1cd7712c60d9a43f11b8c77a3fa5a4dc30c5 100644 --- a/bob/bio/vein/configurations/grid/demanding.py +++ b/bob/bio/vein/configurations/grid/demanding.py @@ -1,23 +1,24 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : -import facereclib - -# define a queue with demanding parameters -grid = facereclib.utils.GridParameters( - training_queue = '32G', - # preprocessing - number_of_preprocessings_per_job = 200, - preprocessing_queue = '4G', - # feature extraction - number_of_extracted_features_per_job = 200, - extraction_queue = '8G', - # feature projection - number_of_projected_features_per_job = 200, - projection_queue = '8G', - # model enrollment - number_of_enrolled_models_per_job = 10, - enrollment_queue = '8G', - # scoring - number_of_models_per_scoring_job = 10, - scoring_queue = '8G' -) +import bob.bio.base.grid import Grid + + +grid = Grid( + training_queue='32G', + + number_of_preprocessings_per_job=200, + preprocessing_queue='4G', + + number_of_extraction_jobs=200, + extraction_queue='8G', + + number_of_projection_jobs=200, + projection_queue='8G', + + number_of_enrollment_jobs=10, + enrollment_queue='8G', + + number_of_scoring_jobs=10, + scoring_queue='8G', + ) diff --git a/bob/bio/vein/configurations/grid/gbu.py b/bob/bio/vein/configurations/grid/gbu.py index 2970511ddf3e6fae61e5bfcf834d247fae397911..471c7e6c5da0824407efadb260a82037245a17cd 100644 --- a/bob/bio/vein/configurations/grid/gbu.py +++ b/bob/bio/vein/configurations/grid/gbu.py @@ -1,24 +1,24 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : -import facereclib - -# define a queue specifically for the xbob.db.gbu database -grid = facereclib.utils.GridParameters( - training_queue = '32G', - # preprocessing - number_of_preprocessings_per_job = 1000, - preprocessing_queue = '8G', - # feature extraction - number_of_extracted_features_per_job = 100, - extraction_queue = '8G', - # feature projection - number_of_projected_features_per_job = 100, - projection_queue = '8G', - # model enrollment - number_of_enrolled_models_per_job = 100, - enrollment_queue = '8G', - # scoring - number_of_models_per_scoring_job = 10, - scoring_queue = '8G' -) +import bob.bio.base.grid import Grid + +grid = Grid( + training_queue = '32G', + + number_of_preprocessing_jobs = 1000, + preprocessing_queue = '8G', + + number_of_extraction_jobs = 100, + extraction_queue = '8G', + + number_of_projection_jobs = 100, + projection_queue = '8G', + + number_of_enrollment_jobs = 100, + enrollment_queue = '8G', + + number_of_scoring_jobs = 10, + scoring_queue = '8G' + ) diff --git a/bob/bio/vein/configurations/grid/gpu.py b/bob/bio/vein/configurations/grid/gpu.py index 2e4848fdcbf3d47e97365f575c1b28fb77f78886..5ca10c5aa22564cd9061f5d1dd50474df8f7bb89 100644 --- a/bob/bio/vein/configurations/grid/gpu.py +++ b/bob/bio/vein/configurations/grid/gpu.py @@ -1,25 +1,24 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : -import facereclib - -# setup of the grid parameters -# define a queue with demanding parameters -grid = facereclib.utils.GridParameters( - training_queue = '8G', - # preprocessing - number_of_preprocessing_jobs = 32, - preprocessing_queue = '4G-io-big', - # feature extraction - number_of_extraction_jobs = 32, - extraction_queue = '4G-io-big', - # feature projection - number_of_projection_jobs = 32, - projection_queue = {}, - # model enrollment - number_of_enrollment_jobs = 32, - enrollment_queue = {}, - # scoring - number_of_scoring_jobs = 32, - scoring_queue = {'queue': 'q_gpu'}, -) +import bob.bio.base.grid import Grid + +grid = Grid( + training_queue = '8G', + + number_of_preprocessing_jobs = 32, + preprocessing_queue = '4G-io-big', + + number_of_extraction_jobs = 32, + extraction_queue = '4G-io-big', + + number_of_projection_jobs = 32, + projection_queue = {}, + + number_of_enrollment_jobs = 32, + enrollment_queue = {}, + + number_of_scoring_jobs = 32, + scoring_queue = {'queue': 'q_gpu'}, + ) diff --git a/bob/bio/vein/configurations/grid/gpu2.py b/bob/bio/vein/configurations/grid/gpu2.py index 7f0e444753cb2449bb38d5ec8f6ce0fc55edd56f..02d04550a99a65c35de14e006d7a655ed8580420 100644 --- a/bob/bio/vein/configurations/grid/gpu2.py +++ b/bob/bio/vein/configurations/grid/gpu2.py @@ -1,24 +1,24 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : -import facereclib - -# setup of the grid parameters -# define a queue with demanding parameters -grid = facereclib.utils.GridParameters( - training_queue = '8G', - # preprocessing - number_of_preprocessing_jobs = 32, - preprocessing_queue = '4G-io-big', - # feature extraction - number_of_extraction_jobs = 32, - extraction_queue = '4G-io-big', - # feature projection - number_of_projection_jobs = 32, - projection_queue = {}, - # model enrollment - number_of_enrollment_jobs = 32, - enrollment_queue = {}, - # scoring - number_of_scoring_jobs = 32, - scoring_queue = '4G-io-big', -) +import bob.bio.base.grid import Grid + + +grid = Grid( + training_queue = '8G', + + number_of_preprocessing_jobs = 32, + preprocessing_queue = '4G-io-big', + + number_of_extraction_jobs = 32, + extraction_queue = '4G-io-big', + + number_of_projection_jobs = 32, + projection_queue = {}, + + number_of_enrollment_jobs = 32, + enrollment_queue = {}, + + number_of_scoring_jobs = 32, + scoring_queue = '4G-io-big', + ) diff --git a/bob/bio/vein/configurations/grid/gpu3.py b/bob/bio/vein/configurations/grid/gpu3.py index 363d209f5eaad9dca3ebb8de131c676a708dc2f6..4d0d2b972ad378da404f3f4e521264900d8dd2af 100644 --- a/bob/bio/vein/configurations/grid/gpu3.py +++ b/bob/bio/vein/configurations/grid/gpu3.py @@ -1,25 +1,24 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : -import facereclib - -# setup of the grid parameters -# define a queue with demanding parameters -grid = facereclib.utils.GridParameters( - training_queue = '8G', - # preprocessing - number_of_preprocessings_per_job = 1000, - preprocessing_queue = {}, - # feature extraction - number_of_extracted_features_per_job = 1000, - extraction_queue = {}, - # feature projection - number_of_projected_features_per_job = 1000, - projection_queue = {}, - # model enrollment - number_of_enrolled_models_per_job = 100, - enrollment_queue = '2G', - # scoring - number_of_models_per_scoring_job = 1500, - scoring_queue = {'queue': 'q_gpu'}, -) +import bob.bio.base.grid import Grid + +grid = Grid( + training_queue = '8G', + + number_of_preprocessing_jobs = 1000, + preprocessing_queue = {}, + + number_of_extraction_jobs = 1000, + extraction_queue = {}, + + number_of_projection_jobs = 1000, + projection_queue = {}, + + number_of_enrollment_jobs = 100, + enrollment_queue = '2G', + + number_of_scoring_jobs = 1500, + scoring_queue = {'queue': 'q_gpu'}, + ) diff --git a/bob/bio/vein/configurations/grid/grid.py b/bob/bio/vein/configurations/grid/grid.py index 8b882567d16a61d1ad4aab74db77e7004e4e9a83..b0b1080cc552381f565e3ced315cbf2fa3d07db9 100644 --- a/bob/bio/vein/configurations/grid/grid.py +++ b/bob/bio/vein/configurations/grid/grid.py @@ -1,7 +1,7 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : -import facereclib +import bob.bio.base.grid import Grid -# define the queue using all the default parameters -grid = facereclib.utils.GridParameters( -) + +grid = Grid() diff --git a/bob/bio/vein/configurations/grid/large.py b/bob/bio/vein/configurations/grid/large.py deleted file mode 100644 index 3a051a4514e2bd2cac6a40accf108a8f8f634168..0000000000000000000000000000000000000000 --- a/bob/bio/vein/configurations/grid/large.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python - -# setup of the grid parameters - -# default queue used for training -training_queue = { 'queue':'q1d', 'memfree':'8G' } - -# number of images that one job should preprocess -number_of_images_per_job = 1000 -preprocessing_queue = {} - -# number of features that one job should extract -number_of_features_per_job = 10000 -extraction_queue = {} - -# number of features that one job should project -number_of_projections_per_job = 100000 -projection_queue = {} - -# number of models that should be enrolled by one enroll job -number_of_models_per_enroll_job = 1000 -enroll_queue = {} - -# number of models that one score computation should use -number_of_models_per_score_job = 500 -score_queue = {} diff --git a/bob/bio/vein/configurations/grid/local.py b/bob/bio/vein/configurations/grid/local.py index 755fa9c168b27235f2989cbc61c6016084263bbe..a5cb82d1a9fbafe1fe2beccd06750f6bcb0f96db 100644 --- a/bob/bio/vein/configurations/grid/local.py +++ b/bob/bio/vein/configurations/grid/local.py @@ -1,21 +1,20 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : -import facereclib +import bob.bio.base.grid import Grid -# define the queue using all the default parameters -grid = facereclib.utils.GridParameters( + +grid = Grid( grid = 'local', number_of_parallel_processes = 4 ) -# define a queue that is highly parallelized -grid_p16 = facereclib.utils.GridParameters( - number_of_preprocessings_per_job = 50, - number_of_extracted_features_per_job = 50, - number_of_projected_features_per_job = 50, - number_of_enrolled_models_per_job = 10, - number_of_models_per_scoring_job = 10, - +grid_p16 = Grid( + number_of_preprocessing_jobs = 50, + number_of_extraction_jobs = 50, + number_of_projection_jobs = 50, + number_of_enrollment_jobs = 10, + number_of_scoring_jobs = 10, grid = 'local', number_of_parallel_processes = 4 ) diff --git a/bob/bio/vein/configurations/grid/small.py b/bob/bio/vein/configurations/grid/small.py deleted file mode 100644 index 8e6eccb50e1ee7d5a322e0be0dfe8662000b1a96..0000000000000000000000000000000000000000 --- a/bob/bio/vein/configurations/grid/small.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -import facereclib - -# define a queue for small databases -grid = facereclib.utils.GridParameters( - training_queue = '8G', - # preprocessing - number_of_preprocessings_per_job = 20, - # feature extraction - number_of_extracted_features_per_job = 20, - # feature projection - number_of_projected_features_per_job = 20, - # model enrollment - number_of_enrolled_models_per_job = 5, - # scoring - number_of_models_per_scoring_job = 5, -) diff --git a/bob/bio/vein/configurations/grid/very_demanding.py b/bob/bio/vein/configurations/grid/very_demanding.py index 51ac3bdedf5b2850fc44ca1b892c49dad1903d40..ea16a0dbd2819b1772d3850d350157d8ab4da413 100644 --- a/bob/bio/vein/configurations/grid/very_demanding.py +++ b/bob/bio/vein/configurations/grid/very_demanding.py @@ -1,23 +1,24 @@ #!/usr/bin/env python +# vim: set fileencoding=utf-8 : -import facereclib - -# define a queue with very demanding parameters -grid = facereclib.utils.GridParameters( - training_queue = '64G', - # preprocessing - number_of_preprocessings_per_job = 100, - preprocessing_queue = '4G', - # feature extraction - number_of_extracted_features_per_job = 100, - extraction_queue = '8G-io-big', - # feature projection - number_of_projected_features_per_job = 20, - projection_queue = '8G-io-big', - # model enrollment - number_of_enrolled_models_per_job = 2, - enrollment_queue = '8G-io-big', - # scoring - number_of_models_per_scoring_job = 1, - scoring_queue = '8G-io-big' -) +import bob.bio.base.grid import Grid + + +grid = Grid( + training_queue = '64G', + + number_of_preprocessing_jobs = 100, + preprocessing_queue = '4G', + + number_of_extraction_jobs = 100, + extraction_queue = '8G-io-big', + + number_of_projection_jobs = 20, + projection_queue = '8G-io-big', + + number_of_enrollment_jobs = 2, + enrollment_queue = '8G-io-big', + + number_of_scoring_jobs = 1, + scoring_queue = '8G-io-big' + ) diff --git a/bob/bio/vein/configurations/preprocessors/__init__.py b/bob/bio/vein/configurations/preprocessors/__init__.py index 9d7600217ea0136a7b2e067ff27f00dcb3c946da..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/bob/bio/vein/configurations/preprocessors/__init__.py +++ b/bob/bio/vein/configurations/preprocessors/__init__.py @@ -1,5 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> - -"""Configuration files for image preprocessors""" diff --git a/bob/bio/vein/configurations/preprocessors/finger_crop_None_CircGabor.py b/bob/bio/vein/configurations/preprocessors/finger_crop_None_CircGabor.py index 702eae37896e322f52e59da2852e26a17ec85d56..909a31ea2a5ea623bcf6a0e3036d8637dd19aea7 100644 --- a/bob/bio/vein/configurations/preprocessors/finger_crop_None_CircGabor.py +++ b/bob/bio/vein/configurations/preprocessors/finger_crop_None_CircGabor.py @@ -1,10 +1,9 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.fingervein +from ...preprocessors import FingerCrop -# Contour localization mask +# Contour localization mask CONTOUR_MASK_HEIGHT = 4 # Height of the mask CONTOUR_MASK_WIDTH = 40 # Width of the mask @@ -12,20 +11,19 @@ PADDING_OFFSET = 5 PADDING_THRESHOLD = 0.2 #Threshold for padding black zones PREPROCESSING = None -FINGERCONTOUR = 'leemaskMod' # Options: 'leemaskMatlab', 'konomask' +FINGERCONTOUR = 'leemaskMod' # Options: 'leemaskMatlab', 'konomask' POSTPROCESSING = 'CircGabor' # Options: None, 'HE', 'HFE', 'CircGabor' GPU_ACCELERATION = False # define the preprocessor -preprocessor = bob.fingervein.preprocessing.FingerCrop( - mask_h =CONTOUR_MASK_HEIGHT, - mask_w =CONTOUR_MASK_WIDTH, - padding_offset = PADDING_OFFSET, - padding_threshold = PADDING_THRESHOLD, - preprocessing = PREPROCESSING, - fingercontour = FINGERCONTOUR, - postprocessing = POSTPROCESSING, - gpu = GPU_ACCELERATION -) - +preprocessor = FingerCrop( + mask_h=CONTOUR_MASK_HEIGHT, + mask_w=CONTOUR_MASK_WIDTH, + padding_offset=PADDING_OFFSET, + padding_threshold=PADDING_THRESHOLD, + preprocessing=PREPROCESSING, + fingercontour=FINGERCONTOUR, + postprocessing=POSTPROCESSING, + gpu=GPU_ACCELERATION, + ) diff --git a/bob/bio/vein/configurations/preprocessors/finger_crop_None_HE.py b/bob/bio/vein/configurations/preprocessors/finger_crop_None_HE.py index 6ccac04e4cda413310e1ac9a730e05081341ed8f..8b317a71142be5612a5c11fe70b2168317805759 100644 --- a/bob/bio/vein/configurations/preprocessors/finger_crop_None_HE.py +++ b/bob/bio/vein/configurations/preprocessors/finger_crop_None_HE.py @@ -1,10 +1,9 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.fingervein +from ...preprocessors import FingerCrop -# Contour localization mask +# Contour localization mask CONTOUR_MASK_HEIGHT = 4 # Height of the mask CONTOUR_MASK_WIDTH = 40 # Width of the mask @@ -12,20 +11,19 @@ PADDING_OFFSET = 5 PADDING_THRESHOLD = 0.2 #Threshold for padding black zones PREPROCESSING = None -FINGERCONTOUR = 'leemaskMod' # Options: 'leemaskMatlab', 'konomask' +FINGERCONTOUR = 'leemaskMod' # Options: 'leemaskMatlab', 'konomask' POSTPROCESSING = 'HE' # Options: None, 'HE', 'HFE', 'CircGabor' GPU_ACCELERATION = False # define the preprocessor -preprocessor = bob.fingervein.preprocessing.FingerCrop( - mask_h =CONTOUR_MASK_HEIGHT, - mask_w =CONTOUR_MASK_WIDTH, - padding_offset = PADDING_OFFSET, - padding_threshold = PADDING_THRESHOLD, - preprocessing = PREPROCESSING, - fingercontour = FINGERCONTOUR, - postprocessing = POSTPROCESSING, - gpu = GPU_ACCELERATION -) - +preprocessor = FingerCrop( + mask_h=CONTOUR_MASK_HEIGHT, + mask_w=CONTOUR_MASK_WIDTH, + padding_offset=PADDING_OFFSET, + padding_threshold=PADDING_THRESHOLD, + preprocessing=PREPROCESSING, + fingercontour=FINGERCONTOUR, + postprocessing=POSTPROCESSING, + gpu=GPU_ACCELERATION + ) diff --git a/bob/bio/vein/configurations/preprocessors/finger_crop_None_HFE.py b/bob/bio/vein/configurations/preprocessors/finger_crop_None_HFE.py index 607326888bcc45aa326999f7eeede22e3081832e..6f1991e753c5deda7f6c413b18c7ca53a32f66eb 100644 --- a/bob/bio/vein/configurations/preprocessors/finger_crop_None_HFE.py +++ b/bob/bio/vein/configurations/preprocessors/finger_crop_None_HFE.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.fingervein +from ...preprocessors import FingerCrop -# Contour localization mask + +# Contour localization mask CONTOUR_MASK_HEIGHT = 4 # Height of the mask CONTOUR_MASK_WIDTH = 40 # Width of the mask @@ -12,20 +12,19 @@ PADDING_OFFSET = 5 PADDING_THRESHOLD = 0.2 #Threshold for padding black zones PREPROCESSING = None -FINGERCONTOUR = 'leemaskMod' # Options: 'leemaskMatlab', 'konomask' +FINGERCONTOUR = 'leemaskMod' # Options: 'leemaskMatlab', 'konomask' POSTPROCESSING = 'HFE' # Options: None, 'HE', 'HFE', 'CircGabor' GPU_ACCELERATION = False # define the preprocessor -preprocessor = bob.fingervein.preprocessing.FingerCrop( - mask_h =CONTOUR_MASK_HEIGHT, - mask_w =CONTOUR_MASK_WIDTH, - padding_offset = PADDING_OFFSET, - padding_threshold = PADDING_THRESHOLD, - preprocessing = PREPROCESSING, - fingercontour = FINGERCONTOUR, - postprocessing = POSTPROCESSING, - gpu = GPU_ACCELERATION -) - +preprocessor = FingerCrop( + mask_h=CONTOUR_MASK_HEIGHT, + mask_w=CONTOUR_MASK_WIDTH, + padding_offset=PADDING_OFFSET, + padding_threshold=PADDING_THRESHOLD, + preprocessing=PREPROCESSING, + fingercontour=FINGERCONTOUR, + postprocessing=POSTPROCESSING, + gpu=GPU_ACCELERATION + ) diff --git a/bob/bio/vein/configurations/preprocessors/finger_crop_None_None.py b/bob/bio/vein/configurations/preprocessors/finger_crop_None_None.py index 168d74767d2d7b1f8f3e10901a80266bb8634ae1..9366aa66846220ab4b81090fb0f515781cb5c1f9 100644 --- a/bob/bio/vein/configurations/preprocessors/finger_crop_None_None.py +++ b/bob/bio/vein/configurations/preprocessors/finger_crop_None_None.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.fingervein +from ...preprocessors import FingerCrop -# Contour localization mask + +# Contour localization mask CONTOUR_MASK_HEIGHT = 4 # Height of the mask CONTOUR_MASK_WIDTH = 40 # Width of the mask @@ -12,20 +12,19 @@ PADDING_OFFSET = 5 PADDING_THRESHOLD = 0.2 #Threshold for padding black zones PREPROCESSING = None -FINGERCONTOUR = 'leemaskMod' # Options: 'leemaskMod', leemaskMatlab', 'konomask' +FINGERCONTOUR = 'leemaskMod' # Options: 'leemaskMod', leemaskMatlab', 'konomask' POSTPROCESSING = None # Options: None, 'HE', 'HFE', 'CircGabor' GPU_ACCELERATION = False # define the preprocessor -preprocessor = bob.fingervein.preprocessing.FingerCrop( - mask_h =CONTOUR_MASK_HEIGHT, - mask_w =CONTOUR_MASK_WIDTH, - padding_offset = PADDING_OFFSET, - padding_threshold = PADDING_THRESHOLD, - preprocessing = PREPROCESSING, - fingercontour = FINGERCONTOUR, - postprocessing = POSTPROCESSING, - gpu = GPU_ACCELERATION -) - +preprocessor = FingerCrop( + mask_h=CONTOUR_MASK_HEIGHT, + mask_w=CONTOUR_MASK_WIDTH, + padding_offset=PADDING_OFFSET, + padding_threshold=PADDING_THRESHOLD, + preprocessing=PREPROCESSING, + fingercontour=FINGERCONTOUR, + postprocessing=POSTPROCESSING, + gpu=GPU_ACCELERATION + ) diff --git a/bob/bio/vein/extractors/LocalBinaryPatterns.py b/bob/bio/vein/extractors/LocalBinaryPatterns.py index 20c08eb92afe360dc949744aa44c08e7eb2e8fb8..178e0498b6e94ee7e012f0b3b4bca7cfe0b87d7b 100644 --- a/bob/bio/vein/extractors/LocalBinaryPatterns.py +++ b/bob/bio/vein/extractors/LocalBinaryPatterns.py @@ -1,10 +1,11 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> + +import numpy import bob.ip.base import bob.io.base -import numpy + from bob.bio.base.features.Extractor import Extractor diff --git a/bob/bio/vein/extractors/MaximumCurvature.py b/bob/bio/vein/extractors/MaximumCurvature.py index 08d3b2c9f29b1d58bf335a7cae70066fdc9579b9..251d1ca6aae2752efe81483fd4844d2d4737583c 100644 --- a/bob/bio/vein/extractors/MaximumCurvature.py +++ b/bob/bio/vein/extractors/MaximumCurvature.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> import math import numpy diff --git a/bob/bio/vein/extractors/NormalisedCrossCorrelation.py b/bob/bio/vein/extractors/NormalisedCrossCorrelation.py index 75a94158ba25592fe67aa7fff022d88c6ac8889f..563d1e9ceb0f1b0f7d5cd93dae84ec3f74c4b07b 100644 --- a/bob/bio/vein/extractors/NormalisedCrossCorrelation.py +++ b/bob/bio/vein/extractors/NormalisedCrossCorrelation.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> import numpy diff --git a/bob/bio/vein/extractors/PrincipalCurvature.py b/bob/bio/vein/extractors/PrincipalCurvature.py index 5ea46c2c3bd8ce7d2e6616a6137fbfb86cb8400c..17b33d582e6476c38f61a17fb47e456d78485e8c 100644 --- a/bob/bio/vein/extractors/PrincipalCurvature.py +++ b/bob/bio/vein/extractors/PrincipalCurvature.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -import bob.io.base import numpy +import bob.io.base from bob.bio.base.features.Extractor import Extractor + class MaximumCurvature (Extractor): """MiuraMax feature extractor diff --git a/bob/bio/vein/extractors/RepeatedLineTracking.py b/bob/bio/vein/extractors/RepeatedLineTracking.py index 8dce5ec08edae349a3026d42d9e2aeaceeb024b2..0ab4b22d0c84839847dec806664707143c248b49 100644 --- a/bob/bio/vein/extractors/RepeatedLineTracking.py +++ b/bob/bio/vein/extractors/RepeatedLineTracking.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> import numpy import math diff --git a/bob/bio/vein/extractors/WideLineDetector.py b/bob/bio/vein/extractors/WideLineDetector.py index 505e891dfab8fcfe31d88be974c21ea5d212acb7..78cfbcb7cf143c130fc92829f0eefd6ec95e9602 100644 --- a/bob/bio/vein/extractors/WideLineDetector.py +++ b/bob/bio/vein/extractors/WideLineDetector.py @@ -1,14 +1,13 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> - -import bob.io.base -import bob.ip.base import numpy import scipy import scipy.misc +import bob.io.base +import bob.ip.base + from bob.bio.base.features.Extractor import Extractor diff --git a/bob/bio/vein/preprocessors/FingerCrop.py b/bob/bio/vein/preprocessors/FingerCrop.py index c4855d61bdafae84de8e670aacd8b13965581224..218f38aa97e26cbe6dd3c3a91271d2a95c537f3f 100644 --- a/bob/bio/vein/preprocessors/FingerCrop.py +++ b/bob/bio/vein/preprocessors/FingerCrop.py @@ -1,48 +1,37 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# @author: # Pedro Tome <Pedro.Tome@idiap.ch> -# @date: Thu Mar 27 10:21:42 CEST 2014 -# -# Copyright (C) 2014-2015 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/>. + +import math +import numpy +from PIL import Image import bob.io.base import bob.ip.base import bob.sp import bob.core -import numpy -import math -from facereclib.preprocessing.Preprocessor import Preprocessor +from bob.bio.base.preprocessor import Preprocessor + from .. import utils -from PIL import Image + class FingerCrop (Preprocessor): - """Fingervein mask based on the implementation: - E.C. Lee, H.C. Lee and K.R. Park. Finger vein recognition using minutia-based alignment and - local binary pattern-based feature extraction. International Journal of Imaging Systems and - Technology. Vol. 19, No. 3, pp. 175-178, September 2009. - """ + """Fingervein mask + + Based on the implementation: E.C. Lee, H.C. Lee and K.R. Park. Finger vein + recognition using minutia-based alignment and local binary pattern-based + feature extraction. International Journal of Imaging Systems and + Technology. Vol. 19, No. 3, pp. 175-178, September 2009. + """ def __init__( self, mask_h = 4, # Height of the mask mask_w = 40, # Width of the mask - + padding_offset = 5, #Always the same padding_threshold = 0.2, #0 for UTFVP database (high quality), 0.2 for VERA database (low quality) - + preprocessing = None, fingercontour = 'leemaskMatlab', postprocessing = None, @@ -61,7 +50,7 @@ class FingerCrop (Preprocessor): mask_w Height of the cropped mask of a fingervein image - + """ # call base class constructor @@ -69,10 +58,10 @@ class FingerCrop (Preprocessor): self, mask_h = mask_h, mask_w = mask_w, - - padding_offset = padding_offset, + + padding_offset = padding_offset, padding_threshold = padding_threshold, - + preprocessing = preprocessing, fingercontour = fingercontour, postprocessing = postprocessing, @@ -84,25 +73,25 @@ class FingerCrop (Preprocessor): self.mask_h = mask_h self.mask_w = mask_w - + self.preprocessing = preprocessing self.fingercontour = fingercontour self.postprocessing = postprocessing - self.padding_offset = padding_offset - self.padding_threshold = padding_threshold + self.padding_offset = padding_offset + self.padding_threshold = padding_threshold self.gpu = gpu self.color_channel = color_channel - - + + def __konomask__(self, image, sigma): - """ M. Kono, H. Ueki and S. Umemura. Near-infrared finger vein patterns for personal identification, + """ M. Kono, H. Ueki and S. Umemura. Near-infrared finger vein patterns for personal identification, Applied Optics, Vol. 41, Issue 35, pp. 7429-7436 (2002). - """ - + """ + sigma = 5 img_h,img_w = image.shape - + # Determine lower half starting point if numpy.mod(img_h,2) == 0: half_img_h = img_h/2 + 1 @@ -115,9 +104,9 @@ class FingerCrop (Preprocessor): x = numpy.arange(-winsize, winsize+1) y = numpy.arange(-winsize, winsize+1) X, Y = numpy.meshgrid(x, y) - + hy = (-Y/(2*math.pi*sigma**4))*numpy.exp(-(X**2 + Y**2)/(2*sigma**2)) - + # Filter the image with the directional kernel fy = utils.imfilter(image, hy, self.gpu, conv=False) @@ -128,105 +117,105 @@ class FingerCrop (Preprocessor): # Lower part of filtred image img_filt_lo = fy[half_img_h-1:,:] y_lo = img_filt_lo.argmin(axis=0) - - # Fill region between upper and lower edges - finger_mask = numpy.ndarray(image.shape, numpy.bool) + + # Fill region between upper and lower edges + finger_mask = numpy.ndarray(image.shape, numpy.bool) finger_mask[:,:] = False for i in range(0,img_w): finger_mask[y_up[i]:y_lo[i]+image.shape[0]-half_img_h+2,i] = True - + # Extract y-position of finger edges edges = numpy.zeros((2,img_w)) edges[0,:] = y_up - edges[1,:] = y_lo + image.shape[0] - half_img_h + 1 - + edges[1,:] = y_lo + image.shape[0] - half_img_h + 1 + return (finger_mask, edges) - + def __leemaskMod__(self, image): - + img_h,img_w = image.shape - + # Determine lower half starting point vertically if numpy.mod(img_h,2) == 0: half_img_h = img_h/2 + 1 else: half_img_h = numpy.ceil(img_h/2) - + # Determine lower half starting point horizontally if numpy.mod(img_w,2) == 0: half_img_w = img_w/2 + 1 else: half_img_w = numpy.ceil(img_w/2) - # Construct mask for filtering + # Construct mask for filtering mask = numpy.zeros((self.mask_h,self.mask_w)) mask[0:self.mask_h/2,:] = -1 mask[self.mask_h/2:,:] = 1 img_filt = utils.imfilter(image, mask, self.gpu, conv=True) - + # Upper part of filtred image img_filt_up = img_filt[0:half_img_h-1,:] y_up = img_filt_up.argmax(axis=0) - + # Lower part of filtred image img_filt_lo = img_filt[half_img_h-1:,:] y_lo = img_filt_lo.argmin(axis=0) - + img_filt = utils.imfilter(image, mask.T, self.gpu, conv=True) - + # Left part of filtered image img_filt_lf = img_filt[:,0:half_img_w] y_lf = img_filt_lf.argmax(axis=1) - + # Right part of filtred image img_filt_rg = img_filt[:,half_img_w:] y_rg = img_filt_rg.argmin(axis=1) - - finger_mask = numpy.ndarray(image.shape, numpy.bool) + + finger_mask = numpy.ndarray(image.shape, numpy.bool) finger_mask[:,:] = False - + for i in range(0,y_up.size): finger_mask[y_up[i]:y_lo[i]+img_filt_lo.shape[0]+1,i] = True - + # Left region for i in range(0,y_lf.size): finger_mask[i,0:y_lf[i]+1] = False - + # Right region has always the finger ending, crop the padding with the meadian - finger_mask[:,numpy.median(y_rg)+img_filt_rg.shape[1]:] = False - + finger_mask[:,numpy.median(y_rg)+img_filt_rg.shape[1]:] = False + # Extract y-position of finger edges edges = numpy.zeros((2,img_w)) edges[0,:] = y_up - edges[0,0:round(numpy.mean(y_lf))+1] = edges[0,round(numpy.mean(y_lf))+1] - - - edges[1,:] = numpy.round(y_lo + img_filt_lo.shape[0]) - edges[1,0:round(numpy.mean(y_lf))+1] = edges[1,round(numpy.mean(y_lf))+1] - + edges[0,0:round(numpy.mean(y_lf))+1] = edges[0,round(numpy.mean(y_lf))+1] + + + edges[1,:] = numpy.round(y_lo + img_filt_lo.shape[0]) + edges[1,0:round(numpy.mean(y_lf))+1] = edges[1,round(numpy.mean(y_lf))+1] + return (finger_mask, edges) - - + + def __leemaskMatlab__(self, image): img_h,img_w = image.shape - + # Determine lower half starting point if numpy.mod(img_h,2) == 0: half_img_h = img_h/2 + 1 else: half_img_h = numpy.ceil(img_h/2) - - # Construct mask for filtering + + # Construct mask for filtering mask = numpy.zeros((self.mask_h,self.mask_w)) mask[0:self.mask_h/2,:] = -1 mask[self.mask_h/2:,:] = 1 img_filt = utils.imfilter(image, mask, self.gpu, conv=True) - + # Upper part of filtred image img_filt_up = img_filt[0:numpy.floor(img_h/2),:] y_up = img_filt_up.argmax(axis=0) @@ -234,22 +223,22 @@ class FingerCrop (Preprocessor): # Lower part of filtred image img_filt_lo = img_filt[half_img_h-1:,:] y_lo = img_filt_lo.argmin(axis=0) - + for i in range(0,y_up.size): img_filt[y_up[i]:y_lo[i]+img_filt_lo.shape[0],i]=1 - - finger_mask = numpy.ndarray(image.shape, numpy.bool) + + finger_mask = numpy.ndarray(image.shape, numpy.bool) finger_mask[:,:] = False - + finger_mask[img_filt==1] = True - + # Extract y-position of finger edges edges = numpy.zeros((2,img_w)) edges[0,:] = y_up - edges[1,:] = numpy.round(y_lo + img_filt_lo.shape[0]) - + edges[1,:] = numpy.round(y_lo + img_filt_lo.shape[0]) + return (finger_mask, edges) - + def __huangnormalization__(self, image, mask, edges): @@ -258,77 +247,78 @@ class FingerCrop (Preprocessor): bl = (edges[0,:] + edges[1,:])/2 # Finger base line x = numpy.arange(0,img_w) A = numpy.vstack([x, numpy.ones(len(x))]).T - + # Fit a straight line through the base line points w = numpy.linalg.lstsq(A,bl)[0] # obtaining the parameters - + angle = -1*math.atan(w[0]) # Rotation tr = img_h/2 - w[1] # Translation scale = 1.0 # Scale - - #Affine transformation parameters + + #Affine transformation parameters sx=sy=scale cosine = math.cos(angle) sine = math.sin(angle) - + a = cosine/sx b = -sine/sy #b = sine/sx c = 0 #Translation in x - + d = sine/sx e = cosine/sy f = tr #Translation in y #d = -sine/sy #e = cosine/sy - #f = 0 - - g = 0 - h = 0 - #h=tr - i = 1 - + #f = 0 + + g = 0 + h = 0 + #h=tr + i = 1 + T = numpy.matrix([[a,b,c],[d,e,f],[g,h,i]]) Tinv = numpy.linalg.inv(T) Tinvtuple = (Tinv[0,0],Tinv[0,1], Tinv[0,2], Tinv[1,0],Tinv[1,1],Tinv[1,2]) - + img=Image.fromarray(image) image_norm = img.transform(img.size, Image.AFFINE, Tinvtuple, resample=Image.BICUBIC) #image_norm = img.transform(img.size, Image.AFFINE, (a,b,c,d,e,f,g,h,i), resample=Image.BICUBIC) - image_norm = numpy.array(image_norm) + image_norm = numpy.array(image_norm) finger_mask = numpy.zeros(mask.shape) - finger_mask[mask == True] = 1 + finger_mask[mask == True] = 1 img_mask=Image.fromarray(finger_mask) mask_norm = img_mask.transform(img_mask.size, Image.AFFINE, Tinvtuple, resample=Image.BICUBIC) #mask_norm = img_mask.transform(img_mask.size, Image.AFFINE, (a,b,c,d,e,f,g,h,i), resample=Image.BICUBIC) - mask_norm = numpy.array(mask_norm) + mask_norm = numpy.array(mask_norm) mask[:,:] = False mask[mask_norm==1] = True - + return (image_norm,mask) - + + def __padding_finger__(self, image): - - image_new = bob.core.convert(image,numpy.float64,(0,1),(0,255)) - + + image_new = bob.core.convert(image,numpy.float64,(0,1),(0,255)) + img_h, img_w = image_new.shape - - padding_w = self.padding_threshold * numpy.ones((self.padding_offset, img_w)) - # up and down + + padding_w = self.padding_threshold * numpy.ones((self.padding_offset, img_w)) + # up and down image_new = numpy.concatenate((padding_w,image_new),axis=0) image_new = numpy.concatenate((image_new,padding_w),axis=0) - + img_h, img_w = image_new.shape - padding_h = self.padding_threshold * numpy.ones((img_h,self.padding_offset)) - # left and right + padding_h = self.padding_threshold * numpy.ones((img_h,self.padding_offset)) + # left and right image_new = numpy.concatenate((padding_h,image_new),axis=1) image_new = numpy.concatenate((image_new,padding_h),axis=1) - + return bob.core.convert(image_new,numpy.uint8,(0,255),(0,1)) - + def __CLAHE__(self, image): """ Contrast-limited adaptive histogram equalization (CLAHE). @@ -336,36 +326,38 @@ class FingerCrop (Preprocessor): #TODO return true + def __HE__(self, image): #Umbralization based on the pixels non zero - #import ipdb; ipdb.set_trace() + #import ipdb; ipdb.set_trace() imageEnhance = numpy.zeros(image.shape) imageEnhance = imageEnhance.astype(numpy.uint8) - - bob.ip.base.histogram_equalization(image, imageEnhance) - + + bob.ip.base.histogram_equalization(image, imageEnhance) + return imageEnhance + def __circularGabor__(self, image, bw, sigma): """ CIRCULARGABOR Construct a circular gabor filter Parameters: bw = bandwidth, (1.12 octave) sigma = standard deviation, (5 pixels) """ - #Convert image to doubles - image_new = bob.core.convert(image,numpy.float64,(0,1),(0,255)) + #Convert image to doubles + image_new = bob.core.convert(image,numpy.float64,(0,1),(0,255)) img_h, img_w = image_new.shape - + fc = (1/math.pi * math.sqrt(math.log(2)/2) * (2**bw+1)/(2**bw-1))/sigma sz = numpy.fix(8*numpy.max([sigma,sigma])) - if numpy.mod(sz,2) == 0: + if numpy.mod(sz,2) == 0: sz = sz+1 - + #Construct filter kernel winsize = numpy.fix(sz/2) - + x = numpy.arange(-winsize, winsize+1) y = numpy.arange(winsize, numpy.fix(-sz/2)-1, -1) X, Y = numpy.meshgrid(x, y) @@ -376,15 +368,16 @@ class FingerCrop (Preprocessor): # Without normalisation #gaborfilter = numpy.exp(-0.5*(X**2/sigma**2+Y**2/sigma**2))*numpy.cos(2*math.pi*fc*numpy.sqrt(X**2+Y**2)) - + imageEnhance = utils.imfilter(image, gaborfilter, self.gpu, conv=False) imageEnhance = numpy.abs(imageEnhance) - - #import ipdb; ipdb.set_trace() - imageEnhance = bob.core.convert(imageEnhance,numpy.uint8,(0,255),(imageEnhance.min(),imageEnhance.max())) + + #import ipdb; ipdb.set_trace() + imageEnhance = bob.core.convert(imageEnhance,numpy.uint8,(0,255),(imageEnhance.min(),imageEnhance.max())) return imageEnhance + def __HFE__(self,image): """ High Frequency Enphasis Filtering (HFE) @@ -395,15 +388,15 @@ class FingerCrop (Preprocessor): b = 1.2 n = 2.0 - #import ipdb; ipdb.set_trace() - - #Convert image to doubles - image_new = bob.core.convert(image,numpy.float64,(0,1),(0,255)) + #import ipdb; ipdb.set_trace() + + #Convert image to doubles + image_new = bob.core.convert(image,numpy.float64,(0,1),(0,255)) img_h, img_w = image_new.shape - + # DFT - Ffreq = bob.sp.fftshift(bob.sp.fft(image_new.astype(numpy.complex128))/math.sqrt(img_h*img_w)) - + Ffreq = bob.sp.fftshift(bob.sp.fft(image_new.astype(numpy.complex128))/math.sqrt(img_h*img_w)) + row = numpy.arange(1,img_w+1) x = (numpy.tile(row,(img_h,1)) - (numpy.fix(img_w/2)+1)) /img_w col = numpy.arange(1,img_h+1) @@ -411,111 +404,112 @@ class FingerCrop (Preprocessor): #D is the distance from point (u,v) to the centre of the frequency rectangle. radius = numpy.sqrt(x**2 + y**2) - + f = a + b / (1.0 + (D0 / radius)**(2*n)) Ffreq = Ffreq * f #Inverse DFT imageEnhance = bob.sp.ifft(bob.sp.ifftshift(Ffreq)) #Skip complex part imageEnhance = numpy.abs(imageEnhance) - + #To solve errors - imageEnhance = bob.core.convert(imageEnhance,numpy.uint8,(0,255),(imageEnhance.min(),imageEnhance.max())) - - return imageEnhance - + imageEnhance = bob.core.convert(imageEnhance,numpy.uint8,(0,255),(imageEnhance.min(),imageEnhance.max())) + + return imageEnhance + def __spoofingdetector__(self, image): #Histogram equalization to normalize imageEnhance = numpy.zeros(image.shape) imageEnhance = imageEnhance.astype(numpy.uint8) - - bob.ip.base.histogram_equalization(image, imageEnhance) + + bob.ip.base.histogram_equalization(image, imageEnhance) #Convert image to doubles - image_new = bob.core.convert(imageEnhance,numpy.float64,(0,1),(0,255)) - + image_new = bob.core.convert(imageEnhance,numpy.float64,(0,1),(0,255)) + img_h, img_w = image_new.shape - + # Determine lower half starting point vertically if numpy.mod(img_h,2) == 0: half_img_h = img_h/2 + 1 else: half_img_h = numpy.ceil(img_h/2) - + # Determine lower half starting point horizontally if numpy.mod(img_w,2) == 0: half_img_w = img_w/2 + 1 else: half_img_w = numpy.ceil(img_w/2) - - Ffreq = bob.sp.fftshift(bob.sp.fft(image_new.astype(numpy.complex128))/math.sqrt(img_h*img_w)) + + Ffreq = bob.sp.fftshift(bob.sp.fft(image_new.astype(numpy.complex128))/math.sqrt(img_h*img_w)) F = numpy.log10(abs(Ffreq)**2) - + offset_window = 10 img_half_section_v = F[:,(half_img_w-offset_window):(half_img_w+offset_window)] pv = numpy.mean(img_half_section_v,1) - - dBthreshold = -3 + + dBthreshold = -3 Bwv = numpy.size(numpy.where(pv>dBthreshold))*1.0 / img_h - return Bwv + return Bwv + def crop_finger(self, image): spoofingValue = self.__spoofingdetector__(image) - #import ipdb; ipdb.set_trace() - - #Padding array + #import ipdb; ipdb.set_trace() + + #Padding array image = self.__padding_finger__(image) - - ## Fingervein image enhancement: + + ## Fingervein image enhancement: if self.preprocessing != None: if self.preprocessing == 'CLAHE': - image_eq = self.__CLAHE__(image) + image_eq = self.__CLAHE__(image) elif self.preprocessing == 'HE': - image_eq = self.__HE__(image) + image_eq = self.__HE__(image) elif self.preprocessing == 'HFE': - image_eq = self.__HFE__(image) + image_eq = self.__HFE__(image) elif self.preprocessing == 'CircGabor': - image_eq = self.__circularGabor__(image, 1.12, 5) - else: image_eq = image - - ## Finger edges and contour extraction: + image_eq = self.__circularGabor__(image, 1.12, 5) + else: image_eq = image + + ## Finger edges and contour extraction: if self.fingercontour == 'leemaskMatlab': finger_mask, finger_edges = self.__leemaskMatlab__(image_eq) #Function for UTFVP - elif self.fingercontour == 'leemaskMod': + elif self.fingercontour == 'leemaskMod': finger_mask, finger_edges = self.__leemaskMod__(image_eq) #Function for VERA - elif self.fingercontour == 'konomask': - finger_mask, finger_edges = self.__konomask__(image_eq, sigma=5) - + elif self.fingercontour == 'konomask': + finger_mask, finger_edges = self.__konomask__(image_eq, sigma=5) + ## Finger region normalization: - image_norm,finger_mask_norm = self.__huangnormalization__(image_eq, finger_mask, finger_edges) + image_norm,finger_mask_norm = self.__huangnormalization__(image_eq, finger_mask, finger_edges) - ## veins enhancement: + ## veins enhancement: if self.postprocessing != None: if self.postprocessing == 'CLAHE': - image_norm = self.__CLAHE__(image_norm) + image_norm = self.__CLAHE__(image_norm) elif self.postprocessing == 'HE': - image_norm = self.__HE__(image_norm) + image_norm = self.__HE__(image_norm) elif self.postprocessing == 'HFE': - image_norm = self.__HFE__(image_norm) + image_norm = self.__HFE__(image_norm) elif self.postprocessing == 'CircGabor': - image_norm = self.__circularGabor__(image_norm, 1.12, 5) - - - #To check the mask: - finger_mask2 = bob.core.convert(finger_mask,numpy.uint8,(0,255),(0,1)) - - return (image_norm, finger_mask_norm, finger_mask2, spoofingValue) + image_norm = self.__circularGabor__(image_norm, 1.12, 5) + + + #To check the mask: + finger_mask2 = bob.core.convert(finger_mask,numpy.uint8,(0,255),(0,1)) + return (image_norm, finger_mask_norm, finger_mask2, spoofingValue) def __call__(self, image, annotations=None): """Reads the input image, extract the Lee mask of the fingervein, and writes the resulting image""" return self.crop_finger(image) + def save_data(self, image, image_file): f = bob.io.base.HDF5File(image_file, 'w') f.set('image', image[0]) @@ -523,8 +517,9 @@ class FingerCrop (Preprocessor): f.set('mask', image[2]) f.set('spoofingValue', image[3]) + def read_data(self, image_file): f = bob.io.base.HDF5File(image_file, 'r') image = f.read('image') - finger_mask = f.read('finger_mask') - return (image, finger_mask) \ No newline at end of file + finger_mask = f.read('finger_mask') + return (image, finger_mask) diff --git a/bob/bio/vein/preprocessors/__init__.py b/bob/bio/vein/preprocessors/__init__.py index edd706250a94135d346f62b917daf1b5535af108..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/bob/bio/vein/preprocessors/__init__.py +++ b/bob/bio/vein/preprocessors/__init__.py @@ -1,7 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> - -"""Image preprocessing tools""" -from FingerCrop import FingerCrop - diff --git a/bob/bio/vein/script/__init__.py b/bob/bio/vein/script/__init__.py deleted file mode 100644 index d86e6227315f9e26446834c3ef52a32b6e8b0a97..0000000000000000000000000000000000000000 --- a/bob/bio/vein/script/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <pedro.tome@idiap.ch> - -"""Scripts to run face verification experiments""" - -import fingerveinverify -import scores2spoofingfile -#import scoresanalysis -#import scoresfusion -#import plot_scatter_fusion diff --git a/bob/bio/vein/script/fingerveinverify.py b/bob/bio/vein/script/fingerveinverify.py deleted file mode 100644 index 21248e43c6caf4d1c4a4cbc2602480c4990006a6..0000000000000000000000000000000000000000 --- a/bob/bio/vein/script/fingerveinverify.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> - -import sys, os -import argparse - -from facereclib.script.faceverify import parse_args, face_verify -from facereclib import utils - -def main(command_line_parameters = sys.argv): - """Executes the main function""" - try: - # do the command line parsing - args = parse_args(command_line_parameters[1:], exclude_resources_from=['facereclib']) - - # perform face verification test - face_verify(args, command_line_parameters) - except Exception as e: - # track any exceptions as error logs (i.e., to get a time stamp) - utils.error("During the execution, an exception was raised: %s" % e) - raise - -if __name__ == "__main__": - main() diff --git a/bob/bio/vein/script/scores2spoofingfile.py b/bob/bio/vein/script/scores2spoofingfile.py deleted file mode 100644 index 3ae48615fa96c4258da621af6920267f8ba9ded8..0000000000000000000000000000000000000000 --- a/bob/bio/vein/script/scores2spoofingfile.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# Pedro Tome <Pedro.Tome@idiap.ch> -# -# Copyright (C) 2014-2015 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/>. - -"""This script generate the spoofing score for genuine scores of -the experiment to compute the SFAR rate.""" - -import sys -import argparse -import numpy, math -import os -from facereclib import utils - -def command_line_arguments(command_line_parameters): - """Parse the program options""" - - # set up command line parser - parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter) - - parser.add_argument('-d', '--dev-file', required=True, help = "The score file of the Normal Operation Mode (NOM: real vs real images) of the system.") - parser.add_argument('-s', '--spoofing-file', required=True, help = "The score file of the Spoofing Attack (SpoofingAttack: real vs spoofing images) of the system.") - parser.add_argument('-o', '--output-file', required=False, help = "(Optional) The filename of the genuine spoofing score distribution to compute the SFAR, by default is save as --spoofing-file+_spoof.") - - utils.add_logger_command_line_option(parser) - - # parse arguments - args = parser.parse_args(command_line_parameters) - - #import ipdb; ipdb.set_trace() - - utils.set_verbosity_level(args.verbose) - - # some sanity checks: - #if len(args.dev_file) != len(args.spoofing_file): - # utils.error("The number of --dev-file (%d) and --spoofing-file (%d) are not identical!" % (len(args.dev_file), len(args.spoofing_file))) - - return args - - -def main(command_line_parameters=None): - """Reads score files, computes the score file from spoofing genuine distribution.""" - - args = command_line_arguments(command_line_parameters) - - #print 'Number of arguments:', len(sys.argv), 'arguments.' - #print 'Argument List:', str(sys.argv) - - scoresFileNOM = args.dev_file - scoresFileSpoof = args.spoofing_file - scoresFileOut = args.output_file - if scoresFileOut == None: - scoresFileOut = scoresFileSpoof + '_spoof' - - #For debugging - #import ipdb; ipdb.set_trace() - - with open(scoresFileSpoof, 'r') as fin, open(scoresFileOut, 'w') as fout: - while True: - tline = fin.readline() - if not tline: - break - token1 = tline.find(' ') - model = tline[0:token1] - token2 = tline.find(' ',token1+1) - mreal = tline[token1+1:token2] - token3 = tline.find(' ',token2+1) - filemodel = tline[token2+1:token3] - score = tline[token3+1:] - - if ( model.find(mreal) == 0 ): - newline = model + ' attack ' + tline[token2+1:] - fout.write(newline) - - with open(scoresFileNOM, 'r') as fin, open(scoresFileOut, 'a') as fout: - while True: - tline = fin.readline() - if not tline: - break - token1 = tline.find(' ') - model = tline[0:token1] - token2 = tline.find(' ',token1+1) - mreal = tline[token1+1:token2] - token3 = tline.find(' ',token2+1) - filemodel = tline[token2+1:token3] - score = tline[token3+1:] - - if ( model.find(mreal) == 0 ): - fout.write(tline) - - diff --git a/bob/bio/vein/tests/__init__.py b/bob/bio/vein/tests/__init__.py index 680fe8cbc89a98be35b0caa767adef94ccc50a0c..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/bob/bio/vein/tests/__init__.py +++ b/bob/bio/vein/tests/__init__.py @@ -1,6 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : - -"""Tool chain for computing verification test""" - - diff --git a/bob/bio/vein/tests/test.py b/bob/bio/vein/tests/test.py index 495dd821a3618a26cab43bedd90f31025b2fe410..9622ee8e08d6349a39ad59ef23fd344e26fb4de3 100644 --- a/bob/bio/vein/tests/test.py +++ b/bob/bio/vein/tests/test.py @@ -1,179 +1,151 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <pedro.tome@idiap.ch> -# -# Copyright (C) 2014-2015 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/>. """Test Units """ -import unittest -import bob.io.base -import bob.io.matlab import os +import numpy +import nose.tools + import pkg_resources -def F_pre(name, f): - """Returns the test file on the "data" subdirectory""" - return pkg_resources.resource_filename(name, os.path.join('preprocessing', f)) - -def F_feat(name, f): - """Returns the test file on the "data" subdirectory""" - return pkg_resources.resource_filename(name, os.path.join('features', f)) - -def F_mat(name, f): - """Returns the test file on the "data" subdirectory""" - return pkg_resources.resource_filename(name, os.path.join('matching', f)) - - -class FingerveinTests(unittest.TestCase): - - def test_finger_crop(self): - """Test finger vein image preprocessing""" - import numpy - input_filename = F_pre(__name__, '0019_3_1_120509-160517.png') - output_img_filename = F_pre(__name__, '0019_3_1_120509-160517_img_lee_huang.mat') - output_fvr_filename = F_pre(__name__, '0019_3_1_120509-160517_fvr_lee_huang.mat') - - img = bob.io.base.load(input_filename) - - from bob.fingervein.preprocessing.FingerCrop import FingerCrop - FC = FingerCrop(4, 40, False, False) - #FC = FingerCrop(4, 40, False, 5, 0.2, False) - - output_img, finger_mask_norm, finger_mask2, spoofingValue = FC(img) - - # Load Matlab reference - output_img_ref = bob.io.base.load(output_img_filename) - output_fvr_ref = bob.io.base.load(output_fvr_filename) - - # Compare output of python's implementation to matlab reference - # (loose comparison!) - #For debugging - #import ipdb; ipdb.set_trace() - - self.assertTrue(numpy.mean(numpy.abs(output_img - output_img_ref)) < 1e2) - - - def test_miuramax(self): - """Test feature extraction: Maximum Curvature method against Matlab reference""" - - import numpy - input_img_filename = F_feat(__name__, 'miuramax_input_img.mat') - input_fvr_filename = F_feat(__name__, 'miuramax_input_fvr.mat') - output_filename = F_feat(__name__, 'miuramax_output.mat') - - # Load inputs - input_img = bob.io.base.load(input_img_filename) - input_fvr = bob.io.base.load(input_fvr_filename) - - # Apply Python implementation - from bob.fingervein.features.MaximumCurvature import MaximumCurvature - MC = MaximumCurvature(5, False) - output_img = MC((input_img, input_fvr)) - - # Load Matlab reference - output_img_ref = bob.io.base.load(output_filename) - - # Compare output of python's implementation to matlab reference - # (loose comparison!) - self.assertTrue(numpy.mean(numpy.abs(output_img - output_img_ref)) < 8e-3) - - - def test_miurarlt(self): - """Test feature extraction: Repeated Line Tracking method against Matlab reference""" - - import numpy - input_img_filename = F_feat(__name__, 'miurarlt_input_img.mat') - input_fvr_filename = F_feat(__name__, 'miurarlt_input_fvr.mat') - output_filename = F_feat(__name__, 'miurarlt_output.mat') - - # Load inputs - input_img = bob.io.base.load(input_img_filename) - input_fvr = bob.io.base.load(input_fvr_filename) - - # Apply Python implementation - from bob.fingervein.features.RepeatedLineTracking import RepeatedLineTracking - RLT = RepeatedLineTracking(3000, 1, 21, False) - output_img = RLT((input_img, input_fvr)) - - # Load Matlab reference - output_img_ref = bob.io.base.load(output_filename) - - # Compare output of python's implementation to matlab reference - # (loose comparison!) - self.assertTrue(numpy.mean(numpy.abs(output_img - output_img_ref)) < 0.5) - - - def test_huangwl(self): - """Test feature extraction: Wide Line Detector method against Matlab reference""" - - import numpy - input_img_filename = F_feat(__name__, 'huangwl_input_img.mat') - input_fvr_filename = F_feat(__name__, 'huangwl_input_fvr.mat') - output_filename = F_feat(__name__, 'huangwl_output.mat') - - # Load inputs - input_img = bob.io.base.load(input_img_filename) - input_fvr = bob.io.base.load(input_fvr_filename) - - # Apply Python implementation - from bob.fingervein.features.WideLineDetector import WideLineDetector - WL = WideLineDetector(5, 1, 41, False) - output_img = WL((input_img, input_fvr)) - - # Load Matlab reference - output_img_ref = bob.io.base.load(output_filename) - - #For debugging - #import ipdb; ipdb.set_trace() - #from PIL import Image - #Image.fromarray(bob.core.convert(output_img,numpy.uint8,(0,255),(0,1))).show() - #Image.fromarray(bob.core.convert(output_img_ref,numpy.uint8,(0,255),(0,1))).show() - - # Compare output of python's implementation to matlab reference - self.assertTrue(numpy.allclose(output_img, output_img_ref)) - - - def test_miura_match(self): - """Test matching: Match Ratio method against Matlab reference""" - - template_filename = F_mat(__name__, '0001_2_1_120509-135338.mat') - probe_gen_filename = F_mat(__name__, '0001_2_2_120509-135558.mat') - probe_imp_filename = F_mat(__name__, '0003_2_1_120509-141255.mat') - - template_vein = bob.io.base.load(template_filename) - probe_gen_vein = bob.io.base.load(probe_gen_filename) - probe_imp_vein = bob.io.base.load(probe_imp_filename) - - from bob.fingervein.tools.MiuraMatch import MiuraMatch - MM = MiuraMatch(ch=18, cw=28) - score_gen = MM.score(template_vein, probe_gen_vein) - self.assertAlmostEqual(score_gen, 0.382689335394127) - - #import ipdb; ipdb.set_trace() +import bob.io.base +import bob.io.matlab - score_imp = MM.score(template_vein, probe_imp_vein) - self.assertAlmostEqual(score_imp, 0.172906739278421) - if False: - MM = MiuraMatch(ch=18, cw=28, gpu=True) - score_gen = MM.score(template_vein, probe_gen_vein) - self.assertAlmostEqual(score_gen, 0.382689335394127) +def F(parts): + """Returns the test file path""" + + return pkg_resources.resource_filename(__name__, os.path.join(*parts)) + + +def test_finger_crop(): + + #Test finger vein image preprocessing + + input_filename = F(('preprocessing', '0019_3_1_120509-160517.png')) + output_img_filename = F(('preprocessing', + '0019_3_1_120509-160517_img_lee_huang.mat')) + output_fvr_filename = F(('preprocessing', + '0019_3_1_120509-160517_fvr_lee_huang.mat')) + + img = bob.io.base.load(input_filename) + + from bob.fingervein.preprocessing.FingerCrop import FingerCrop + FC = FingerCrop(4, 40, False, False) + #FC = FingerCrop(4, 40, False, 5, 0.2, False) + + output_img, finger_mask_norm, finger_mask2, spoofingValue = FC(img) + + # Load Matlab reference + output_img_ref = bob.io.base.load(output_img_filename) + output_fvr_ref = bob.io.base.load(output_fvr_filename) + + # Compare output of python's implementation to matlab reference + # (loose comparison!) + assert numpy.mean(numpy.abs(output_img - output_img_ref)) < 1e2 + + +def test_miuramax(): + + #Maximum Curvature method against Matlab reference + + input_img_filename = F(('features', 'miuramax_input_img.mat')) + input_fvr_filename = F(('features', 'miuramax_input_fvr.mat')) + output_filename = F(('features', 'miuramax_output.mat')) + + # Load inputs + input_img = bob.io.base.load(input_img_filename) + input_fvr = bob.io.base.load(input_fvr_filename) + + # Apply Python implementation + from bob.fingervein.features.MaximumCurvature import MaximumCurvature + MC = MaximumCurvature(5, False) + output_img = MC((input_img, input_fvr)) + + # Load Matlab reference + output_img_ref = bob.io.base.load(output_filename) + + # Compare output of python's implementation to matlab reference + # (loose comparison!) + assert numpy.mean(numpy.abs(output_img - output_img_ref)) < 8e-3 - score_imp = MM.score(template_vein, probe_imp_vein) - self.assertAlmostEqual(score_imp, 0.172906739278421) +def test_miurarlt(): + + #Repeated Line Tracking method against Matlab reference + + input_img_filename = F(('features', 'miurarlt_input_img.mat')) + input_fvr_filename = F(('features', 'miurarlt_input_fvr.mat')) + output_filename = F(('features', 'miurarlt_output.mat')) + + # Load inputs + input_img = bob.io.base.load(input_img_filename) + input_fvr = bob.io.base.load(input_fvr_filename) + + # Apply Python implementation + from bob.fingervein.features.RepeatedLineTracking import RepeatedLineTracking + RLT = RepeatedLineTracking(3000, 1, 21, False) + output_img = RLT((input_img, input_fvr)) + + # Load Matlab reference + output_img_ref = bob.io.base.load(output_filename) + + # Compare output of python's implementation to matlab reference + # (loose comparison!) + assert numpy.mean(numpy.abs(output_img - output_img_ref)) < 0.5 + + +def test_huangwl(): + + #Wide Line Detector method against Matlab reference + + input_img_filename = F(('features', 'huangwl_input_img.mat')) + input_fvr_filename = F(('features', 'huangwl_input_fvr.mat')) + output_filename = F(('features', 'huangwl_output.mat')) + + # Load inputs + input_img = bob.io.base.load(input_img_filename) + input_fvr = bob.io.base.load(input_fvr_filename) + + # Apply Python implementation + from bob.fingervein.features.WideLineDetector import WideLineDetector + WL = WideLineDetector(5, 1, 41, False) + output_img = WL((input_img, input_fvr)) + + # Load Matlab reference + output_img_ref = bob.io.base.load(output_filename) + + # Compare output of python's implementation to matlab reference + assert numpy.allclose(output_img, output_img_ref) + + +def test_miura_match(): + """Test matching: Match Ratio method against Matlab reference""" + + template_filename = F(('matching', '0001_2_1_120509-135338.mat')) + probe_gen_filename = F(('matching', '0001_2_2_120509-135558.mat')) + probe_imp_filename = F(('matching', '0003_2_1_120509-141255.mat')) + + template_vein = bob.io.base.load(template_filename) + probe_gen_vein = bob.io.base.load(probe_gen_filename) + probe_imp_vein = bob.io.base.load(probe_imp_filename) + + from bob.fingervein.tools.MiuraMatch import MiuraMatch + MM = MiuraMatch(ch=18, cw=28) + score_gen = MM.score(template_vein, probe_gen_vein) + + assert numpy.isclose(score_gen, 0.382689335394127) + + score_imp = MM.score(template_vein, probe_imp_vein) + assert numpy.isclose(score_imp, 0.172906739278421) + + if False: #testing gpu enabled calculations + MM = MiuraMatch(ch=18, cw=28, gpu=True) + score_gen = MM.score(template_vein, probe_gen_vein) + assert numpy.isclose(score_gen, 0.382689335394127) + + score_imp = MM.score(template_vein, probe_imp_vein) + assert numpy.isclose(score_imp, 0.172906739278421) diff --git a/buildout.cfg b/buildout.cfg index d41c69873fb1e4301f8a3f9a272ad03d05be099b..7361c96ab1251e2e121b1c729b5b2d2a31c273cc 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -1,19 +1,13 @@ ; vim: set fileencoding=utf-8 : -; Andre Anjos <andre.anjos@idiap.ch> -; Fri 08 Jul 2016 16:02:37 CEST [buildout] parts = scripts extensions = bob.buildout eggs = bob.bio.vein - bob.db.vera - bob.db.utfvp + bob.db.base + bob.extension gridtk - -debug = true -verbose = true newest = false [scripts] recipe = bob.buildout:scripts -dependent-scripts = true diff --git a/doc/conf.py b/doc/conf.py index 32a5980ec8b892b5ac9f42ccf1b4a2175a6b09fb..1fcb4b6802205ddf94e30d2376770226d0e9f90b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,9 +1,5 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <pedro.tome@idiap.ch> -# Wed Jan 14 11:58:57 CEST 2015 -# -# Copyright (C) 2011-2014 Idiap Research Institute, Martigny, Switzerland import os import sys diff --git a/doc/contribute.rst b/doc/contribute.rst index 9daba4f79cf4aebe6409a591fd9ede166bcc3b05..b9b2850e683ffd5da1dc49bf7ad9d7ee04695e83 100644 --- a/doc/contribute.rst +++ b/doc/contribute.rst @@ -1,151 +1,228 @@ .. vim: set fileencoding=utf-8 : -.. author: Pedro Tome <pedro.tome@idiap.ch> .. date: Wed Jan 14 11:58:57 CEST 2015 -========================================================================================= -Implementing your own Database, Preprocessor, Feature Extractor, or Recognition Algorithm -========================================================================================= +=========================================================================================== + Implementing your own Database, Preprocessor, Feature Extractor, or Recognition Algorithm +=========================================================================================== -The FingerveinRecLib module is specifically designed to be as flexible as possible while trying to keep things simple. -Therefore, it uses python to implement algorithms. -It is file based so any algorithm can implement its own way of reading and writing data, features or models. -Algorithm configurations are stored in configuration files, so it should be easy to test different parameters of your algorithms without modifying the code. +The FingerveinRecLib module is specifically designed to be as flexible as +possible while trying to keep things simple. Therefore, it uses python to +implement algorithms. It is file based so any algorithm can implement its own +way of reading and writing data, features or models. Algorithm configurations +are stored in configuration files, so it should be easy to test different +parameters of your algorithms without modifying the code. -To implement your own database, preprocessor, feature, or algorithm, simply follow the examples that are already in the FingerveinRecLib. -In the following sections there will be an overview of the functions that need to be implemented. +To implement your own database, preprocessor, feature, or algorithm, simply +follow the examples that are already in the FingerveinRecLib. In the following +sections there will be an overview of the functions that need to be +implemented. -The FingerveinRecLib is designed in a way that useful default functionalities are executed. -If you want/need to have a different behavior, you can simply add functions to your classes and register these functions, for details please see below. +The FingerveinRecLib is designed in a way that useful default functionalities +are executed. If you want/need to have a different behavior, you can simply +add functions to your classes and register these functions, for details please +see below. Implementing your own Functions ------------------------------- -There are two options to add functionality to the FingerveinRecLib. -The preferred option should be to write a satellite package of the FingerveinRecLib, implement everything you want to do, test it and document it. +There are two options to add functionality to the FingerveinRecLib. The +preferred option should be to write a satellite package of the +FingerveinRecLib, implement everything you want to do, test it and document it. Please read the :ref:`satellite-packages` section for more details on this. -Here, we describe the second way, which is to add functionality to FingerveinRecLib directly. +Here, we describe the second way, which is to add functionality to +FingerveinRecLib directly. + Base Classes ~~~~~~~~~~~~ -In general, any database, preprocessor, feature extractor or recognition algorithm should be derived from a base class that is detailed below. -This base class provides default implementations of functionality that can be used directly or overwritten in your class. -One of these functions, which is identical to all base classes, is the ``__str__(self)`` function, a special Python construct to convert an object of a class into a string that contains information about the object. -In the FingerveinRecLib, this function is used to write the experimental configuration into a specific text file (by default: **Experiment.info** in the ``--result-directory``). -This information is useful to see the exact configuration of the experiment with which the results was generated. + +In general, any database, preprocessor, feature extractor or recognition +algorithm should be derived from a base class that is detailed below. This +base class provides default implementations of functionality that can be used +directly or overwritten in your class. One of these functions, which is +identical to all base classes, is the ``__str__(self)`` function, a special +Python construct to convert an object of a class into a string that contains +information about the object. In the FingerveinRecLib, this function is used +to write the experimental configuration into a specific text file (by default: +**Experiment.info** in the ``--result-directory``). This information is useful +to see the exact configuration of the experiment with which the results was +generated. There are two ways of providing these information for your class: -1. Call the base class constructor and specify all parameters that should be added to the information file. -2. Overwrite the ``__str__(self)`` function in your class, following the example of the base class. +1. Call the base class constructor and specify all parameters that should be + added to the information file. +2. Overwrite the ``__str__(self)`` function in your class, following the + example of the base class. + .. _filelist: Image Databases ~~~~~~~~~~~~~~~ -If you have your own database that you want to execute the recognition experiments on, you should first check if you could use the :ref:`Verifcation FileList Database <bob.db.verification.filelist>` interface by defining appropriate file lists for the training set, the model set, and the probes. -For more details, please check the documentation of `FaceRecLib <http://pythonhosted.org/facereclib/contribute.html>`_. +If you have your own database that you want to execute the recognition +experiments on, you should first check if you could use the :ref:`Verifcation +FileList Database <bob.db.verification.filelist>` interface by defining +appropriate file lists for the training set, the model set, and the probes. + +For more details, please check the documentation of `FaceRecLib +<http://pythonhosted.org/facereclib/contribute.html>`_. Data Preprocessors ~~~~~~~~~~~~~~~~~~ -All preprocessing classes should be derived from the :py:class:`FingerveinRecLib.preprocessing.Preprocessor` class. -If your class returns data that is **not** of type :py:class:`numpy.ndarray`, you might need to overwrite further functions from :py:class:`FingerveinRecLib.preprocessing.Preprocessor` that define the IO of your class: +All preprocessing classes should be derived from the +:py:class:`FingerveinRecLib.preprocessing.Preprocessor` class. + +If your class returns data that is **not** of type :py:class:`numpy.ndarray`, +you might need to overwrite further functions from +:py:class:`FingerveinRecLib.preprocessing.Preprocessor` that define the IO of +your class: -* ``save_data(data, filename)``: Writes the given data (that has been generated using the ``__call__`` function of this class) to file. +* ``save_data(data, filename)``: Writes the given data (that has been generated + using the ``__call__`` function of this class) to file. * ``read_data(filename)``: Reads the preprocessed data from file. -By default, the original data is read by :py:func:`bob.io.base.load`. -Hence, data is given as :py:class:`numpy.ndarray`\s. -If you want to use a different IO for the original data (rarely useful...), you might want to overload: +By default, the original data is read by :py:func:`bob.io.base.load`. Hence, +data is given as :py:class:`numpy.ndarray`\s. If you want to use a different +IO for the original data (rarely useful...), you might want to overload: * ``read_original_data(filename)``: Reads the original data from file. -If you plan to use a simple finger cropping for fingervein image processing, you might want to derive your class from the :py:class:`FingerveinRecLib.preprocessing.FingerCrop` class (you don't need to derive from :py:class:`FingerveinRecLib.preprocessing.Preprocessor ` in this case). -In this case, just add a ``**kwargs`` parameter to your constructor, call the fingervein crop constructor with these parameters: ``FingerveinRecLib.preprocessing.FingerCrop.__init__(self, **kwargs)``, and call the ``self.finger_crop(image)`` in your ``__call__`` function. -For an example of this behavior, you might have a look into the `FingerveinRecLib.preprocessing.finger_crop_None_HE <file:../FingerveinRecLib/preprocessing/finger_crop_None_HE.py>`_ class. +If you plan to use a simple finger cropping for fingervein image processing, +you might want to derive your class from the +:py:class:`FingerveinRecLib.preprocessing.FingerCrop` class (you don't need to +derive from :py:class:`FingerveinRecLib.preprocessing.Preprocessor ` in this +case). In this case, just add a ``**kwargs`` parameter to your constructor, +call the fingervein crop constructor with these parameters: +``FingerveinRecLib.preprocessing.FingerCrop.__init__(self, **kwargs)``, and +call the ``self.finger_crop(image)`` in your ``__call__`` function. For an +example of this behavior, you might have a look into the +`FingerveinRecLib.preprocessing.finger_crop_None_HE +<file:../FingerveinRecLib/preprocessing/finger_crop_None_HE.py>`_ class. Feature Extractors ~~~~~~~~~~~~~~~~~~ -Feature extractors should be derived from the :py:class:`FingerveinRecLib.features.Extractor` class. -Your extractor class has to provide at least the functions: -* ``__init__(self, <parameters>)``: Initializes the feature extraction algorithm with the parameters it needs. - Please call the base class constructor in this constructor, e.g. as ``FingerveinRecLib.features.Extractor.__init__(self, ...)`` (there are more parameters to this constructor, see below). -* ``__call__(self, data) -> feature``: Extracts the feature from the given preprocessed data. - By default, the returned feature should be a :py:class:`numpy.ndarray`. +Feature extractors should be derived from the +:py:class:`FingerveinRecLib.features.Extractor` class. Your extractor class +has to provide at least the functions: -If your features are not of type :py:class:`numpy.ndarray`, please overwrite the ``save_feature`` function to write features of other types. -Please also overwrite the function to read your kind of features: +* ``__init__(self, <parameters>)``: Initializes the feature extraction + algorithm with the parameters it needs. Please call the base class + constructor in this constructor, e.g. as + ``FingerveinRecLib.features.Extractor.__init__(self, ...)`` (there are more + parameters to this constructor, see below). +* ``__call__(self, data) -> feature``: Extracts the feature from the given + preprocessed data. By default, the returned feature should be a + :py:class:`numpy.ndarray`. + +If your features are not of type :py:class:`numpy.ndarray`, please overwrite +the ``save_feature`` function to write features of other types. Please also +overwrite the function to read your kind of features: * ``save_feature(self, feature, feature_file)``: Saves the feature (as returned by the ``__call__`` function) to the given file name. * ``read_feature(self, feature_file) -> feature``: Reads the feature (as written by the ``save_feature`` function) from the given file name. .. note:: - If your feature is of a class that contains and is written via a ``save(bob.io.base.HDF5File)`` method, you do not need to define a ``save_feature`` function. - However, the ``read_feature`` function is required in this case. -If the feature extraction process requires to read a trained extractor model from file, simply overload the function: + If your feature is of a class that contains and is written via a + ``save(bob.io.base.HDF5File)`` method, you do not need to define a + ``save_feature`` function. However, the ``read_feature`` function is + required in this case. + +If the feature extraction process requires to read a trained extractor model +from file, simply overload the function: -* ``load(self, extractor_file)``: Loads the extractor from file. - This function is called at least once before the ``__call__`` function is executed. +* ``load(self, extractor_file)``: Loads the extractor from file. This function + is called at least once before the ``__call__`` function is executed. Recognition Algorithms ~~~~~~~~~~~~~~~~~~~~~~ -Implementing your recognition algorithm should be as straightforward. -Simply derive your class from the :py:class:`FingerveinRecLib.tools.Tool` class. - .. note:: - When you use a distance measure in your scoring function, and lower distances represents higher probabilities of having the same identity, please return the negative distance. +Implementing your recognition algorithm should be as straightforward. Simply +derive your class from the :py:class:`FingerveinRecLib.tools.Tool` class. -And once more, if the projected feature is not of type ``numpy.ndarray``, overwrite the methods: +.. note:: -* ``save_feature(feature, feature_file)``: Writes the feature (as returned by the ``project`` function) to file. -* ``read_feature(feature_file) -> feature``: Reads and returns the feature (as written by the ``write_feature`` function). + When you use a distance measure in your scoring function, and lower + distances represents higher probabilities of having the same identity, + please return the negative distance. -By default, it is assumed that both the models and the probe features are of type :py:class:`numpy.ndarray`. -If your ``score`` function expects models and probe features to be of a different type, you should overwrite the functions: +And once more, if the projected feature is not of type ``numpy.ndarray``, +overwrite the methods: -* ``save_model(self, model, model_file)``: writes the model (as returned by the ``enroll`` function) -* ``read_model(self, model_file) -> model``: reads the model (as written by the ``write_model`` function) from file. -* ``read_probe(self, probe_file) -> feature``: reads the probe feature from file. +* ``save_feature(feature, feature_file)``: Writes the feature (as returned by + the ``project`` function) to file. +* ``read_feature(feature_file) -> feature``: Reads and returns the feature (as + written by the ``write_feature`` function). - .. note:: - In many cases, the ``read_feature`` and ``read_probe`` functions are identical (if both are present). +By default, it is assumed that both the models and the probe features are of +type :py:class:`numpy.ndarray`. If your ``score`` function expects models and +probe features to be of a different type, you should overwrite the functions: -Finally, the :py:class:`FingerveinRecLib.tools.Tool` class provides default implementations for the case that models store several features, or that several probe features should be combined into one score. +* ``save_model(self, model, model_file)``: writes the model (as returned by the + ``enroll`` function) +* ``read_model(self, model_file) -> model``: reads the model (as written by the + ``write_model`` function) from file. +* ``read_probe(self, probe_file) -> feature``: reads the probe feature from + file. + +.. note:: + + In many cases, the ``read_feature`` and ``read_probe`` functions are + identical (if both are present). + + +Finally, the :py:class:`FingerveinRecLib.tools.Tool` class provides default +implementations for the case that models store several features, or that +several probe features should be combined into one score. Executing experiments with your classes --------------------------------------- -Finally, executing experiments using your database, preprocessor, feature extraction, and/or recognition tool should be as easy as using the tools that are already available. -Nonetheless, it might be a good idea to first run the experiments locally (i.e., calling the ``bin/fingerveinverify.py -vvv`` without the ``--grid`` option) to see if your functions do work and do provide expected results. + +Finally, executing experiments using your database, preprocessor, feature +extraction, and/or recognition tool should be as easy as using the tools that +are already available. Nonetheless, it might be a good idea to first run the +experiments locally (i.e., calling the ``bin/fingerveinverify.py -vvv`` without +the ``--grid`` option) to see if your functions do work and do provide expected +results. Adding Unit Tests ----------------- -To make sure that your piece of code it working properly, you should add a test case for your class. -The FingerveinRecLib, as well as Bob_, rely on `nose tests <http://pypi.python.org/pypi/nose>`_ to run the unit tests. -To implement a unit test for your contribution, you simply can create a python file with a name containing 'test' in your package. -In the FingerveinRecLib, these files are located in `FingerveinRecLib/tests <file:../FingerveinRecLib/tests>`_. -In the test file, please write a test class that derives from ``unittest.TestCase``. -Any function name containing the string ``test`` will be automatically found and executed when running ``bin/nosetests``. -In your test function, please assure that all aspects of your contribution are thoroughly tested and that all test cases pass. -Also remember that your tests need to run on different machines with various operating systems, so don't test floating point values for equality. +To make sure that your piece of code it working properly, you should add a test +case for your class. The FingerveinRecLib, as well as Bob_, rely on `nose +tests <http://pypi.python.org/pypi/nose>`_ to run the unit tests. To implement +a unit test for your contribution, you simply can create a python file with a +name containing 'test' in your package. In the FingerveinRecLib, these files +are located in `FingerveinRecLib/tests <file:../FingerveinRecLib/tests>`_. + +In the test file, please write a test class that derives from +``unittest.TestCase``. Any function name containing the string ``test`` will +be automatically found and executed when running ``bin/nosetests``. In your +test function, please assure that all aspects of your contribution are +thoroughly tested and that all test cases pass. Also remember that your tests +need to run on different machines with various operating systems, so don't test +floating point values for equality. .. _configuration-files: Adding Configuration Files -------------------------- -After your code is tested, you should provide a configuration file for your algorithm. -A configuration file basically consists of a constructor call to your new class with a useful (yet not necessarily optimized) set of parameters. + +After your code is tested, you should provide a configuration file for your +algorithm. A configuration file basically consists of a constructor call to +your new class with a useful (yet not necessarily optimized) set of parameters. Depending on your type of contribution, you should write a line like: * ``database = FingerveinRecLib.databases.<YourDatabase>(<YourParameters>)`` @@ -153,15 +230,19 @@ Depending on your type of contribution, you should write a line like: * ``feature_extractor = FingerveinRecLib.features.<YourExtractor>(<YourParameters>)`` * ``tool = FingerveinRecLib.tools.<YourAlgorithm>(<YourParameters>)`` -and save the configuration file into the according sub-directory of `FingerveinRecLib/configurations <file:../FingerveinRecLib/configurations>`_. +and save the configuration file into the according sub-directory of +`FingerveinRecLib/configurations <file:../FingerveinRecLib/configurations>`_. .. _register-resources: Registering your Code as a Resource ----------------------------------- -Now, you should be able to register this configuration file as a resource, so that you can use the configuration from above by a simple ``<shortcut>`` of your choice. -Please open the `setup.py <file:../setup.py>`_ file in the base directory of your satellite package and edit the ``entry_points`` section. + +Now, you should be able to register this configuration file as a resource, so +that you can use the configuration from above by a simple ``<shortcut>`` of +your choice. Please open the `setup.py <file:../setup.py>`_ file in the base +directory of your satellite package and edit the ``entry_points`` section. Depending on your type of algorithm, you have to add: * ``'FingerveinRecLib.database': [ '<your-database-shortcut> = <your-database-configuration>.database' ]`` @@ -169,7 +250,8 @@ Depending on your type of algorithm, you have to add: * ``'FingerveinRecLib.feature_extractor': [ '<your-extractor-shortcut> = <your-extractor-configuration>.feature_extractor' ]`` * ``'FingerveinRecLib.tool': [ '<your-recognition-algorithm-shortcut> = <your-algorithm-configuration>.tool' ]`` -After re-running ``bin/buildout``, your new resource should be listed in the output of ``bin/resources.py``. +After re-running ``bin/buildout``, your new resource should be listed in the +output of ``bin/resources.py``. .. include:: links.rst diff --git a/doc/evaluate.rst b/doc/evaluate.rst index adef3a6a911d755e16330d7d723f681113a2b051..82fd9b58a2386022cb9ea8437628f25f49241079 100644 --- a/doc/evaluate.rst +++ b/doc/evaluate.rst @@ -1,62 +1,117 @@ .. vim: set fileencoding=utf-8 : -.. author: Pedro Tome <pedro.tome@idiap.ch> .. date: Thu Jan 15 15:58:57 CEST 2015 .. _evaluate: -====================== -Evaluating Score Files -====================== -Now, you have successfully run fingervein recognition experiments, and the result is one or more score files. -Usually, these score files are located in sub-directories of your ``--result-directory`` and are called ``scores-dev`` and ``scores-eval``. -This section describes how to interpret these score files. -So far, so good. -In this section we show, what to do with these files. +======================== + Evaluating Score Files +======================== + +Now, you have successfully run fingervein recognition experiments, and the +result is one or more score files. Usually, these score files are located in +sub-directories of your ``--result-directory`` and are called ``scores-dev`` +and ``scores-eval``. This section describes how to interpret these score +files. So far, so good. In this section we show, what to do with these files. Interpreting Score Files ------------------------ -The scores in the score files are arranged in rows. -Usually, each score was generated by comparing one probe image to one client model. -Information about this pair is contained in each row of the score file, which contains the four elements: -1. The client id of the model. This is the identity of the enrolled client model of this model/probe pair. -2. The client id of the probe. This is the identity shown in the probe image of this model/probe pair. -3. The path of the probe image file, which is relative to the image database directory and without file extension. +The scores in the score files are arranged in rows. Usually, each score was +generated by comparing one probe image to one client model. Information about +this pair is contained in each row of the score file, which contains the four +elements: + +1. The client id of the model. This is the identity of the enrolled client + model of this model/probe pair. +2. The client id of the probe. This is the identity shown in the probe image of + this model/probe pair. +3. The path of the probe image file, which is relative to the image database + directory and without file extension. 4. The score that was produced by comparing model and probe. -Hence, if the first two elements are identical, the score is a client (a.k.a. genuine, positive, true access, target) score, if they differ it is an impostor (a.k.a. negative, non-target) score. +Hence, if the first two elements are identical, the score is a client (a.k.a. +genuine, positive, true access, target) score, if they differ it is an impostor +(a.k.a. negative, non-target) score. Evaluation ---------- -Since all required information is available in the score file, you can use any tool (like MatLab) to evaluate the score file and compute error measures or generate plots. -The FingerveinRecLib defines one generic script that is able to evaluate the score files, compute some error measures and generate various types of plots. -This script is called ``bin/evaluate.py`` and has the following command line options (see ``bin/evaluate.py --help`` for the shortcuts): + +Since all required information is available in the score file, you can use any +tool (like MatLab) to evaluate the score file and compute error measures or +generate plots. The FingerveinRecLib defines one generic script that is able +to evaluate the score files, compute some error measures and generate various +types of plots. This script is called ``bin/evaluate.py`` and has the +following command line options (see ``bin/evaluate.py --help`` for the +shortcuts): * ``--dev-files``: A list of files of the development set that will be evaluated. -* ``--eval-files`` (optional): A list of files of the evaluation set. If given, please assure that there exist exactly one evaluation file for each development score file and that they are given in the same order. -* ``--directory`` (optional): If given, the ``--dev-files`` and ``--eval-files`` have either absolute paths or are relative to the given directory. -* ``--roc`` (optional): If given, the score files will be evaluated to compute an ROC curve (one for dev and one for eval) and the result is plotted to the given pdf file. -* ``--det`` (optional): If given, the score files will be evaluated to compute a DET curve (one for dev and one for eval) and the result is plotted to the given pdf file. -* ``--cmc`` (optional): If given, the score files will be evaluated to compute a CMC curve (one for dev and one for eval) and the result is plotted to the given pdf file. Please note that CMC plots are not valid for all databases. -* ``--legends`` (optional): If given, these legends will be placed into ROC, DET and CMC plots. Otherwise the file names will be used. Please assure that there exist exactly one legend for each development score file and that they are given in the correct order. -* ``--criterion`` (optional): If given, a threshold will be computed based on the EER or minimum HTER of each development set file, and applied to the development and evaluation files. Both results will be written to console. -* ``--cllr`` (optional): If given, a the Cllr and the minCllr will be computed on both the development and the evaluation set. All results will be written to console. +* ``--eval-files`` (optional): A list of files of the evaluation set. If given, + please assure that there exist exactly one evaluation file for each + development score file and that they are given in the same order. + +* ``--directory`` (optional): If given, the ``--dev-files`` and + ``--eval-files`` have either absolute paths or are relative to the given + directory. + +* ``--roc`` (optional): If given, the score files will be evaluated to compute + an ROC curve (one for dev and one for eval) and the result is plotted to the + given pdf file. + +* ``--det`` (optional): If given, the score files will be evaluated to compute + a DET curve (one for dev and one for eval) and the result is plotted to the + given pdf file. + +* ``--cmc`` (optional): If given, the score files will be evaluated to compute + a CMC curve (one for dev and one for eval) and the result is plotted to the + given pdf file. Please note that CMC plots are not valid for all databases. + +* ``--legends`` (optional): If given, these legends will be placed into ROC, + DET and CMC plots. Otherwise the file names will be used. Please assure that + there exist exactly one legend for each development score file and that they + are given in the correct order. + +* ``--criterion`` (optional): If given, a threshold will be computed based on + the EER or minimum HTER of each development set file, and applied to the + development and evaluation files. Both results will be written to console. -As usual, the ``--verbose`` (i.e., ``-v``) option exists, and it is wise to use ``-vv``. +* ``--cllr`` (optional): If given, a the Cllr and the minCllr will be computed + on both the development and the evaluation set. All results will be written + to console. + +As usual, the ``--verbose`` (i.e., ``-v``) option exists, and it is wise to use +``-vv``. Deep Evaluation --------------- -For deep evaluation you can use to plot the fauna models, EER per model for the all database in a detailed way. -The script called ``bin/scoresanalysis.py`` and has the following command line options (see ``bin/scoresanalysis.py --help`` for the shortcuts): -* ``--dev-files``: A list of files of the development set that will be evaluated. -* ``--eval-files`` (optional): A list of files of the evaluation set. If given, please assure that there exist exactly one evaluation file for each development score file and that they are given in the same order. -* ``--norm`` (optional): The scores are normalized in the rank [0,1]. (default: norm). -* ``--directory`` (optional): If given, the ``--dev-files`` and ``--eval-files`` have either absolute paths or are relative to the given directory. -* ``--criterion`` (optional): If given, a threshold will be computed based on the EER or minimum HTER of each development set file, and applied to the development and evaluation files. Both results will be written to console. -* ``--pdf`` (optional): If given, Fauna graph will be plotted into the given pdf file. (default: None) +For deep evaluation you can use to plot the fauna models, EER per model for the +all database in a detailed way. The script called ``bin/scoresanalysis.py`` +and has the following command line options (see ``bin/scoresanalysis.py +--help`` for the shortcuts): + +* ``--dev-files``: A list of files of the development set that will be + evaluated. + +* ``--eval-files`` (optional): A list of files of the evaluation set. If given, + please assure that there exist exactly one evaluation file for each + development score file and that they are given in the same order. + +* ``--norm`` (optional): The scores are normalized in the rank [0,1]. (default: + norm). + +* ``--directory`` (optional): If given, the ``--dev-files`` and + ``--eval-files`` have either absolute paths or are relative to the given + directory. + +* ``--criterion`` (optional): If given, a threshold will be computed based on + the EER or minimum HTER of each development set file, and applied to the + development and evaluation files. Both results will be written to console. + +* ``--pdf`` (optional): If given, Fauna graph will be plotted into the given + pdf file. (default: None) -As usual, the ``--verbose`` (i.e., ``-v``) option exists, and it is wise to use ``-vv``. +As usual, the ``--verbose`` (i.e., ``-v``) option exists, and it is wise to use +``-vv``. diff --git a/doc/experiments.rst b/doc/experiments.rst index 5f3973f489b80d2ade0ebf361297ccaa9a6fc667..8f6aeb65c97acae8847d0e39408b3f44e63cd00a 100644 --- a/doc/experiments.rst +++ b/doc/experiments.rst @@ -1,33 +1,41 @@ .. vim: set fileencoding=utf-8 : -.. author: Pedro Tome <pedro.tome@idiap.ch> .. date: Thu Jan 15 15:58:57 CEST 2015 .. _experiments: -=================== -Running Experiments -=================== +===================== + Running Experiments +===================== -For running experiments with a defined setup, you should use the ``bin/fingerveinverify.py`` script directly. +For running experiments with a defined setup, you should use the +``bin/fingerveinverify.py`` script directly. In the following sections the available command line arguments are listed. -Sometimes, arguments have a long version starting with ``--`` and a short one starting with a single ``-``. -In this section, only the long names of the arguments are listed, please refer to ``bin/fingerveinverify.py --help`` (or short: ``bin/fingerveinverify.py -h``) for the abbreviations. +Sometimes, arguments have a long version starting with ``--`` and a short one +starting with a single ``-``. In this section, only the long names of the +arguments are listed, please refer to ``bin/fingerveinverify.py --help`` (or +short: ``bin/fingerveinverify.py -h``) for the abbreviations. + .. _required: Required Command Line Arguments ------------------------------- -To run a fingervein recognition experiment using the FingerveinRecLib, you have to tell the ``bin/fingerveinverify.py`` script, which database, preprocessing, features, and algorithm should be used. -To use this script, you have to specify at least these command line arguments (see also the ``--help`` option): -* ``--database``: The database to run the experiments on, and which protocol to use. +To run a fingervein recognition experiment using the FingerveinRecLib, you have +to tell the ``bin/fingerveinverify.py`` script, which database, preprocessing, +features, and algorithm should be used. To use this script, you have to +specify at least these command line arguments (see also the ``--help`` option): + +* ``--database``: The database to run the experiments on, and which protocol to + use. * ``--preprocessing``: The data preprocessing and its parameters. * ``--features``: The features to extract and their options. * ``--tool``: The recognition algorithm and all its required parameters. -There is another command line argument that is used to separate the resulting files from different experiments. -Please specify a descriptive name for your experiment to be able to remember, how the experiment was run: +There is another command line argument that is used to separate the resulting +files from different experiments. Please specify a descriptive name for your +experiment to be able to remember, how the experiment was run: * ``--sub-directory``: A descriptive name for your experiment. @@ -36,38 +44,45 @@ Please specify a descriptive name for your experiment to be able to remember, ho Managing Resources ~~~~~~~~~~~~~~~~~~ -The FingerveinRecLib is designed in a way that makes it very easy to select the setup of your experiments. -Basically, you can specify your algorithm and its configuration in three different ways: -1. You choose one of the registered resources. - Just call ``bin/resources.py`` or ``bin/fingerveinverify.py --help`` to see, which kind of resources are currently registered. - Of course, you can also register a new resource. +The FingerveinRecLib is designed in a way that makes it very easy to select the +setup of your experiments. Basically, you can specify your algorithm and its +configuration in three different ways: + +1. You choose one of the registered resources. Just call ``bin/resources.py`` + or ``bin/fingerveinverify.py --help`` to see, which kind of resources are + currently registered. Of course, you can also register a new resource. How this is done is detailed in section :ref:`register-resources`. Example: .. code-block:: sh - $ bin/fingerveinverify.py --database vera + $ bin/fingerveinverify.py --database vera + -2. You define a configuration file or choose one of the already existing configuration files that are located in `FingerveinRecLib/configurations`_ and its sub-directories. - How to define a new configuration file, please read section :ref:`configuration-files`. +2. You define a configuration file or choose one of the already existing + configuration files that are located in `FingerveinRecLib/configurations`_ + and its sub-directories. How to define a new configuration file, please read + section :ref:`configuration-files`. Example: .. code-block:: sh - $ bin/fingerveinverify.py --preprocessing histeq + $ bin/fingerveinverify.py --preprocessing histeq + 3. You directly put the constructor call of the class into the command line. - Since the parentheses are special characters in the shell, usually you have to enclose the constructor call into quotes. - If you, e.g., want to extract MC-MaximumCurvature features, just add a to your command line. + Since the parentheses are special characters in the shell, usually you have + to enclose the constructor call into quotes. If you, e.g., want to extract + MC-MaximumCurvature features, just add a to your command line. Example: .. code-block:: sh - $ bin/fingerveinverify.py --features mc-maximumcurvature + $ bin/fingerveinverify.py --features mc-maximumcurvature Of course, you can mix the ways, how you define command line options. @@ -134,13 +149,13 @@ Fingervein Cropping Parameters * ``mask_h``: Height of the cropping finger mask. -* ``mask_w``: Width of the cropping finger mask. +* ``mask_w``: Width of the cropping finger mask. * ``padding_offset``: An offset to the paddy array to be applied arround the fingervein image. * ``padding_threshold``: The pixel value of this paddy array. Defined to 0.2 to uncontrolled (low quality) fingervein databases and to 0 for controlled (high quality) fingervein databases. (By default 0.2). - -* ``preprocessing``: The pre-processing applied to the fingervein image before finger contour extraction. + +* ``preprocessing``: The pre-processing applied to the fingervein image before finger contour extraction. By default equal to 'None'. * ``fingercontour``: The algorithm used to localize the finger contour. @@ -171,10 +186,10 @@ Several different kinds of features can be extracted from the preprocessed data. Here is the list of classes to perform feature extraction and its parameters. * :py:class:`FingerveinRecLib.features.normalised_crosscorr`: Just use the full image as a feature. -* :py:class:`FingerveinRecLib.features.maximum_curvature`: Extracts Maximum Curvature features [MNM05]_ from the preprocessed data. -* :py:class:`FingerveinRecLib.features.repeated_line_tracking`: Extracts Repeated Line Tracking features [MNM04]_ from the preprocessed data. -* :py:class:`FingerveinRecLib.features.wide_line_detector`: Extracts Wide Line Detector features [HDLTL10]_ from the preprocessed data. -* :py:class:`FingerveinRecLib.features.lbp`: Extracts Local Binary Patterns features [MD13]_ from the preprocessed data. +* :py:class:`FingerveinRecLib.features.maximum_curvature`: Extracts Maximum Curvature features [MNM05]_ from the preprocessed data. +* :py:class:`FingerveinRecLib.features.repeated_line_tracking`: Extracts Repeated Line Tracking features [MNM04]_ from the preprocessed data. +* :py:class:`FingerveinRecLib.features.wide_line_detector`: Extracts Wide Line Detector features [HDLTL10]_ from the preprocessed data. +* :py:class:`FingerveinRecLib.features.lbp`: Extracts Local Binary Patterns features [MD13]_ from the preprocessed data. .. _algorithms: @@ -189,12 +204,12 @@ These parameters mainly deal with how to compute a single score when more than o Here is a list of the most important algorithms and their parameters: -* :py:class:`FingerveinRecLib.tools.MiuraMatch`: Computes the match ratio based on [MNM04]_ convolving the two template image. +* :py:class:`FingerveinRecLib.tools.MiuraMatch`: Computes the match ratio based on [MNM04]_ convolving the two template image. Return score - Value between 0 and 0.5, larger value is better match. - ``ch``: Maximum search displacement in y-direction. Different defult values based on the different features. - ``cw``: Maximum search displacement in x-direction. Different defult values based on the different features. - + * :py:class:`FingerveinRecLib.tools.HammingDistance`: Computes the Hamming Distance between two fingervein templates. @@ -277,7 +292,7 @@ If you want to re-use parts previous experiments, you can specify the directorie * ``--preprocessed-data-directory`` * ``--features-directory`` -* ``--models-directories`` +* ``--models-directories`` or even trained extractor, projector, or enroller (i.e., the results of the extractor, projector, or enroller training): diff --git a/doc/index.rst b/doc/index.rst index 10e855ad92277634e909555c9d739c1726dae15b..bc320c6c76dccffa5a93a5a2dc3a4c6b7fb7d9c8 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -1,5 +1,4 @@ .. vim: set fileencoding=utf-8 : -.. author: Pedro Tome <pedro.tome@idiap.ch> .. date: Wed Jan 14 11:58:57 CEST 2015 .. _fingerveinreclib: @@ -47,4 +46,4 @@ This documentation is still under development. .. include:: links.rst -.. _facereclib: http://pythonhosted.org/facereclib/index.html \ No newline at end of file +.. _facereclib: http://pythonhosted.org/facereclib/index.html diff --git a/doc/installation.rst b/doc/installation.rst index 35b0b8818de69c13a27292c292bb5a011c1098f0..c1b05103da04336075cb172dde19ef2b13940f37 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -1,5 +1,4 @@ .. vim: set fileencoding=utf-8 : -.. author: Pedro Tome <pedro.tome@idiap.ch> .. date: Thu Jan 15 15:58:57 CEST 2015 .. _installation: @@ -33,7 +32,7 @@ Be aware that you will get the latest changes and that it might not work as expe Bob ~~~ -The FingerveinRecLib is a satellite package of Bob_, where most of the image processing, feature extraction, and fingervein recognition algorithms, as well as the evaluation techniques are implemented. This package uses FaceRecLib_ as a parent package. +The FingerveinRecLib is a satellite package of Bob_, where most of the image processing, feature extraction, and fingervein recognition algorithms, as well as the evaluation techniques are implemented. This package uses FaceRecLib_ as a parent package. In its current version, the FingerveinRecLib requires Bob_ version 2 or greater. Since version 2.0 there is no need for a global installation of Bob any more, all required packages will be automatically downloaded from PyPi_. @@ -114,4 +113,4 @@ Afterwards, the documentation is available and you can read it, e.g., by using: .. include:: links.rst -.. _facereclib: http://pythonhosted.org/facereclib/index.html \ No newline at end of file +.. _facereclib: http://pythonhosted.org/facereclib/index.html diff --git a/doc/references.rst b/doc/references.rst index 4cbf18db9054d6f574d5c6485b8411294d5a3f1b..07af04f28260307e15b286ab7d5cc7aeaa7bc8f4 100644 --- a/doc/references.rst +++ b/doc/references.rst @@ -1,5 +1,4 @@ .. vim: set fileencoding=utf-8 : -.. author: Pedro Tome <pedro.tome@idiap.ch> .. date: Thu Jan 15 15:58:57 CEST 2015 ========== diff --git a/doc/satellite.rst b/doc/satellite.rst index f2a335d80e0734aed162adad8c4ea2edf7ad17f8..5d00f22e7824772d7e5e3dc3057f967827bdebfc 100644 --- a/doc/satellite.rst +++ b/doc/satellite.rst @@ -1,5 +1,4 @@ .. vim: set fileencoding=utf-8 : -.. author: Pedro Tome <pedro.tome@idiap.ch> .. date: Wed Jan 14 11:58:57 CEST 2015 .. _satellite-packages: diff --git a/setup.py b/setup.py index 4caf173f3648d6b6f4ec35dbab966849244c02e9..1e1bec542cc8d0641da6415822e891d2e1415068 100644 --- a/setup.py +++ b/setup.py @@ -1,37 +1,5 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Pedro Tome <pedro.tome@idiap.ch> -# Tue 25 Mar 18:18:08 2014 CEST -# -# Copyright (C) 2011-2014 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/>. - -# This file contains the python (distutils/setuptools) instructions so your -# package can be installed on **any** host system. It defines some basic -# information like the package name for instance, or its homepage. -# -# It also defines which other packages this python package depends on and that -# are required for this package's operation. The python subsystem will make -# sure all dependent packages are installed or will install them for you upon -# the installation of this package. -# -# The 'buildout' system we use here will go further and wrap this package in -# such a way to create an isolated python working environment. Buildout will -# make sure that dependencies which are not yet installed do get installed, but -# **without** requiring adminstrative privileges on the host system. This -# allows you to test your package with new python dependencies w/o requiring -# administrative interventions. from setuptools import setup, dist dist.Distribution(dict(setup_requires=['bob.extension'])) @@ -48,8 +16,8 @@ setup( url='https://gitlab.idiap.ch/biometric/bob.bio.vein', license='GPLv3', - author='Andre Anjos', - author_email='andre.anjos@idiap.ch', + author='Andre Anjos,Pedro Tome', + author_email='andre.anjos@idiap.ch,pedro.tome@idiap.ch', keywords = "bob, biometric recognition, evaluation, vein", @@ -63,15 +31,6 @@ setup( entry_points={ - # scripts should be declared using this entry: - 'console_scripts': [ - 'fingerveinverify.py = bob.bio.vein.script.fingerveinverify:main', - 'scores2spoofingfile.py = bob.bio.vein.script.scores2spoofingfile:main', - #'scoresanalysis.py = bob.bio.vein.script.scoresanalysis:main', - #'scoresfusion.py = bob.bio.vein.script.scoresfusion:main', - #'plot_scatter_fusion.py = bob.bio.vein.script.plot_scatter_fusion:main', - ], - # registered database short cuts 'bob.bio.database': [ 'utfvp = bob.bio.vein.configurations.databases.utfvp:database', @@ -116,7 +75,6 @@ setup( 'demanding = bob.bio.vein.configurations.grid.demanding:grid', 'very-demanding = bob.bio.vein.configurations.grid.very_demanding:grid', 'gbu = bob.bio.vein.configurations.grid.gbu:grid', - 'small = bob.bio.vein.configurations.grid.small:grid', ], },