Commit 331df584 authored by André Anjos's avatar André Anjos 💬
Browse files

[extractors] Porting and cleanup

parent ebc2f696
#!/usr/bin/env python
# Pedro Tome <Pedro.Tome@idiap.ch>
import configurations
import tools
import preprocessing
import features
import tests
import script
#import utils
# vim: set fileencoding=utf-8 :
def get_config():
"""Returns a string containing the configuration information.
"""
import pkg_resources
packages = pkg_resources.require(__name__)
this = packages[0]
deps = packages[1:]
retval = "%s: %s (%s)\n" % (this.key, this.version, this.location)
retval += " - python dependencies:\n"
for d in deps: retval += " - %s: %s (%s)\n" % (d.key, d.version, d.location)
return retval.strip()
import bob.extension
return bob.extension.get_config(__name__)
# gets sphinx autodoc done right - don't remove it
__all__ = [_ for _ in dir() if not _.startswith('_')]
......@@ -5,18 +5,14 @@
import bob.ip.base
import bob.io.base
import numpy
import math
#from math import pi
#from mumpy import sqrt
import scipy.signal
from facereclib.features.Extractor import Extractor
from .. import utils
#from facereclib.utils import histogram
from bob.bio.base.features.Extractor import Extractor
class LocalBinaryPatterns (Extractor):
"""LBP feature extractor, paramters fixed based on
L. Mirmohamadsadeghi and A. Drygajlo. Palm vein recognition uisng local texture patterns, IET Biometrics, pp. 1-9, 2013.
"""LBP feature extractor
Parameters fixed based on L. Mirmohamadsadeghi and A. Drygajlo. Palm vein
recognition uisng local texture patterns, IET Biometrics, pp. 1-9, 2013.
"""
def __init__(
......@@ -34,9 +30,8 @@ class LocalBinaryPatterns (Extractor):
lbp_add_average = False,
# histogram options
sparse_histogram = False,
split_histogram = None
):
split_histogram = None,
):
# call base class constructor
Extractor.__init__(
......@@ -53,15 +48,15 @@ class LocalBinaryPatterns (Extractor):
lbp_compare_to_average = lbp_compare_to_average,
lbp_add_average = lbp_add_average,
sparse_histogram = sparse_histogram,
split_histogram = split_histogram
)
split_histogram = split_histogram,
)
# block parameters
self.m_block_size = block_size if isinstance(block_size, (tuple, list)) else (block_size, block_size)
self.m_block_overlap = block_overlap if isinstance(block_overlap, (tuple, list)) else (block_overlap, block_overlap)
if self.m_block_size[0] < self.m_block_overlap[0] or self.m_block_size[1] < self.m_block_overlap[1]:
raise ValueError("The overlap is bigger than the block size. This won't work. Please check your setup!")
self.m_lbp = bob.ip.base.LBP(
neighbors = lbp_neighbor_count,
radius = float(lbp_radius),
......@@ -70,76 +65,78 @@ class LocalBinaryPatterns (Extractor):
add_average_bit = lbp_add_average,
uniform = lbp_uniform,
rotation_invariant = lbp_rotation_invariant,
border_handling = 'wrap'
)
border_handling = 'wrap',
)
self.m_split = split_histogram
self.m_sparse = sparse_histogram
if self.m_sparse and self.m_split:
raise ValueError("Sparse histograms cannot be split! Check your setup!")
raise ValueError("Sparse histograms cannot be split! Check your setup.")
def __fill__(self, lbphs_array, lbphs_blocks, j):
"""Copies the given array into the given blocks"""
# fill array in the desired shape
#For debugging
#import ipdb; ipdb.set_trace()
#For debugging
#import ipdb; ipdb.set_trace()
for b in range(self.m_n_blocks):
lbphs_array[b * self.m_n_bins : (b+1) * self.m_n_bins] = lbphs_blocks[b][:]
def lbp_features(self, finger_image, mask):
"""Computes and returns the LBP features for the given input fingervein image"""
# For debugging
#import ipdb; ipdb.set_trace()
"""Computes and returns the LBP features for the given input fingervein
image"""
# For debugging
#import ipdb; ipdb.set_trace()
finger_image = finger_image.astype(numpy.float64)
finger_mask = numpy.zeros(mask.shape)
finger_mask[mask == True] = 1
finger_mask[mask == True] = 1
# Mask the vein image with the finger region
finger_image = finger_image*finger_mask
finger_image = finger_image*finger_mask
# Computes LBP histograms
abs_blocks = bob.ip.base.lbphs(finger_image, self.m_lbp, self.m_block_size, self.m_block_overlap)
# Converts to Blitz array (of different dimensionalities)
self.m_n_bins = abs_blocks.shape[1]
self.m_n_blocks = abs_blocks.shape[0]
shape = self.m_n_bins * self.m_n_blocks
# create new array
# create new array
lbphs_array = numpy.zeros(shape, 'float64')
#For debugging
#import ipdb; ipdb.set_trace()
#For debugging
#import ipdb; ipdb.set_trace()
# fill the array with the absolute values of the Gabor wavelet transform
self.__fill__(lbphs_array, abs_blocks, 0)
# return the concatenated list of all histograms
return lbphs_array
def __call__(self, image):
def __call__(self, image):
"""Reads the input image, extract the features based on LBP of the fingervein image, and writes the resulting template"""
#For debugging
#For debugging
finger_image = image[0] #Normalized image with histogram equalization
finger_mask = image[1]
return self.lbp_features(finger_image, finger_mask)
finger_mask = image[1]
return self.lbp_features(finger_image, finger_mask)
def save_feature(self, feature, feature_file):
f = bob.io.base.HDF5File(feature_file, 'w')
f.set('feature', feature)
def read_feature(self, feature_file):
f = bob.io.base.HDF5File(feature_file, 'r')
image = f.read('feature')
return (image)
\ No newline at end of file
return image
......@@ -2,25 +2,26 @@
# vim: set fileencoding=utf-8 :
# Pedro Tome <Pedro.Tome@idiap.ch>
import math
import numpy
import bob.core
import bob.io.base
import numpy
import math
#from math import pi
#from mumpy import sqrt
import scipy.signal
from facereclib.features.Extractor import Extractor
from bob.bio.base.features.Extractor import Extractor
from .. import utils
class MaximumCurvature (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
"""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
"""
def __init__(
self,
sigma = 5, #Sigma used for determining derivatives
......@@ -33,65 +34,66 @@ class MaximumCurvature (Extractor):
sigma = sigma,
gpu = gpu
)
# block parameters
self.sigma = sigma
self.gpu = gpu
def maximum_curvature(self, image, mask):
"""Computes and returns the Maximum Curvature features for the given input fingervein image"""
def maximum_curvature(self, image, mask):
"""Computes and returns the Maximum Curvature features for the given input
fingervein image"""
if image.dtype != numpy.uint8:
image = bob.core.convert(image,numpy.uint8,(0,255),(0,1))
#No es necesario pasarlo a uint8, en matlab lo dejan en float64. Comprobar si varian los resultados en vera database y ajustar.
finger_mask = numpy.zeros(mask.shape)
finger_mask[mask == True] = 1
finger_mask[mask == True] = 1
winsize = numpy.ceil(4*self.sigma)
x = numpy.arange(-winsize, winsize+1)
y = numpy.arange(-winsize, winsize+1)
X, Y = numpy.meshgrid(x, y)
h = (1/(2*math.pi*self.sigma**2))*numpy.exp(-(X**2 + Y**2)/(2*self.sigma**2))
hx = (-X/(self.sigma**2))*h
hxx = ((X**2 - self.sigma**2)/(self.sigma**4))*h
hy = hx.T
hyy = hxx.T
hxy = ((X*Y)/(self.sigma**4))*h
# Do the actual filtering
fx = utils.imfilter(image, hx, self.gpu, conv=False)
fxx = utils.imfilter(image, hxx, self.gpu, conv=False)
fy = utils.imfilter(image, hy, self.gpu, conv=False)
fyy = utils.imfilter(image, hyy, self.gpu, conv=False)
fxy = utils.imfilter(image, hxy, self.gpu, conv=False)
f1 = 0.5*numpy.sqrt(2)*(fx + fy) # \ #
f2 = 0.5*numpy.sqrt(2)*(fx - fy) # / #
f11 = 0.5*fxx + fxy + 0.5*fyy # \\ #
f22 = 0.5*fxx - fxy + 0.5*fyy # // #
img_h, img_w = image.shape #Image height and width
# Calculate curvatures
k = numpy.zeros((img_h, img_w, 4))
k[:,:,0] = (fxx/((1 + fx**2)**(3/2)))*finger_mask # hor #
k[:,:,1] = (fyy/((1 + fy**2)**(3/2)))*finger_mask # ver #
k[:,:,2] = (f11/((1 + f1**2)**(3/2)))*finger_mask # \ #
k[:,:,3] = (f22/((1 + f2**2)**(3/2)))*finger_mask # / #
# Scores
Vt = numpy.zeros(image.shape)
Wr = 0
# Horizontal direction
bla = k[:,:,0] > 0
for y in range(0,img_h):
for x in range(0,img_w):
for y in range(0,img_h):
for x in range(0,img_w):
if (bla[y,x]):
Wr = Wr + 1
if ( Wr > 0 and (x == (img_w-1) or not bla[y,x]) ):
......@@ -100,23 +102,23 @@ class MaximumCurvature (Extractor):
pos_end = x
else:
pos_end = x - 1
pos_start = pos_end - Wr + 1 # Start pos of concave
pos_start = pos_end - Wr + 1 # Start pos of concave
if (pos_start == pos_end):
I=numpy.argmax(k[y,pos_start,0])
else:
else:
I=numpy.argmax(k[y,pos_start:pos_end+1,0])
pos_max = pos_start + I
Scr = k[y,pos_max,0]*Wr
Vt[y,pos_max] = Vt[y,pos_max] + Scr
Wr = 0
Wr = 0
# Vertical direction
bla = k[:,:,1] > 0
for x in range(0,img_w):
for y in range(0,img_h):
for x in range(0,img_w):
for y in range(0,img_h):
if (bla[y,x]):
Wr = Wr + 1
if ( Wr > 0 and (y == (img_h-1) or not bla[y,x]) ):
......@@ -124,20 +126,20 @@ class MaximumCurvature (Extractor):
# Reached edge of image
pos_end = y
else:
pos_end = y - 1
pos_end = y - 1
pos_start = pos_end - Wr + 1 # Start pos of concave
if (pos_start == pos_end):
I=numpy.argmax(k[pos_start,x,1])
else:
I=numpy.argmax(k[pos_start:pos_end+1,x,1])
pos_max = pos_start + I
pos_max = pos_start + I
Scr = k[pos_max,x,1]*Wr
Vt[pos_max,x] = Vt[pos_max,x] + Scr
Wr = 0
# Direction: \ #
bla = k[:,:,2] > 0
for start in range(0,img_w+img_h-1):
......@@ -149,11 +151,11 @@ class MaximumCurvature (Extractor):
x = 0
y = start - img_w + 1
done = False
while (not done):
if(bla[y,x]):
Wr = Wr + 1
if ( Wr > 0 and (y == img_h-1 or x == img_w-1 or not bla[y,x]) ):
if (y == img_h-1 or x == img_w-1):
# Reached edge of image
......@@ -162,10 +164,10 @@ class MaximumCurvature (Extractor):
else:
pos_x_end = x - 1
pos_y_end = y - 1
pos_x_start = pos_x_end - Wr + 1
pos_y_start = pos_y_end - Wr + 1
if (pos_y_start == pos_y_end and pos_x_start == pos_x_end):
d = k[pos_y_start, pos_x_start, 2]
elif (pos_y_start == pos_y_end):
......@@ -174,23 +176,23 @@ class MaximumCurvature (Extractor):
d = numpy.diag(k[pos_y_start:pos_y_end+1, pos_x_start, 2])
else:
d = numpy.diag(k[pos_y_start:pos_y_end+1, pos_x_start:pos_x_end+1, 2])
I = numpy.argmax(d)
pos_x_max = pos_x_start + I
pos_y_max = pos_y_start + I
I = numpy.argmax(d)
pos_x_max = pos_x_start + I
pos_y_max = pos_y_start + I
Scr = k[pos_y_max,pos_x_max,2]*Wr
Vt[pos_y_max,pos_x_max] = Vt[pos_y_max,pos_x_max] + Scr
Wr = 0
if((x == img_w-1) or (y == img_h-1)):
done = True
else:
x = x + 1
y = y + 1
# Direction: /
bla = k[:,:,3] > 0
for start in range(0,img_w+img_h-1):
......@@ -202,7 +204,7 @@ class MaximumCurvature (Extractor):
x = 0
y = img_w+img_h-start-1
done = False
while (not done):
if(bla[y,x]):
Wr = Wr + 1
......@@ -214,10 +216,10 @@ class MaximumCurvature (Extractor):
else:
pos_x_end = x - 1
pos_y_end = y + 1
pos_x_start = pos_x_end - Wr + 1
pos_y_start = pos_y_end + Wr - 1
if (pos_y_start == pos_y_end and pos_x_start == pos_x_end):
d = k[pos_y_end, pos_x_start, 3]
elif (pos_y_start == pos_y_end):
......@@ -226,19 +228,19 @@ class MaximumCurvature (Extractor):
d = numpy.diag(numpy.flipud(k[pos_y_end:pos_y_start+1, pos_x_start, 3]))
else:
d = numpy.diag(numpy.flipud(k[pos_y_end:pos_y_start+1, pos_x_start:pos_x_end+1, 3]))
I = numpy.argmax(d)
pos_x_max = pos_x_start + I
pos_y_max = pos_y_start - I
I = numpy.argmax(d)
pos_x_max = pos_x_start + I
pos_y_max = pos_y_start - I
Scr = k[pos_y_max,pos_x_max,3]*Wr
Vt[pos_y_max,pos_x_max] = Vt[pos_y_max,pos_x_max] + Scr
Wr = 0
if((x == img_w-1) or (y == 0)):
done = True
else:
x = x + 1
y = y - 1
y = y - 1
## Connection of vein centres
Cd = numpy.zeros((img_h, img_w, 4))
......@@ -248,34 +250,31 @@ class MaximumCurvature (Extractor):
Cd[y,x,1] = min(numpy.amax(Vt[y+1:y+3,x]), numpy.amax(Vt[y-2:y,x])) # Vert #
Cd[y,x,2] = min(numpy.amax(Vt[y-2:y,x-2:x]), numpy.amax(Vt[y+1:y+3,x+1:x+3])) # \ #
Cd[y,x,3] = min(numpy.amax(Vt[y+1:y+3,x-2:x]), numpy.amax(Vt[y-2:y,x+1:x+3])) # / #
#Veins
img_veins = numpy.amax(Cd,axis=2)
# Binarise the vein image
md = numpy.median(img_veins[img_veins>0])
img_veins_bin = img_veins > md
return img_veins_bin.astype(numpy.float64)
def __call__(self, image):
def __call__(self, image):
"""Reads the input image, extract the features based on Maximum Curvature of the fingervein image, and writes the resulting template"""
finger_image = image[0] #Normalized image with or without histogram equalization
finger_mask = image[1]
return self.maximum_curvature(finger_image, finger_mask)
finger_mask = image[1]
return self.maximum_curvature(finger_image, finger_mask)
def save_feature(self, feature, feature_file):
f = bob.io.base.HDF5File(feature_file, 'w')
f.set('feature', feature)
def read_feature(self, feature_file):
f = bob.io.base.HDF5File(feature_file, 'r')
image = f.read('feature')
return (image)
\ No newline at end of file
return image
......@@ -2,48 +2,44 @@
# vim: set fileencoding=utf-8 :
# Pedro Tome <Pedro.Tome@idiap.ch>
import bob.core
import numpy
import bob.io.base
import numpy
from facereclib.features.Extractor import Extractor
from bob.bio.base.features.Extractor import Extractor
class NormalisedCrossCorrelation (Extractor):
"""Normalised Cross-Correlation feature extractor based on
M. Kono, H. Ueki, and S.Umemura. Near-infrared finger vein patterns for personal
identification. Appl. Opt. 41(35):7429-7436, 2002
"""Normalised Cross-Correlation feature extractor
Based on M. Kono, H. Ueki, and S.Umemura. Near-infrared finger vein patterns
for personal identification. Appl. Opt. 41(35):7429-7436, 2002
"""
def __init__(
self,
):
# call base class constructor
Extractor.__init__(
self,
)
# block parameters
def __call__(self, image, mask):
"""Reads the input image, extract the features based on Normalised Cross-Correlation of the fingervein image, and writes the resulting template"""
def __init__(self):
Extractor.__init__(self)
def __call__(self, image, mask):
"""Reads the input image, extract the features based on Normalised
Cross-Correlation of the fingervein image, and writes the resulting
template"""
finger_image = image #Normalized image with histogram equalization
finger_mask = mask
image_vein = finger_image*finger_mask
#TODO
return image_vein.astype(numpy.float64)
finger_mask = mask
image_vein = finger_image*finger_mask