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

[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
This diff is collapsed.
......@@ -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
#TODO
return image_vein.astype(numpy.float64)
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')
......
......@@ -4,48 +4,46 @@
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 bob.bio.base.features.Extractor import Extractor
class MaximumCurvature (Extractor):
"""MiuraMax feature extractor 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)
"""MiuraMax feature extractor
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)
"""
def __init__(
self,
sigma = 2, # Gaussian standard deviation applied
threshold = 1.3, # Percentage of maximum used for hard thresholding
gpu = False
):
threshold = 1.3, # Percentage of maximum used for hard thresholding
gpu = False,
):
# call base class constructor
Extractor.__init__(
self,
sigma = sigma,
threshold = threshold,
gpu = gpu
)
gpu = gpu,
)
# block parameters
self.sigma = sigma
self.threshold = threshold
self.gpu = gpu
def principal_curvature(self, image, mask):
"""Computes and returns the Maximum Curvature features for the given input fingervein image"""
def principal_curvature(self, image, mask):
"""Computes and returns the Maximum Curvature features for the given input
fingervein image"""
finger_mask = numpy.zeros(mask.shape)
finger_mask[mask == True] = 1
finger_mask[mask == True] = 1
sigma = numpy.sqrt(self.sigma**2/2)
gx = ut_gauss(img,sigma,1,0)
......@@ -55,9 +53,9 @@ class MaximumCurvature (Extractor):
# Apply threshold
gamma = (self.threshold/100)*max(max(Gmag))
indices = find(Gmag < gamma)
gx[indices] = 0
gy[indices] = 0
......@@ -65,7 +63,7 @@ class MaximumCurvature (Extractor):
Gmag( find(Gmag == 0) ) = 1 # Avoid dividing by zero
gx = gx/Gmag
gy = gy/Gmag
hxx = ut_gauss(gx,sigma,1,0)
hxy = ut_gauss(gx,sigma,0,1)
hyy = ut_gauss(gy,sigma,0,1)
......@@ -80,31 +78,30 @@ class MaximumCurvature (Extractor):
veins = veins*finger_mask
# Binarise the vein image by otsu
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):
"""Reads the input image, extract the features based on Principal Curvature of the fingervein image, and writes the resulting template"""
def __call__(self, image):
"""Reads the input image, extract the features based on Principal 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.principal_curvature(finger_image, finger_mask)
finger_mask = image[1]
return self.principal_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
......@@ -2,24 +2,23 @@
# vim: set fileencoding=utf-8 :
# Pedro Tome <Pedro.Tome@idiap.ch>
import bob.core
import bob.io.base
import bob.ip.base
import numpy
import math
#from math import pi
#from mumpy import sqrt
import scipy.signal
import scipy
import scipy.misc
from facereclib.features.Extractor import Extractor
from .. import utils
from bob.bio.base.features.Extractor import Extractor
class WideLineDetector (Extractor):
"""Wide Line Detector feature extractor 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
"""Wide Line Detector feature extractor
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.
"""
def __init__(
......@@ -27,9 +26,8 @@ class WideLineDetector (Extractor):
radius = 5, #Radius of the circular neighbourhood region
threshold = 1, #Neigborhood threshold
g = 41, #Sum of neigbourhood threshold
rescale = True
):
rescale = True,
):
# call base class constructor
Extractor.__init__(
......@@ -37,9 +35,9 @@ class WideLineDetector (Extractor):
radius = radius,
threshold = threshold,
g = g,
rescale = rescale
)
rescale = rescale,
)
# block parameters
self.radius = radius
self.threshold = threshold
......@@ -48,13 +46,14 @@ class WideLineDetector (Extractor):
def wide_line_detector(self, finger_image, mask):
"""Computes and returns the Wide Line Detector features for the given input fingervein image"""
finger_image = finger_image.astype(numpy.float64)
"""Computes and returns the Wide Line Detector features for the given input
fingervein image"""
finger_image = finger_image.astype(numpy.float64)
finger_mask = numpy.zeros(mask.shape)
finger_mask[mask == True] = 1
finger_mask[mask == True] = 1
# Rescale image if required
if self.rescale == True:
scaling_factor = 0.24
......@@ -68,40 +67,42 @@ class WideLineDetector (Extractor):
x = numpy.arange((-1)*self.radius, self.radius+1)
y = numpy.arange((-1)*self.radius, self.radius+1)
X, Y = numpy.meshgrid(x,y)
N = X**2 + Y**2 <= self.radius**2 # Neighbourhood mask
img_h, img_w = finger_image.shape #Image height and width
img_h, img_w = finger_image.shape #Image height and width
veins = numpy.zeros(finger_image.shape)
for y in range(self.radius,img_h-self.radius):
for x in range(self.radius,img_w-self.radius):
for y in range(self.radius,img_h-self.radius):
for x in range(self.radius,img_w-self.radius):
s=((finger_image[y-self.radius:y+self.radius+1,x-self.radius:x+self.radius+1] - finger_image[y,x]) <= self.threshold)
m = (s*N).sum()
veins[y,x] = float(m <= self.g)
# Mask the vein image with the finger region
img_veins_bin = veins*finger_mask
return img_veins_bin
def __call__(self, image):
"""Reads the input image, extract the features based on Wide Line Detector of the fingervein image, and writes the resulting template"""
#For debugging
def __call__(self, image):
"""Reads the input image, extract the features based on Wide Line Detector
of the fingervein image, and writes the resulting template"""
#For debugging
finger_image = image[0] #Normalized image with histogram equalization
finger_mask = image[1]
return self.wide_line_detector(finger_image, finger_mask)
finger_mask = image[1]
return self.wide_line_detector(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)
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
"""Feature Extraction"""
from NormalisedCrossCorrelation import NormalisedCrossCorrelation
from MaximumCurvature import MaximumCurvature
from RepeatedLineTracking import RepeatedLineTracking
from WideLineDetector import WideLineDetector
from LocalBinaryPatterns import LocalBinaryPatterns
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Pedro Tome <Pedro.Tome@idiap.ch>
import numpy.random
import scipy.ndimage
import numpy
import scipy.signal
import bob.ip.base
import bob.sp
......@@ -12,23 +10,21 @@ import bob.core
def imfilter(a, b, gpu=False, conv=True):
"""imfilter function based on MATLAB implementation."""
if (a.dtype == numpy.uint8):
a= bob.core.convert(a,numpy.float64,(0,1))
a= bob.core.convert(a,numpy.float64,(0,1))
M, N = a.shape
if conv == True:
b = bob.ip.base.rotate(b, 180)
b = bob.ip.base.rotate(b, 180)
shape = numpy.array((0,0))
shape[0] = a.shape[0] + b.shape[0] - 1
shape[1] = a.shape[1] + b.shape[1] - 1
a_ext = numpy.ndarray(shape=shape, dtype=numpy.float64)
bob.sp.extrapolate_nearest(a, a_ext)
if gpu == True:
import xbob.cusp
return xbob.cusp.conv(a_ext, b)
else:
return scipy.signal.convolve2d(a_ext, b, 'valid')
#return = self.convfft(a_ext, b)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment