PrincipalCurvature.py 3.1 KB
Newer Older
Pedro TOME's avatar
Pedro TOME committed
1 2 3 4
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :

import numpy
5

6
import bob.io.base
7

André Anjos's avatar
André Anjos committed
8
from bob.bio.base.extractor import Extractor
Pedro TOME's avatar
Pedro TOME committed
9

10 11
from scipy.ndimage import gaussian_filter

12

André Anjos's avatar
André Anjos committed
13
class PrincipalCurvature (Extractor):
14
    """MiuraMax feature extractor
15

16 17 18 19
    Based on J.H. Choi, W. Song, T. Kim, S.R. Lee and H.C. Kim, Finger vein
    extraction using gradient normalization and principal curvature. Proceedings
    on Image Processing: Machine Vision Applications II, SPIE 7251, (2009)
    """
20

21 22 23
    def __init__(
          self,
          sigma = 3, # Gaussian standard deviation applied
24
          threshold = 4, # Percentage of maximum used for hard thresholding
25 26 27 28 29 30 31 32 33 34 35 36 37
          ):
        """NOTE: In the reference paper where the size of the finger image is 320 by 128,
        the proposed values for sigma and threshold are 3 and 4, respectively.
        However, for other resolutions it is better to change the values for sigma and
        threshold. e.g., in UTFVP dataset where the size of the finger image is 672 by 380,
        sigma=6 and threshold=4 workes better results better features.
        """
        # call base class constructor
        Extractor.__init__(
            self,
            sigma = sigma,
            threshold = threshold,
            )
Pedro TOME's avatar
Pedro TOME committed
38

39 40 41
        # block parameters
        self.sigma = sigma
        self.threshold = threshold
42

43 44
    def ut_gauss(self, img, sigma, dx, dy):
        return gaussian_filter(numpy.float64(img), sigma, order = [dx,dy])
45 46


47 48 49
    def principal_curvature(self, image, mask):
        """Computes and returns the Maximum Curvature features for the given input
        fingervein image"""
50

51 52
        finger_mask = numpy.zeros(mask.shape)
        finger_mask[mask == True] = 1
53

54
        sigma = numpy.sqrt(self.sigma**2/2)
Pedro TOME's avatar
Pedro TOME committed
55

56 57
        gx = self.ut_gauss(image,self.sigma,1,0)
        gy = self.ut_gauss(image,self.sigma,0,1)
Pedro TOME's avatar
Pedro TOME committed
58

59
        Gmag = numpy.sqrt(gx**2 + gy**2) #  Gradient magnitude
Pedro TOME's avatar
Pedro TOME committed
60

61 62
        # Apply threshold
        gamma = (self.threshold/100)*numpy.max(Gmag)
63

64
        indices = numpy.where(Gmag < gamma)
65

66 67
        gx[indices] = 0
        gy[indices] = 0
Pedro TOME's avatar
Pedro TOME committed
68

69 70 71 72
        # Normalize
        Gmag[numpy.where(Gmag==0)] = 1  # Avoid dividing by zero
        gx = gx/Gmag
        gy = gy/Gmag
73

74 75 76
        hxx = self.ut_gauss(gx,sigma,1,0)
        hxy = self.ut_gauss(gx,sigma,0,1)
        hyy = self.ut_gauss(gy,sigma,0,1)
Pedro TOME's avatar
Pedro TOME committed
77 78


79 80
        lambda1 = 0.5*(hxx + hyy + numpy.sqrt(hxx**2 + hyy**2 - 2*hxx*hyy + 4*hxy**2))
        veins = lambda1*finger_mask
Pedro TOME's avatar
Pedro TOME committed
81

82 83 84
        # Normalise
        veins = veins - numpy.min(veins[:])
        veins = veins/numpy.max(veins[:])
Pedro TOME's avatar
Pedro TOME committed
85

86
        veins = veins*finger_mask
Pedro TOME's avatar
Pedro TOME committed
87

88

89 90 91
        # Binarise the vein image by otsu
        md = numpy.median(veins[veins>0])
        img_veins_bin = veins > md
Pedro TOME's avatar
Pedro TOME committed
92

93
        return img_veins_bin.astype(numpy.float64)
94 95


96 97 98
    def __call__(self, image):
        """Reads the input image, extract the features based on Principal Curvature
        of the fingervein image, and writes the resulting template"""
99

100 101
        finger_image = image[0]    #Normalized image with or without histogram equalization
        finger_mask = image[1]
102

103
        return self.principal_curvature(finger_image, finger_mask)