Commit ef93bd8e by André Anjos

Merge branch 'add_hamming_dist' into 'master'

Fix Hamming Distance module See merge request !37
parents 700025b3 ba79af1b
Pipeline #13273 passed with stages
in 17 minutes 59 seconds
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
import bob.ip.base
import numpy
import scipy.signal
from bob.bio.base.algorithm import Distance
import scipy.spatial.distance
from bob.bio.base.algorithm import Algorithm
class HammingDistance (Distance):
"""This class calculates the Hamming distance between two binary images.
Each binary image is first flattened by concatenating its rows to form a one-dimensional vector. The Hamming distance is then calculated between the two binary vectors.
The Hamming distance is computed using :py:func:`scipy.spatial.distance.hamming`, which returns a scalar ``float`` to represent the proportion of mismatching corresponding bits between the two binary vectors.
**Parameters:**
``distance_function`` : function
Set this parameter to ``scipy.spatial.distance.hamming`` to ensure we are calculating the Hamming distance
``is_distance_function`` : bool
Set this flag to ``False`` to ensure that Hamming distances are returned as positive values rather than negative
class HammingDistance (Algorithm):
"""Finger vein matching: hamming distance
"""
def __init__(
self,
# some similarity functions might need a GaborWaveletTransform class, so we have to provide the parameters here as well...
ch = 8, # Maximum search displacement in y-direction
cw = 5, # Maximum search displacement in x-direction
distance_function = scipy.spatial.distance.hamming,
is_distance_function = False # setting this to False ensures that Hamming distances are returned as positive values rather than negative
):
# call base class constructor
Algorithm.__init__(
# Call base class constructor
Distance.__init__(
self,
ch = ch,
cw = cw,
multiple_model_scoring = None,
multiple_probe_scoring = None
)
self.ch = ch
self.cw = cw
def enroll(self, enroll_features):
"""Enrolls the model by computing an average graph for each model"""
# return the generated model
return numpy.vstack(enroll_features)
def score(self, model, probe):
"""Computes the score of the probe and the model
Return score - Value between 0 and 0.5, larger value is better match
"""
I=probe.astype(numpy.float64)
R=model.astype(numpy.float64)
h, w = R.shape
crop_R = R[self.ch:h-self.ch, self.cw:w-self.cw]
rotate_R = numpy.zeros((crop_R.shape[0], crop_R.shape[1]))
bob.ip.base.rotate(crop_R, rotate_R, 180)
#FFT for scoring!
#Nm=bob.sp.ifft(bob.sp.fft(I)*bob.sp.fft(rotate_R))
Nm = scipy.signal.convolve2d(I, rotate_R, 'valid');
t0, s0 = numpy.unravel_index(Nm.argmax(), Nm.shape)
Nmm = Nm[t0,s0]
#Nmm = Nm.max()
#mi = numpy.argwhere(Nmm == Nm)
#t0, s0 = mi.flatten()[:2]
score = Nmm/(sum(sum(crop_R)) + sum(sum(I[t0:t0+h-2*self.ch, s0:s0+w-2*self.cw])))
return score
distance_function = distance_function,
is_distance_function = is_distance_function
)
\ No newline at end of file
......@@ -685,3 +685,26 @@ def test_correlation():
total = time.clock() - start
print('scipy+correlate2d, %d iterations - %.2e per iteration' % (N, total/N))
'''
def test_hamming_distance():
from ..algorithm.HammingDistance import HammingDistance
HD = HammingDistance()
# Tests on simple binary arrays:
# 1.) Maximum HD (1.0):
model_1 = numpy.array([0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0])
probe_1 = numpy.array([[1, 0, 0, 0, 1, 0], [0, 1, 1, 1, 0, 1]])
score_max = HD.score(model_1, probe_1)
assert score_max == 1.0
# 2.) Minimum HD (0.0):
model_2 = numpy.array([0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1])
probe_2 = numpy.array([[0, 1, 1, 1, 0, 1], [0, 1, 1, 1, 0, 1]])
score_min = HD.score(model_2, probe_2)
assert score_min == 0.0
# 3.) HD of exactly half (0.5)
model_3 = numpy.array([0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0])
probe_3 = numpy.array([[0, 1, 1, 1, 0, 1], [0, 1, 1, 1, 0, 1]])
score_half = HD.score(model_3, probe_3)
assert score_half == 0.5
\ No newline at end of file
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