MiuraMatch.py 3.98 KB
 Pedro TOME committed Mar 09, 2015 1 2 3 4 5 6 ``````#!/usr/bin/env python # vim: set fileencoding=utf-8 : import numpy import scipy.signal `````` André Anjos committed Nov 08, 2016 7 ``````import bob.ip.base `````` André Anjos committed Jul 11, 2016 8 ``````from bob.bio.base.algorithm import Algorithm `````` Pedro TOME committed Mar 09, 2015 9 `````` `````` André Anjos committed Jul 11, 2016 10 11 `````` class MiuraMatch (Algorithm): `````` André Anjos committed Nov 08, 2016 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 `````` """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), to evaluate 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 :math:`[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** erosion 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 eroded model image and the matching pixels on the probe that yield the maximum on the resulting convolution. `````` André Anjos committed Jul 11, 2016 33 34 35 36 37 `````` 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 `````` André Anjos committed Sep 27, 2016 38 `````` `````` André Anjos committed Nov 07, 2016 39 `````` Parameters: `````` André Anjos committed Sep 27, 2016 40 `````` `````` André Anjos committed Nov 08, 2016 41 `````` ch (:py:class:`int`, optional): Maximum search displacement in y-direction. `````` André Anjos committed Nov 07, 2016 42 `````` `````` André Anjos committed Nov 08, 2016 43 `````` cw (:py:class:`int`, optional): Maximum search displacement in x-direction. `````` André Anjos committed Sep 27, 2016 44 `````` `````` Pedro TOME committed Mar 09, 2015 45 46 `````` """ `````` André Anjos committed Jul 11, 2016 47 `````` def __init__(self, `````` Pedro TOME committed Mar 09, 2015 48 49 `````` ch = 8, # Maximum search displacement in y-direction cw = 5, # Maximum search displacement in x-direction `````` André Anjos committed Jul 11, 2016 50 `````` ): `````` Pedro TOME committed Mar 09, 2015 51 52 `````` # call base class constructor `````` André Anjos committed Jul 11, 2016 53 `````` Algorithm.__init__( `````` Pedro TOME committed Mar 09, 2015 54 55 56 57 58 59 60 61 62 63 64 65 `````` self, ch = ch, cw = cw, multiple_model_scoring = None, multiple_probe_scoring = None ) self.ch = ch self.cw = cw `````` André Anjos committed Jul 11, 2016 66 `````` `````` Pedro TOME committed Mar 09, 2015 67 68 `````` def enroll(self, enroll_features): """Enrolls the model by computing an average graph for each model""" `````` André Anjos committed Jul 11, 2016 69 `````` `````` Pedro TOME committed Mar 09, 2015 70 71 72 73 `````` # return the generated model return numpy.array(enroll_features) `````` André Anjos committed Nov 08, 2016 74 75 `````` def score(self, model, probe): """Computes the score between the probe and the model. `````` André Anjos committed Jul 11, 2016 76 `````` `````` André Anjos committed Nov 08, 2016 77 `````` Parameters: `````` André Anjos committed Jul 11, 2016 78 `````` `````` André Anjos committed Nov 08, 2016 79 `````` model (numpy.ndarray): The model of the user to test the probe agains `````` André Anjos committed Jul 11, 2016 80 `````` `````` André Anjos committed Nov 08, 2016 81 `````` probe (numpy.ndarray): The probe to test `````` Pedro TOME committed Mar 09, 2015 82 83 `````` `````` André Anjos committed Nov 08, 2016 84 `````` Returns: `````` Olegs NIKISINS committed Oct 06, 2016 85 `````` `````` André Anjos committed Nov 08, 2016 86 `````` score (float): Value between 0 and 0.5, larger value means a better match `````` Olegs NIKISINS committed Oct 06, 2016 87 `````` `````` Pedro TOME committed Mar 09, 2015 88 `````` """ `````` André Anjos committed Jul 11, 2016 89 `````` `````` Pedro TOME committed Mar 09, 2015 90 `````` I=probe.astype(numpy.float64) `````` André Anjos committed Jul 11, 2016 91 92 `````` if len(model.shape) == 2: `````` Pedro TOME committed Mar 09, 2015 93 `````` model = numpy.array([model]) `````` André Anjos committed Jul 11, 2016 94 `````` `````` Pedro TOME committed Mar 09, 2015 95 96 97 `````` n_models = model.shape[0] scores = [] `````` André Anjos committed Nov 08, 2016 98 `````` `````` Pedro TOME committed Mar 09, 2015 99 `````` for i in range(n_models): `````` André Anjos committed Nov 08, 2016 100 101 `````` # erode model by (ch, cw) `````` Pedro TOME committed Mar 09, 2015 102 103 104 `````` R=model[i,:].astype(numpy.float64) h, w = R.shape crop_R = R[self.ch:h-self.ch, self.cw:w-self.cw] `````` André Anjos committed Nov 08, 2016 105 106 `````` # rotate input image `````` Pedro TOME committed Mar 09, 2015 107 108 `````` rotate_R = numpy.zeros((crop_R.shape[0], crop_R.shape[1])) bob.ip.base.rotate(crop_R, rotate_R, 180) `````` André Anjos committed Jul 11, 2016 109 `````` `````` André Anjos committed Nov 08, 2016 110 111 112 113 114 `````` # convolve model and probe using FFT/IFFT. #Nm = utils.convfft(I, rotate_R) #drop-in replacement for scipy method Nm = scipy.signal.convolve2d(I, rotate_R, 'valid') # figures out where the maximum is on the resulting matrix `````` Pedro TOME committed Mar 09, 2015 115 `````` t0, s0 = numpy.unravel_index(Nm.argmax(), Nm.shape) `````` André Anjos committed Nov 08, 2016 116 117 `````` # this is our output `````` Pedro TOME committed Mar 09, 2015 118 `````` Nmm = Nm[t0,s0] `````` André Anjos committed Nov 08, 2016 119 120 121 122 `````` # normalizes the output by the number of pixels lit on the input # matrices, taking into consideration the surface that produced the # result (i.e., the eroded model and part of the probe) `````` Pedro TOME committed Mar 09, 2015 123 `````` scores.append(Nmm/(sum(sum(crop_R)) + sum(sum(I[t0:t0+h-2*self.ch, s0:s0+w-2*self.cw])))) `````` André Anjos committed Jul 11, 2016 124 `````` `````` Pedro TOME committed Mar 09, 2015 125 `` return numpy.mean(scores)``