Commit 3f17cb4d authored by Rakesh MEHTA's avatar Rakesh MEHTA
Browse files

Block LBP feature test and comments added.

parent 8be36d81
File added
......@@ -95,6 +95,7 @@ setup(
'mnist_onevsall.py = xbob.boosting.scripts.mnist_onevsall:main',
'mnist_onevsall_lbp.py = xbob.boosting.scripts.mnist_onevsall_lbp:main',
'mnist_onevsall_block_lbp.py = xbob.boosting.scripts.mnist_onevsall_block_lbp:main',
'mnist_multi_block_lbp.py = xbob.boosting.scripts.mnist_multi_block_lbp:main',
],
# tests that are _exported_ (that can be executed by other packages) can
......
......@@ -7,7 +7,6 @@ features. """
import numpy
import math
class lbp_feature():
......@@ -28,7 +27,7 @@ class lbp_feature():
self.ftype = ftype
def integral_img(self,img):
def compute_integral_image(self,img):
"""The function cumputes an intergal image for the given image.
The function computes the intergral image for the effecient computation of the block based features.
......@@ -39,11 +38,11 @@ class lbp_feature():
return:
int_img: The intergal image of the input image."""
integral_x = numpy.cumsum(img,0)
integral_img = numpy.cumsum(integral_x,1)
return integral_img
integral_y = numpy.cumsum(img,0)
integral_xy = numpy.cumsum(integral_y,1)
return integral_xy
def get_features(self,img,cx,cy):
def get_features(self, img, scale_max_x, scale_max_y):
"""The function computes the block based local features at different scales.
The function extracts the block based local features at multiple scales from the image. The scale refers to
......@@ -58,48 +57,50 @@ class lbp_feature():
cy: The maximum rows for the block
Return:
fvec: The concatenated feature vectors for all the scales."""
# Compute the intergal image and add zeros along row and col for block processing
int_imgc = self.integral_img(img)
feature_vector: The concatenated feature vectors for all the scales."""
# Compute the intergal image and pad zeros along row and col for block processing
integral_imgc = self.compute_integral_image(img)
rows, cols = img.shape
int_img = numpy.zeros([rows+1,cols+1])
int_img[1:,1:] = int_imgc
integral_img = numpy.zeros([rows+1,cols+1])
integral_img[1:,1:] = integral_imgc
# initialize
num_neighbours = 8
coord = [[0,0],[0,1],[0,2],[1,2],[2,2],[2,1],[2,0],[1,0]]
fvec = numpy.empty(0, dtype = 'uint8')
feature_vector = numpy.empty(0, dtype = 'uint8')
# Vary the scale of the block and compute features
for xi in range(cx):
for yi in range(cy):
for scale_x in range(scale_max_x):
for scale_y in range(scale_max_y):
# Compute the sum of the blocks for the current scale
blk_int = int_img[yi+1:,xi+1:] + int_img[0:-(yi+1),0:-(xi+1)] - int_img[yi+1:,0:-(xi+1)] - int_img[0:-(yi+1),xi+1:]
block_sum = integral_img[scale_y+1:,scale_x+1:] + integral_img[0:-(scale_y+1),0:-(scale_x+1)] - integral_img[scale_y+1:,0:-(scale_x+1)] - integral_img[0:-(scale_y+1),scale_x+1:]
# Initialize the size of the final feature map that will be obtained
fmap_dimy = blk_int.shape[0] -2
fmap_dimx = blk_int.shape[1] -2
feature_map_dimy = block_sum.shape[0] -2
feature_map_dimx = block_sum.shape[1] -2
# extract the specific feature from the image
if(self.ftype == 'lbp'):
fmap = self.lbp(coord, fmap_dimx, fmap_dimy, blk_int)
elif(self.ftype == 'tlbp'):
fmap = self.tlbp(coord, fmap_dimx, fmap_dimy, blk_int)
elif(self.ftype == 'dlbp'):
fmap = self.dlbp(coord, fmap_dimx, fmap_dimy, blk_int)
elif(self.ftype == 'mlbp'):
fmap = self.mlbp(coord, fmap_dimx, fmap_dimy, blk_int)
if self.ftype == 'lbp':
feature_map = self.lbp(coord, fmap_dimx, fmap_dimy, block_sum)
elif self.ftype == 'tlbp':
feature_map = self.tlbp(coord, fmap_dimx, fmap_dimy, block_sum)
elif self.ftype == 'dlbp':
feature_map = self.dlbp(coord, fmap_dimx, fmap_dimy, block_sum)
elif self.ftype == 'mlbp':
feature_map = self.mlbp(coord, fmap_dimx, fmap_dimy, block_sum)
# reshape feature image into vector
vec = numpy.reshape(fmap,fmap.shape[0]*fmap.shape[1],1)
temp_vector = numpy.reshape(feature_map,feature_map.shape[0]*fmap.shape[1],1)
# concatenate the vector
fvec = numpy.hstack((fvec,vec))
return fvec
feature_vector = numpy.hstack((feature_vector,temp_vector))
return feature_vector
def lbp(self, coord, fmap_dimx, fmap_dimy, blk_int):
def lbp(self, coord, fmap_dimx, fmap_dimy, block_sum):
"""Function to compute the LBP for a image at single scale.
The LBP features of the given image is computed and the feature map is returned
......@@ -110,21 +111,21 @@ class lbp_feature():
fmap_dimy: Feature maps dimension along the rows.
Return:
fmap: The lbp feature map
feature_map: The lbp feature map
"""
num_neighbours = 8
blk_center = blk_int[1:1+fmap_dimy,1:1+fmap_dimx]
fmap = numpy.zeros([fmap_dimy, fmap_dimx])
blk_center = block_sum[1:1+fmap_dimy,1:1+fmap_dimx]
feature_map = numpy.zeros([fmap_dimy, fmap_dimx])
for ind in range(num_neighbours):
fmap = fmap + (2**ind)*(blk_int[coord[ind][0]:coord[ind][0] + fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]>= blk_center)
return fmap
feature_map = feature_map + (2**ind)*(block_sum[coord[ind][0]:coord[ind][0] + fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]>= blk_center)
return feature_map
def tlbp(self, coord, fmap_dimx, fmap_dimy, blk_int):
def tlbp(self, coord, fmap_dimx, fmap_dimy, block_sum):
"""Function to compute the tLBP for a image at single scale.
The LBP features of the given image is computed and the feature map is returned
The tLBP features of the given image is computed and the feature map is returned
Inputs:
coord: The coordinates specify the neighbour to be considered.
......@@ -132,23 +133,28 @@ class lbp_feature():
fmap_dimy: Feature maps dimension along the rows.
Return:
fmap: The lbp feature map
feature_map: The lbp feature map
"""
fmap = numpy.zeros([fmap_dimy, fmap_dimx])
feature_map = numpy.zeros([fmap_dimy, fmap_dimx])
num_neighbour = 8
""" Compute the feature map for the tLBP features. """
for ind in range(num_neighbours):
comp_img = blk_int[coord[(ind+1)%num_neighbour][0]:coord[(ind+1)%num_neighbour][0] + fmap_dimy,coord[(ind+1)%num_neighbour][1]:coord[(ind+1)%num_neighbour][1] + fmap_dimx]
fmap = fmap + (2**ind)*(blk_int[coord[ind][0]:coord[ind][0] + fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]>= comp_img)
return fmap
"""The comparison of pixel is done with the adjacent neighbours."""
comparing_img = block_sum[coord[(ind+1)%num_neighbour][0]:coord[(ind+1)%num_neighbour][0] + fmap_dimy,coord[(ind+1)%num_neighbour][1]:coord[(ind+1)%num_neighbour][1] + fmap_dimx]
""" Compare the neighbours and increment the feature map. """
feature_map = feature_map + (2**ind)*(block_sum[coord[ind][0]:coord[ind][0] + fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]>= comparing_img)
return feature_map
def dlbp(self, coord, fmap_dimx, fmap_dimy, blk_int):
def dlbp(self, coord, fmap_dimx, fmap_dimy, block_sum):
"""Function to compute the dLBP for a image at single scale.
The LBP features of the given image is computed and the feature map is returned
The dLBP features of the given image is computed and the feature map is returned
Inputs:
coord: The coordinates specify the neighbour to be considered.
......@@ -156,24 +162,29 @@ class lbp_feature():
fmap_dimy: Feature maps dimension along the rows.
Return:
fmap: The lbp feature map
feature_map: The lbp feature map
"""
pc = blk_int[1:1+fmap_dimy,1:1+fmap_dimx]
pc = block_sum[1:1+fmap_dimy,1:1+fmap_dimx]
num_neighbours = 8
fmap = numpy.zeros([fmap_dimy,fmap_dimx])
for ind in range(num_neighbours/2):
pi = blk_int[coord[ind][0]:coord[ind][0]+ fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]
pi4 = blk_int[coord[ind+4][0]:coord[ind+4][0]+ fmap_dimy,coord[ind+4][1]:coord[ind+4][1] + fmap_dimx]
"""The comparison of pixel is done with the diagonal neighbours."""
pi = block_sum[coord[ind][0]:coord[ind][0]+ fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]
pi4 = block_sum[coord[ind+4][0]:coord[ind+4][0]+ fmap_dimy,coord[ind+4][1]:coord[ind+4][1] + fmap_dimx]
""" Compare the neighbours and increment the feature map. """
fmap = fmap + (2**ind)*((pi-pc)*(pi4 - pc) > 0) + (4**ind)*(abs(pi - pc) >= abs(pi4 -pc))
return fmap
def mlbp(self, coord, fmap_dimx, fmap_dimy, blk_int):
def mlbp(self, coord, fmap_dimx, fmap_dimy, block_sum):
"""Function to compute the mLBP for a image at single scale.
The LBP features of the given image is computed and the feature map is returned
The mLBP features of the given image is computed and the feature map is returned.
Inputs:
coord: The coordinates specify the neighbour to be considered.
......@@ -181,19 +192,25 @@ class lbp_feature():
fmap_dimy: Feature maps dimension along the rows.
Return:
fmap: The lbp feature map
feature_map: The lbp feature map
"""
num_neighbours = 8
pm = numpy.zeros([fmap_dimy,fmap_dimx])
"""The comparison of pixel is done with the average of the neighbours and central pixel."""
for ind in range(num_neighbours):
pm = pm + blk_int[coord[ind][0]:coord[ind][0]+ fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]
pm = pm + block_sum[coord[ind][0]:coord[ind][0]+ fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]
pm = pm/num_neighbours
fmap = numpy.zeros([fmap_dimy,fmap_dimx])
feature_map = numpy.zeros([fmap_dimy,fmap_dimx])
for ind in range(num_neighbours):
pi = blk_int[coord[ind][0]:coord[ind][0]+ fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]
fmap = fmap + (2**ind)*(pi >= pm)
""" Select the value of the current neighbour."""
pi = block_sum[coord[ind][0]:coord[ind][0]+ fmap_dimy,coord[ind][1]:coord[ind][1] + fmap_dimx]
""" Compare the neighbours and increment the feature map. """
feature_map = feature_map + (2**ind)*(pi >= pm)
return fmap
......
......@@ -11,7 +11,7 @@
import xbob.db.mnist
import numpy as np
import numpy
import sys, getopt
import argparse
import string
......@@ -47,8 +47,8 @@ def main():
label_test = label_test.astype(int)
# initialize the label data for multivariate case
train_targets = -np.ones([fea_train.shape[0],num_digits])
test_targets = -np.ones([fea_test.shape[0],num_digits])
train_targets = -numpy.ones([fea_train.shape[0],num_digits])
test_targets = -numpy.ones([fea_test.shape[0],num_digits])
for i in range(num_digits):
train_targets[label_train == i,i] = 1
......@@ -83,7 +83,7 @@ def main():
# Plot the confusion matrix
cm_title = 'MultiLUT_pixel_round' + str(args.num_rnds)
confusion.display_cm(confusion_matrix, 'LBP_round1')
confusion.display_cm(confusion_matrix, cm_title)
......
......@@ -13,6 +13,7 @@ import numpy
import sys, getopt
import argparse
import string
from ..util import confusion
from ..features import local_feature
from ..core import boosting
import matplotlib.pyplot
......@@ -92,40 +93,17 @@ def main():
# Classify the test samples (testsamp) using the boosited classifier generated above
prediction_labels = machine.classify(test_fea)
# Calulate the values for confusion matrix
score = numpy.zeros([10,10])
confusion_matrix = numpy.zeros([num_digits,num_digits])
for i in range(num_digits):
prediction_i = prediction_labels[test_targets[:,i] == 1,:]
print prediction_i.shape
num_samples_i = prediction_i.shape[0]
for j in range(num_digits):
score[i,j] = sum(prediction_i[:,j] == 1)
numpy.savetxt('conf_mat.out', score, delimiter=',')
cm = score/numpy.sum(score,1)
res = matplotlib.pyplot.imshow(cm, cmap=matplotlib.pyplot.cm.summer, interpolation='nearest')
for x in numpy.arange(cm.shape[0]):
for y in numpy.arange(cm.shape[1]):
col = 'white'
if cm[x,y] > 0.5: col = 'black'
matplotlib.pyplot.annotate('%.2f' % (100*cm[x,y],), xy=(y,x), color=col,
fontsize=8, horizontalalignment='center', verticalalignment='center')
classes = [str(k) for k in range(10)]
matplotlib.pyplot.xticks(numpy.arange(10), classes)
matplotlib.pyplot.yticks(numpy.arange(10), classes, rotation=90)
matplotlib.pyplot.ylabel("(Your prediction)")
matplotlib.pyplot.xlabel("(Real class)")
matplotlib.pyplot.title("Confusion Matrix (%s set) - in %%" % set_name)
matplotlib.pyplot.show()
# Calculate the accuracy in percentage for the curent classificaiton test
accuracy = 100*float(sum(numpy.sum(prediction_labels == test_targets,1) == num_digits))/float(prediction_labels.shape[0])
print "The average accuracy of classification is %f " % (accuracy)
confusion_matrix[j,i] = 100*(float(sum(prediction_i[:,j] == 1)/float(num_samples_i)))
# Plot the confusion matrix
cm_title = 'MultiLUT_Block_' + args.feature_type + str(scale_y) + '_round' + str(args.num_rnds)
confusion.display_cm(confusion_matrix, cm_title)
......
......@@ -107,7 +107,7 @@ def main():
# Plot the confusion matrix
cm_title = 'MultiLUT_LBP_round' + str(args.num_rnds)
confusion.display_cm(confusion_matrix, 'LBP_round1')
confusion.display_cm(confusion_matrix, cm_title)
......
"""The test script to perform the multivariate classification on the digits from the MNIST dataset.
The MNIST data is exported using the xbob.db.mnist module which provide the train and test
partitions for the digits. LBP features are extracted and the available algorithms for
classification is Lut based Boosting.
#!/usr/bin/env python
"""
import xbob.db.mnist
import numpy
import sys, getopt
import argparse
import string
#import cProfile
import bob
from xbob.boosting.util import confusion
from xbob.boosting.features import local_feature
from xbob.boosting.core import boosting
import matplotlib.pyplot
def get_features(img_size, train_img, test_img):
# Extract the lbp features from the images
lbp_extractor = bob.ip.LBP(8)
temp_img = train_img[0,:].reshape([img_size,img_size])
output_image_size = lbp_extractor.get_lbp_shape(temp_img)
feature_dimension = output_image_size[0]*output_image_size[1]
train_fea = numpy.zeros((train_img.shape[0], feature_dimension))
test_fea = numpy.zeros((test_img.shape[0], feature_dimension))
for i in range(train_img.shape[0]):
current_img = train_img[i,:].reshape([img_size,img_size])
lbp_output_image = numpy.ndarray ( output_image_size, dtype = numpy.uint16 )
lbp_extractor (current_img, lbp_output_image)
train_fea[i,:] = numpy.reshape(lbp_output_image, feature_dimension, 1)
for i in range(test_img.shape[0]):
current_img = test_img[i,:].reshape([img_size,img_size])
lbp_output_image = numpy.ndarray ( output_image_size, dtype = numpy.uint16 )
lbp_extractor (current_img, lbp_output_image)
test_fea[i,:] = numpy.reshape(lbp_output_image, feature_dimension, 1)
train_fea = train_fea.astype(numpy.uint8)
test_fea = test_fea.astype(numpy.uint8)
return train_fea, test_fea
def main():
parser = argparse.ArgumentParser(description = " The arguments for the boosting. ")
parser.add_argument('-r', default = 1, dest = "num_rnds", type = int, help = "The number of round for the boosting")
parser.add_argument('-l', default = 'exp', dest = "loss_type", type= str, choices = {'log','exp'}, help = "The type of the loss function. Logit and Exponential functions are the avaliable options")
parser.add_argument('-s', default = 'indep', dest = "selection_type", choices = {'indep', 'shared'}, type = str, help = "The feature selection type for the LUT based trainer. For multivarite case the features can be selected by sharing or independently ")
parser.add_argument('-n', default = 256, dest = "num_entries", type = int, help = "The number of entries in the LookUp table. It is the range of the feature values, e.g. if LBP features are used this values is 256.")
parser.add_argument('-f', default = 'lbp', dest = "feature_type", type = str, choices = {'lbp', 'mlbp', 'tlbp', 'dlbp'}, help = "The type of LBP features to be extracted from the image to perform the classification. The features are extracted from the block of varying scales")
parser.add_argument('-d', default = 10, dest = "num_digits", type = int, help = "The number of digits to be considered for classification.")
args = parser.parse_args()
# download the dataset
db_object = xbob.db.mnist.Database()
# Hardcode the number of digits and the image size
num_digits = args.num_digits
img_size = 28
# get the data (features and labels) for the selected digits from the xbob_db_mnist class functions
train_img, label_train = db_object.data('train',labels = range(num_digits))
test_img, label_test = db_object.data('test', labels = range(num_digits))
# Format the label data into int and change the class labels to -1 and +1
label_train = label_train.astype(int)
label_test = label_test.astype(int)
# initialize the label data for multivariate case
train_targets = -numpy.ones([train_img.shape[0],num_digits])
test_targets = -numpy.ones([test_img.shape[0],num_digits])
for i in range(num_digits):
train_targets[label_train == i,i] = 1
test_targets[label_test == i,i] = 1
train_fea, test_fea = get_features(img_size,train_img, test_img)
#cProfile.run('train_fea, test_fea = get_features(img_size,train_img, test_img)')
print "LBP features computed"
# Initilize the trainer with LutTrainer
boost_trainer = boosting.Boost('LutTrainer')
# Set the parameters for the boosting
boost_trainer.num_rnds = args.num_rnds
boost_trainer.loss_type = args.loss_type
boost_trainer.selection_type = args.selection_type
boost_trainer.num_entries = args.num_entries
# Perform boosting of the feature set samp
machine = boost_trainer.train(train_fea, train_targets)
# Classify the test samples (testsamp) using the boosted classifier generated above
prediction_labels = machine.classify(test_fea)
# Calulate the values for confusion matrix
confusion_matrix = numpy.zeros([num_digits,num_digits])
for i in range(num_digits):
prediction_i = prediction_labels[test_targets[:,i] == 1,:]
num_samples_i = prediction_i.shape[0]
for j in range(num_digits):
confusion_matrix[j,i] = 100*(float(sum(prediction_i[:,j] == 1)/float(num_samples_i)))
# Plot the confusion matrix
cm_title = 'MultiLUT_LBP_round' + str(args.num_rnds)
confusion.display_cm(confusion_matrix, cm_title)
if __name__ == "__main__":
main()
Supports Markdown
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