Python API

This section contains a listing of all functionality available on this library which can be used for vein experiments.

Database Interfaces

Common Utilities

Database definitions for Vein Recognition

class bob.bio.vein.database.AnnotatedArray(input_array, metadata=None)[source]

Bases: ndarray

Defines a numpy array subclass that can carry its own metadata

Copied from: https://docs.scipy.org/doc/numpy-1.12.0/user/basics.subclassing.html#slightly-more-realistic-example-attribute-added-to-existing-array

UTFVP Database

Utfvp database implementation

class bob.bio.vein.database.utfvp.UtfvpDatabase(protocol)[source]

Bases: CSVDataset

The University of Twente Finger Vascular Pattern dataset

Warning

To use this dataset protocol, you need to have the original files of the UTFVP dataset. Once you have it downloaded, please run the following command to set the path for Bob

bob config set bob.bio.vein.utfvp.directory [DATABASE PATH]

The fingervein image database consists of 1440 images taken in 2 distinct session in two days (May 9th, 2012 and May 23rd, 2012) using a custom built fingervein sensor. In each session, each of the 60 subjects in the dataset were asked to present 6 fingers to the sensor twice, making up separate tries. The six fingers are the left and right ring, middle and index fingers. Therefore, the database contains 60x6 = 360 unique fingers.

Files in the database have a strict naming convention and are organized in directories following their subject identifier like so: 0003/0003_5_2_120509-141536. The fields can be interpreted as <subject-id>/<subject-id>_<finger-name>_<trial>_<date>-<hour>. The subject identifier is written as a 4-digit number with leading zeroes, varying from 1 to 60. The finger name is one of the following:

  • 1: Left ring

  • 2: Left middle

  • 3: Left index

  • 4: Right index

  • 5: Right middle

  • 6: Right ring

The trial identifiers can vary between 1 and 4. The first two tries were captured during the first session while the last two, on the second session. Given the difference in the images between trials on the same day, we assume users were asked to remove the finger from the device and re-position it afterwards.

Annotations

We provide region-of-interest (RoI) hand-made annotations for all images in this dataset. The annotations mark the place where the finger is on the image, excluding the background. The annotation file is a text file with one annotation per line in the format (y, x), respecting Bob’s image encoding convention. The interconnection of these points in a polygon forms the RoI.

Warning

To use the annotations, you need to provide the roi files. Once you have it downloaded, please run the following command to set the path for Bob

bob config set bob.bio.vein.utfvp.roi [ANNOTATION PATH]

Protocols

There are 15 protocols implemented in this package:

  • 1vsall

  • nom

  • nomLeftRing

  • nomLeftMiddle

  • nomLeftIndex

  • nomRightIndex

  • nomRightMiddle

  • nomRightRing

  • full

  • fullLeftRing

  • fullLeftMiddle

  • fullLeftIndex

  • fullRightIndex

  • fullRightMiddle

  • fullRightRing

“nom” Protocols

“nom” means “normal operation mode”. In this set of protocols, images from different clients are separated in different sets that can be used for system training, validation and evaluation:

  • Fingers from clients in the range [1, 10] are used on the training set

  • Fingers from clients in the range [11, 28] are used on the development (or validation) set

  • Fingers from clients in the range [29, 60] are used in the evaluation (or test) set

Data from the first session (both trials) can be used for enrolling the finger while data on the last session (both trials) should be used exclusively for probing the finger. In the way setup by this database interface, each of the samples is returned as a separate enrollment model. If a single score per finger is required, the user must manipulate the final score listings and fuse results themselves.

Matching happens exhaustively between all probes and models. The variants named “nomLeftRing”, for example, contain the data filtered by finger name as per the listings above. For example, “Left Ring” means all files named */*_1_*_*-*.png. Therefore, the equivalent protocol contains only 1/6 of the files of its complete nom version.

“full” Protocols

“full” protocols are meant to match current practices in fingervein reporting in which most published material don’t use a separate evaluation set. All data is placed on the development (or validation) set. In these protocols, all images are used both for enrolling and probing for fingers. It is, of course, a biased setup. Matching happens exhaustively between all samples in the development set.

The variants named “fullLeftRing”, for example, contain the data filtered by finger name as per the listings above. For example, “Left Ring” means all files named */*_1_*_*-*.png. Therefore, the equivalent protocol contains only 1/6 of the files of its complete full version.

“1vsall” Protocol

The “1vsall” protocol is meant as a cross-validation protocol. All data from the dataset is split into training and development (or validation). No samples are allocated for a separate evaluation (or test) set. The training set is composed of all samples of fingers 0001_1 (left ring finger of subject 1), 0002_2 (left middle finger of subject 2), 0003_3 (left index finger of subject 3), 0004_4 (right index finger of subject 4), 0005_5 (right middle finger of subject 5), 0006_6 (right ring finger of subject 6), 0007_1 (left ring finger of subject 7), 0008_2 (left middle finger of subject 8) and so on, until subject 35 (inclusive). There are 140 images in total on this set.

All other 1300 samples from the dataset are used as a development (or validation) set. Each sample generates a single model and is used as a probe for all other models. Matching happens exhaustively, but with the same image that generated the model being matched. So, there are 1299 probes per model.

static protocols()[source]
static urls()[source]

VERA Fingervein Contactless Database

VERA-Fingervein-Contactless database implementation

class bob.bio.vein.database.verafinger_contactless.VerafingerContactless(protocol)[source]

Bases: CSVDataset

The VERA Fingervein Contactless database contains 1330 finger vein images of 133 persons, with id ranging from 1 to 137 (with 4 defects). Both hands of the subjects have been imaged over 5 different sessions, with a total of 10 images per person. The sensor is described in this paper.

Warning

To use this dataset protocol, you need to have the original files of the VERA Fingervein Contactless dataset. Once you have it downloaded, please run the following command to set the path for Bob

bob config set bob.bio.vein.verafinger_contactless.directory [DATABASE PATH]

Metadata

Associated to each sample, you may find the metadata configuration for each capture :

  • EXPOSURE : exposure time (in ms)

  • ORTHOLED : Power of the ORTHOLED (in % of the max power)

  • CENTERLED : Power of the CENTERLED (in % of the max power)

  • CROSSLED : Power of the CROSSLED (in % of the max power)

Protocols

NOM (Normal Operation Mode) protocol

  • Development set : Even subject ids

  • Evaluation set : Odd subject ids

  • Models : session 1 & 2

  • Probes : session 3, 4 &5

static protocols()[source]
static urls()[source]

Pre-processors

class bob.bio.vein.preprocessor.AnnotatedRoIMask

Bases: Masker

Devises the mask from the annotated RoI

class bob.bio.vein.preprocessor.Cropper

Bases: object

This is the base class for all croppers

It defines the minimum requirements for all derived cropper classes.

class bob.bio.vein.preprocessor.Filter

Bases: object

Objects of this class filter the input image

class bob.bio.vein.preprocessor.FixedCrop(top=0, bottom=0, left=0, right=0)

Bases: Cropper

Implements cropping using a fixed suppression of border pixels

The defaults supress no lines from the image and returns an image like the original. If an bob.bio.vein.database.AnnotatedArray is passed, then we also check for its .metadata['roi'] component and correct it so that annotated RoI points are consistent on the cropped image.

Note

Before choosing values, note you’re responsible for knowing what is the orientation of images fed into this cropper.

Parameters
  • top (int, optional) – Number of lines to suppress from the top of the image. The top of the image corresponds to y = 0.

  • bottom (int, optional) – Number of lines to suppress from the bottom of the image. The bottom of the image corresponds to y = height.

  • left (int, optional) – Number of lines to suppress from the left of the image. The left of the image corresponds to x = 0.

  • right (int, optional) – Number of lines to suppress from the right of the image. The right of the image corresponds to x = width.

class bob.bio.vein.preprocessor.FixedMask(top=0, bottom=0, left=0, right=0)

Bases: Masker

Implements masking using a fixed suppression of border pixels

The defaults mask no lines from the image and returns a mask of the same size of the original image where all values are True.

Note

Before choosing values, note you’re responsible for knowing what is the orientation of images fed into this masker.

Parameters
  • top (int, optional) – Number of lines to suppress from the top of the image. The top of the image corresponds to y = 0.

  • bottom (int, optional) – Number of lines to suppress from the bottom of the image. The bottom of the image corresponds to y = height.

  • left (int, optional) – Number of lines to suppress from the left of the image. The left of the image corresponds to x = 0.

  • right (int, optional) – Number of lines to suppress from the right of the image. The right of the image corresponds to x = width.

class bob.bio.vein.preprocessor.HistogramEqualization

Bases: Filter

Applies histogram equalization on the input image inside the mask.

In this implementation, only the pixels that lie inside the mask will be used to calculate the histogram equalization parameters. Because of this particularity, we don’t use Bob’s implementation for histogram equalization and have one based exclusively on scikit-image.

class bob.bio.vein.preprocessor.HuangNormalization(padding_width=5, padding_constant=51)

Bases: Normalizer

Simple finger normalization from Huang et. al

Based on B. Huang, Y. Dai, R. Li, D. Tang and W. Li, Finger-vein authentication based on wide line detector and pattern normalization, Proceedings on 20th International Conference on Pattern Recognition (ICPR), 2010.

This implementation aligns the finger to the centre of the image using an affine transformation. Elliptic projection which is described in the referenced paper is not included.

In order to defined the affine transformation to be performed, the algorithm first calculates the center for each edge (column wise) and calculates the best linear fit parameters for a straight line passing through those points.

class bob.bio.vein.preprocessor.KonoMask(sigma=5, padder=<bob.bio.vein.preprocessor.Padder object>)

Bases: Masker

Estimates the finger region given an input NIR image using Kono et al.

This method is based on the work of 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).

Parameters
  • sigma (float, optional) – The standard deviation of the gaussian blur filter to apply for low-passing the input image (background extraction). Defaults to 5.

  • padder (Padder, optional) – If passed, will pad the image before evaluating the mask. The returned value will have the padding removed and is, therefore, of the exact size of the input image.

class bob.bio.vein.preprocessor.LeeMask(filter_height=4, filter_width=40, padder=<bob.bio.vein.preprocessor.Padder object>)

Bases: Masker

Estimates the finger region given an input NIR image using Lee et al.

This method is based on the work of Finger vein recognition using minutia-based alignment and local binary pattern-based feature extraction, E.C. Lee, H.C. Lee and K.R. Park, International Journal of Imaging Systems and Technology, Volume 19, Issue 3, September 2009, Pages 175–178, doi: 10.1002/ima.20193

This code is based on the Matlab implementation by Bram Ton, available at:

https://nl.mathworks.com/matlabcentral/fileexchange/35752-finger-region-localisation/content/lee_region.m

In this method, we calculate the mask of the finger independently for each column of the input image. Firstly, the image is convolved with a [1,-1] filter of size (self.filter_height, self.filter_width). Then, the upper and lower parts of the resulting filtered image are separated. The location of the maxima in the upper part is located. The same goes for the location of the minima in the lower part. The mask is then calculated, per column, by considering it starts in the point where the maxima is in the upper part and goes up to the point where the minima is detected on the lower part.

Parameters
  • filter_height (int, optional) – Height of contour mask in pixels, must be an even number

  • filter_width (int, optional) – Width of the contour mask in pixels

class bob.bio.vein.preprocessor.Masker

Bases: object

This is the base class for all maskers

It defines the minimum requirements for all derived masker classes.

class bob.bio.vein.preprocessor.NoCrop

Bases: FixedCrop

Convenience: same as FixedCrop()

class bob.bio.vein.preprocessor.NoFilter

Bases: Filter

Applies no filtering on the input image, returning it without changes

class bob.bio.vein.preprocessor.NoMask

Bases: FixedMask

Convenience: same as FixedMask()

class bob.bio.vein.preprocessor.NoNormalization

Bases: Normalizer

Trivial implementation with no normalization

class bob.bio.vein.preprocessor.Normalizer

Bases: object

Objects of this class normalize the input image orientation and scale

class bob.bio.vein.preprocessor.Padder(padding_width=5, padding_constant=51)

Bases: object

A class that pads the input image returning a new object

Parameters
  • padding_width (int, optional) – How much padding (in pixels) to add around the borders of the input image. We normally always keep this value on its default (5 pixels). This parameter is always used before normalizing the finger orientation.

  • padding_constant (int, optional) – What is the value of the pixels added to the padding. This number should be a value between 0 and 255. (From Pedro Tome: for UTFVP (high-quality samples), use 0. For the VERA Fingervein database (low-quality samples), use 51 (that corresponds to 0.2 in a float image with values between 0 and 1). This parameter is always used before normalizing the finger orientation.

class bob.bio.vein.preprocessor.Preprocessor(crop, mask, normalize, filter, **kwargs)

Bases: Preprocessor

Extracts the mask and pre-processes fingervein images.

In this implementation, the finger image is (in this order):

  1. The image is pre-cropped to remove obvious non-finger image parts

  2. The mask is extrapolated from the image using one of our Masker’s concrete implementations

  3. The image is normalized with one of our Normalizer’s

  4. The image is filtered with one of our Filter’s

Parameters
  • crop (Cropper) – An object that will perform pre-cropping on the input image before a mask can be estimated. It removes parts of the image which are surely not part of the finger region you’ll want to consider for the next steps.

  • mask (Masker) – An object representing a Masker instance which will extrapolate the mask from the input image.

  • normalize (Normalizer) – An object representing a Normalizer instance which will normalize the input image and its mask returning a new image mask pair.

  • filter (Filter) – An object representing a Filter instance will will filter the input image and return a new filtered image. The filter instance also receives the extrapolated mask so it can, if desired, only apply the filtering operation where the mask has a value of True

read_data(filename)[source]

Overrides the default method implementation to handle our tuple

write_data(data, filename)[source]

Overrides the default method implementation to handle our tuple

class bob.bio.vein.preprocessor.TomesLeeMask(filter_height=4, filter_width=40, padder=<bob.bio.vein.preprocessor.Padder object>)

Bases: Masker

Estimates the finger region given an input NIR image using Lee et al.

This method is based on the work of Finger vein recognition using minutia-based alignment and local binary pattern-based feature extraction, E.C. Lee, H.C. Lee and K.R. Park, International Journal of Imaging Systems and Technology, Volume 19, Issue 3, September 2009, Pages 175–178, doi: 10.1002/ima.20193

This code is a variant of the Matlab implementation by Bram Ton, available at:

https://nl.mathworks.com/matlabcentral/fileexchange/35752-finger-region-localisation/content/lee_region.m

In this variant from Pedro Tome, the technique of filtering the image with a horizontal filter is also applied on the vertical axis. The objective is to find better limits on the horizontal axis in case finger images show the finger tip. If that is not your case, you may use the original variant LeeMask above.

Parameters
  • filter_height (int, optional) – Height of contour mask in pixels, must be an even number

  • filter_width (int, optional) – Width of the contour mask in pixels

Pre-processor utilities

Utilities for preprocessing vein imagery

bob.bio.vein.preprocessor.utils.assert_points(area, points)[source]

Checks all points fall within the determined shape region, inclusively

This assertion function, test all points given in points fall within a certain area provided in area.

Parameters
  • area (tuple) – A tuple containing the size of the limiting area where the points should all be in.

  • points (numpy.ndarray) – A 2D numpy ndarray with any number of rows (points) and 2 columns (representing y and x coordinates respectively), or any type convertible to this format. This array contains the points that will be checked for conformity. In case one of the points doesn’t fall into the determined area an assertion is raised.

Raises

AssertionError – In case one of the input points does not fall within the area defined.

bob.bio.vein.preprocessor.utils.fix_points(area, points)[source]

Checks/fixes all points so they fall within the determined shape region

Points which are lying outside the determined area will be brought into the area by moving the offending coordinate to the border of the said area.

Parameters
  • area (tuple) – A tuple containing the size of the limiting area where the points should all be in.

  • points (numpy.ndarray) – A 2D numpy.ndarray with any number of rows (points) and 2 columns (representing y and x coordinates respectively), or any type convertible to this format. This array contains the points that will be checked/fixed for conformity. In case one of the points doesn’t fall into the determined area, it is silently corrected so it does.

Returns

A new array of points with corrected coordinates

Return type

numpy.ndarray

bob.bio.vein.preprocessor.utils.poly_to_mask(shape, points)[source]

Generates a binary mask from a set of 2D points

Parameters
  • shape (tuple) – A tuple containing the size of the output mask in height and width, for Bob compatibility (y, x).

  • points (list) – A list of tuples containing the polygon points that form a region on the target mask. A line connecting these points will be drawn and all the points in the mask that fall on or within the polygon line, will be set to True. All other points will have a value of False.

Returns

A 2D numpy ndarray with dtype=bool with the mask generated with the determined shape, using the points for the polygon.

Return type

numpy.ndarray

bob.bio.vein.preprocessor.utils.mask_to_image(mask, dtype=<class 'numpy.uint8'>)[source]

Converts a binary (boolean) mask into an integer or floating-point image

This function converts a boolean binary mask into an image of the desired type by setting the points where False is set to 0 and points where True is set to the most adequate value taking into consideration the destination data type dtype. Here are support types and their ranges:

  • numpy.uint8: [0, (2^8)-1]

  • numpy.uint16: [0, (2^16)-1]

  • numpy.uint32: [0, (2^32)-1]

  • numpy.uint64: [0, (2^64)-1]

  • numpy.float32: [0, 1.0] (fixed)

  • numpy.float64: [0, 1.0] (fixed)

All other types are currently unsupported.

Parameters
  • mask (numpy.ndarray) – A 2D numpy ndarray with boolean data type, containing the mask that will be converted into an image.

  • dtype (numpy.dtype) – A valid numpy data-type from the list above for the resulting image

Returns

With the designated data type, containing the binary image formed from the mask.

Return type

numpy.ndarray

Raises

TypeError – If the type is not supported by this function

bob.bio.vein.preprocessor.utils.show_image(image)[source]

Shows a single image using PIL.Image.Image.show()

Warning

This function opens a new window. You must be operating interactively in a windowing system for it to work properly.

Parameters

image (numpy.ndarray) – A 2D numpy.ndarray compose of 8-bit unsigned integers containing the original image

bob.bio.vein.preprocessor.utils.draw_mask_over_image(image, mask, color='red')[source]

Plots the mask over the image of a finger, for debugging purposes

Parameters
  • image (numpy.ndarray) – A 2D numpy.ndarray compose of 8-bit unsigned integers containing the original image

  • mask (numpy.ndarray) – A 2D numpy.ndarray compose of boolean values containing the calculated mask

Returns

An image in PIL format

Return type

PIL.Image

bob.bio.vein.preprocessor.utils.show_mask_over_image(image, mask, color='red')[source]

Plots the mask over the image of a finger using PIL.Image.Image.show()

Warning

This function opens a new window. You must be operating interactively in a windowing system for it to work properly.

Parameters
  • image (numpy.ndarray) – A 2D numpy.ndarray compose of 8-bit unsigned integers containing the original image

  • mask (numpy.ndarray) – A 2D numpy.ndarray compose of boolean values containing the calculated mask

bob.bio.vein.preprocessor.utils.jaccard_index(a, b)[source]

Calculates the intersection over union for two masks

This function calculates the Jaccard index:

\[\begin{split}J(A,B) &= \\frac{|A \cap B|}{|A \\cup B|} \\\\ &= \\frac{|A \cap B|}{|A|+|B|-|A \\cup B|}\end{split}\]
Parameters
Returns

The floating point number that corresponds to the Jaccard index. The float value lies inside the interval \([0, 1]\). If a and b are equal, then the similarity is maximum and the value output is 1.0. If the areas are exclusive, then the value output by this function is 0.0.

Return type

float

bob.bio.vein.preprocessor.utils.intersect_ratio(a, b)[source]

Calculates the intersection ratio between the ground-truth and a probe

This function calculates the intersection ratio between a ground-truth mask (\(A\); probably generated from an annotation) and a probe mask (\(B\)), returning the ratio of overlap when the probe is compared to the ground-truth data:

\[R(A,B) = \frac{|A \cap B|}{|A|}\]

So, if the probe occupies the entirety of the ground-truth data, then the output of this function is 1.0, otherwise, if areas are exclusive, then this function returns 0.0. The output of this function should be analyzed against the output of intersect_ratio_of_complement(), which provides the complementary information about the intersection of the areas being analyzed.

Parameters
  • a (numpy.ndarray) – A 2D numpy array with dtype bool, that corresponds to the ground-truth object

  • b (numpy.ndarray) – A 2D numpy array with dtype bool, that corresponds to the probe object that will be compared to the ground-truth

Returns

The floating point number that corresponds to the overlap ratio. The float value lies inside the interval \([0, 1]\).

Return type

float

bob.bio.vein.preprocessor.utils.intersect_ratio_of_complement(a, b)[source]

Calculates the intersection ratio between the complement of ground-truth and a probe

This function calculates the intersection ratio between the complement of a ground-truth mask (\(A\); probably generated from an annotation) and a probe mask (\(B\)), returning the ratio of overlap when the probe is compared to the ground-truth data:

\[R(A,B) = \frac{|A^c \cap B|}{|A|} = B \setminus A\]

So, if the probe is totally inside the ground-truth data, then the output of this function is 0.0, otherwise, if areas are exclusive for example, then this function outputs greater than zero. The output of this function should be analyzed against the output of intersect_ratio(), which provides the complementary information about the intersection of the areas being analyzed.

Parameters
  • a (numpy.ndarray) – A 2D numpy array with dtype bool, that corresponds to the ground-truth object

  • b (numpy.ndarray) – A 2D numpy array with dtype bool, that corresponds to the probe object that will be compared to the ground-truth

Returns

The floating point number that corresponds to the overlap ratio between the probe area and the complement of the ground-truth area. There are no bounds for the float value on the right side: \([0, +\infty)\).

Return type

float

Feature Extractors

class bob.bio.vein.extractor.MaximumCurvature(sigma=5)[source]

Bases: Extractor

MiuraMax feature extractor.

Based on N. Miura, A. Nagasaka, and T. Miyatake, Extraction of Finger-Vein Pattern Using Maximum Curvature Points in Image Profiles. Proceedings on IAPR conference on machine vision applications, 9 (2005), pp. 347–350.

Parameters

sigma (int, optional) – standard deviation for the gaussian smoothing kernel used to denoise the input image. The width of the gaussian kernel will be set automatically to 4x this value (in pixels).

detect_valleys(image, mask)[source]

Detects valleys on the image respecting the mask

This step corresponds to Step 1-1 in the original paper. The objective is, for all 4 cross-sections (z) of the image (horizontal, vertical, 45 and -45 diagonals), to compute the following proposed valley detector as defined in Equation 1, page 348:

\[\begin{split}\kappa(z) = \\frac{d^2P_f(z)/dz^2}{(1 + (dP_f(z)/dz)^2)^\\frac{3}{2}}\end{split}\]

We start the algorithm by smoothing the image with a 2-dimensional gaussian filter. The equation that defines the kernel for the filter is:

\[\begin{split}\mathcal{N}(x,y)=\\frac{1}{2\pi\sigma^2}e^\\frac{-(x^2+y^2)}{2\sigma^2}\end{split}\]

This is done to avoid noise from the raw data (from the sensor). The maximum curvature method then requires we compute the first and second derivative of the image for all cross-sections, as per the equation above.

We instead take the following equivalent approach:

  1. construct a gaussian filter

  2. take the first (dh/dx) and second (d^2/dh^2) deritivatives of the filter

  3. calculate the first and second derivatives of the smoothed signal using the results from 3. This is done for all directions we’re interested in: horizontal, vertical and 2 diagonals. First and second derivatives of a convolved signal

Note

Item 3 above is only possible thanks to the steerable filter property of the gaussian kernel. See “The Design and Use of Steerable Filters” from Freeman and Adelson, IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol. 13, No. 9, September 1991.

Parameters
  • image (numpy.ndarray) – an array of 64-bit floats containing the input image

  • mask (numpy.ndarray) – an array, of the same size as image, containing a mask (booleans) indicating where the finger is on image.

Returns

a 3-dimensional array of 64-bits containing $kappa$ for all considered directions. $kappa$ has the same shape as image, except for the 3rd. dimension, which provides planes for the cross-section valley detections for each of the contemplated directions, in this order: horizontal, vertical, +45 degrees, -45 degrees.

Return type

numpy.ndarray

eval_vein_probabilities(k)[source]

Evaluates joint vein centre probabilities from cross-sections

This function will take $kappa$ and will calculate the vein centre probabilities taking into consideration valley widths and depths. It aggregates the following steps from the paper:

  • [Step 1-2] Detection of the centres of veins

  • [Step 1-3] Assignment of scores to the centre positions

  • [Step 1-4] Calculation of all the profiles

Once the arrays of curvatures (concavities) are calculated, here is how detection works: The code scans the image in a precise direction (vertical, horizontal, diagonal, etc). It tries to find a concavity on that direction and measure its width (see Wr on Figure 3 on the original paper). It then identifies the centers of the concavity and assign a value to it, which depends on its width (Wr) and maximum depth (where the peak of darkness occurs) in such a concavity. This value is accumulated on a variable (Vt), which is re-used for all directions. Vt represents the vein probabilites from the paper.

Parameters

k (numpy.ndarray) – a 3-dimensional array of 64-bits containing $kappa$ for all considered directions. $kappa$ has the same shape as image, except for the 3rd. dimension, which provides planes for the cross-section valley detections for each of the contemplated directions, in this order: horizontal, vertical, +45 degrees, -45 degrees.

Returns

The un-accumulated vein centre probabilities V. This is a 3D array with 64-bit floats with the same dimensions of the input array k. You must accumulate (sum) over the last dimension to retrieve the variable V from the paper.

Return type

numpy.ndarray

connect_centres(V)[source]

Connects vein centres by filtering vein probabilities V

This function does the equivalent of Step 2 / Equation 4 at Miura’s paper.

The operation is applied on a row from the V matrix, which may be acquired horizontally, vertically or on a diagonal direction. The pixel value is then reset in the center of a windowing operation (width = 5) with the following value:

\[b[w] = min(max(a[w+1], a[w+2]) + max(a[w-1], a[w-2]))\]
Parameters

V (numpy.ndarray) – The accumulated vein centre probabilities V. This is a 2D array with 64-bit floats and is defined by Equation (3) on the paper.

Returns

A 3-dimensional 64-bit array Cd containing the result of the filtering operation for each of the directions. Cd has the dimensions of $kappa$ and $V_i$. Each of the planes correspond to the horizontal, vertical, +45 and -45 directions.

Return type

numpy.ndarray

binarise(G)[source]

Binarise vein images using a threshold assuming distribution is diphasic

This function implements Step 3 of the paper. It binarises the 2-D array G assuming its histogram is mostly diphasic and using a median value.

Parameters

G (numpy.ndarray) – A 2-dimensional 64-bit array G containing the result of the filtering operation. G has the dimensions of the original image.

Returns

A 2-dimensional 64-bit float array with the same dimensions of the input image, but containing its vein-binarised version. The output of this function corresponds to the output of the method.

Return type

numpy.ndarray

class bob.bio.vein.extractor.NormalisedCrossCorrelation[source]

Bases: Extractor

Normalised Cross-Correlation feature extractor

Based on [KUU02]

class bob.bio.vein.extractor.PrincipalCurvature(sigma=3, threshold=4)[source]

Bases: Extractor

MiuraMax feature extractor

Based on [CW09].

ut_gauss(img, sigma, dx, dy)[source]
principal_curvature(image, mask)[source]

Computes and returns the Maximum Curvature features for the given input fingervein image

class bob.bio.vein.extractor.RepeatedLineTracking(iterations=3000, r=1, profile_w=21, rescale=True, seed=0)[source]

Bases: Extractor

Repeated Line Tracking feature extractor

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

repeated_line_tracking(finger_image, mask)[source]

Computes and returns the MiuraMax features for the given input fingervein image

skeletonize(img)[source]
class bob.bio.vein.extractor.WideLineDetector(radius=5, threshold=1, g=41, rescale=True)[source]

Bases: Extractor

Wide Line Detector feature extractor

Based on B. Huang, Y. Dai, R. Li, D. Tang and W. Li. [HDLTL10]

wide_line_detector(finger_image, mask)[source]

Computes and returns the Wide Line Detector features for the given input fingervein image

Matching Algorithms

class bob.bio.vein.algorithm.Correlate(probes_score_fusion='max', enrolls_score_fusion='mean', **kwargs)

Bases: BioAlgorithm

Correlate probe and model without cropping

The method is based on “cross-correlation” between a model and a probe image. The difference between this and MiuraMatch is that no cropping takes place on this implementation. We simply fill the excess boundary with zeros and extract the valid correlation region between the probe and the model using skimage.feature.match_template().

compare(enroll_templates, probe_templates)[source]

Computes the similarity score between all enrollment and probe templates.

Parameters
  • enroll_templates (list) – A list (length N) of enrollment templates.

  • probe_templates (list) – A list (length M) of probe templates.

Returns

scores – A matrix of shape (N, M) containing the similarity scores.

Return type

numpy.ndarray

create_templates(feature_sets, enroll)[source]

Creates enroll or probe templates from multiple sets of features.

The enroll template format can be different from the probe templates.

Parameters
  • list_of_feature_sets (list) – A list of list of features with the shape of Nx?xD. N templates should be computed. Note that you cannot call np.array(list_of_feature_sets) because the number of features per set can be different depending on the database.

  • enroll (bool) – If True, the features are for enrollment. If False, the features are for probe.

Returns

templates – A list of templates which has the same length as list_of_feature_sets.

Return type

list

score(model, probe)[source]

Computes the score between the probe and the model.

Parameters
Returns

Value between 0 and 0.5, larger value means a better match

Return type

float

class bob.bio.vein.algorithm.HammingDistance(**kwargs)

Bases: Distance

This class calculates the Hamming distance between two binary images.

The enrollement and scoring functions of this class are implemented by its base bob.bio.base.algorithm.Distance.

The input to this function should be of binary nature (boolean arrays). Each binary input is first flattened to form a one-dimensional vector. The Hamming distance is then calculated between these two binary vectors.

The current implementation uses scipy.spatial.distance.hamming(), which returns a scalar 64-bit float to represent the proportion of mismatching corresponding bits between the two binary vectors.

The base class constructor parameter factor is set to 1 on purpose to ensure that calculated distances are returned as positive values rather than negative.

class bob.bio.vein.algorithm.MiuraMatch(ch=80, cw=90, probes_score_fusion='max', enrolls_score_fusion='mean', **kwargs)

Bases: BioAlgorithm

Finger vein matching: match ratio via cross-correlation

The method is based on “cross-correlation” between a model and a probe image. It convolves the binary image(s) representing the model with the binary image representing the probe (rotated by 180 degrees), and evaluates how they cross-correlate. If the model and probe are very similar, the output of the correlation corresponds to a single scalar and approaches a maximum. The value is then normalized by the sum of the pixels lit in both binary images. Therefore, the output of this method is a floating-point number in the range \([0, 0.5]\). The higher, the better match.

In case model and probe represent images from the same vein structure, but are misaligned, the output is not guaranteed to be accurate. To mitigate this aspect, Miura et al. proposed to add a small cropping factor to the model image, assuming not much information is available on the borders (ch, for the vertical direction and cw, for the horizontal direction). This allows the convolution to yield searches for different areas in the probe image. The maximum value is then taken from the resulting operation. The convolution result is normalized by the pixels lit in both the cropped model image and the matching pixels on the probe that yield the maximum on the resulting convolution.

For this to work properly, input images are supposed to be binary in nature, with zeros and ones.

Based on [MNM04] and [MNM05]

Parameters
  • ch (int, optional) – Maximum search displacement in y-direction.

  • cw (int, optional) – Maximum search displacement in x-direction.

compare(enroll_templates, probe_templates)[source]

Computes the similarity score between all enrollment and probe templates.

Parameters
  • enroll_templates (list) – A list (length N) of enrollment templates.

  • probe_templates (list) – A list (length M) of probe templates.

Returns

scores – A matrix of shape (N, M) containing the similarity scores.

Return type

numpy.ndarray

create_templates(feature_sets, enroll)[source]

Creates enroll or probe templates from multiple sets of features.

The enroll template format can be different from the probe templates.

Parameters
  • list_of_feature_sets (list) – A list of list of features with the shape of Nx?xD. N templates should be computed. Note that you cannot call np.array(list_of_feature_sets) because the number of features per set can be different depending on the database.

  • enroll (bool) – If True, the features are for enrollment. If False, the features are for probe.

Returns

templates – A list of templates which has the same length as list_of_feature_sets.

Return type

list

score(model, probe)[source]

Computes the score between the probe and the model.

Parameters
Returns

Value between 0 and 0.5, larger value means a better match

Return type

list[float]