Fix LBP variance calculation.

This commit is contained in:
Pietro Berkes
2014-04-01 21:06:15 +01:00
parent a21dca6a77
commit 1a909cbc79
2 changed files with 38 additions and 24 deletions
+22 -10
View File
@@ -129,6 +129,9 @@ def _local_binary_pattern(double[:, ::1] image,
cdef Py_ssize_t rot_index, n_ones
cdef cnp.int8_t first_zero, first_one
# To compute the variance features
cdef double sum_, var_, texture_i
for r in range(image.shape[0]):
for c in range(image.shape[1]):
for i in range(P):
@@ -144,8 +147,24 @@ def _local_binary_pattern(double[:, ::1] image,
lbp = 0
# if method == 'uniform' or method == 'var':
if method == 'U' or method == 'N' or method == 'V':
# if method == 'var':
if method == 'V':
# Compute the variance without passing from numpy.
# Following the LBP paper, we're taking a biased estimate
# of the variance (ddof=0)
sum_ = 0.0
var_ = 0.0
for i in range(P):
texture_i = texture[i]
sum_ += texture_i
var_ += texture_i * texture_i
var_ = (var_ - (sum_ * sum_) / P) / P
if var_ != 0:
lbp = var_
else:
lbp = np.nan
# if method == 'uniform':
elif method == 'U' or method == 'N':
# determine number of 0 - 1 changes
changes = 0
for i in range(P - 1):
@@ -186,7 +205,7 @@ def _local_binary_pattern(double[:, ::1] image,
if changes <= 2:
# We have a uniform pattern
n_ones = 0 # determies the number of ones
n_ones = 0 # determines the number of ones
first_one = -1 # position was the first one
first_zero = -1 # position of the first zero
for i in range(P):
@@ -215,13 +234,6 @@ def _local_binary_pattern(double[:, ::1] image,
lbp += signed_texture[i]
else:
lbp = P + 1
if method == 'V':
var = np.var(texture)
if var != 0:
lbp /= var
else:
lbp = np.nan
else:
# method == 'default'
for i in range(P):
+16 -14
View File
@@ -183,21 +183,23 @@ class TestLBP():
np.testing.assert_array_equal(lbp, ref)
def test_var(self):
lbp = local_binary_pattern(self.image, 8, 1, 'var')
ref = np.array([[0. , 0.00072786, 0. , 0.00115377,
0.00032355, 0.00224467],
[0.00051758, 0. , 0.0026383 , 0.00163246,
0.00027414, 0.00041124],
[0.00192834, 0.00130368, 0.00042095, 0.00171894,
0. , 0.00063726],
[0.00023048, 0.00019464 , 0.00082291, 0.00225386,
0.00076696, 0. ],
[0.00097253, 0.00013236, 0.0009134 , 0.0014467 ,
0. , 0.00082472],
[0.00024701, 0.0012277 , 0. , 0.00109869,
0.00015445, 0.00035881]])
np.testing.assert_array_almost_equal(lbp, ref)
# Test idea: mean of variance is estimate of overall variance.
target_std = 0.3
image = np.random.random((500, 500))
image = image / image.std() * target_std
# Use P=4 to avoid interpolation effects
P, R = 4, 1
lbp = local_binary_pattern(image, P, R, 'var')
# Take central part to avoid border effect.
lbp = lbp[5:-5,5:-5]
# The LBP variance is biased (ddof=0), correct for that.
expected = target_std**2 * (P-1)/P
np.testing.assert_almost_equal(lbp[10:-10,10:-10].mean(),
expected, 4)
def test_nri_uniform(self):
lbp = local_binary_pattern(self.image, 8, 1, 'nri_uniform')