Commit e2507c65 authored by Taddeüs Kroes's avatar Taddeüs Kroes

Implemented SVM classifier and added test file to test it.

parent cce4f7e3
......@@ -7,3 +7,14 @@
*.synctex.gz
*.toc
*.out
*.jpg
images/BBB
images/Images
images/Infos
images/licenseplates
chars
learning_set
test_set
classifier
classifier-model
classifier-characters
# TODO cleanup the getElements stuff
from LocalBinaryPatternizer import LocalBinaryPatternizer
class Character:
def __init__(self, value, corners, image):
self.value = value
......@@ -12,4 +13,6 @@ class Character:
show()
def get_feature_vector(self):
pass
pattern = LocalBinaryPatternizer(self.image)
return pattern.create_features_vector()
from svmutil import svm_model, svm_problem, svm_parameter, svm_predict, LINEAR
from cPicle import dump, load
from svmutil import svm_train, svm_problem, svm_parameter, svm_predict, \
LINEAR, svm_save_model, svm_load_model
from cPickle import dump, load
class Classifier:
def __init__(self, c=None, filename=None):
if filename:
# If a filename is given, load a modl from the fiven filename
f = file(filename, 'r')
self.model, self.param, self.character_map = load(f)
self.model = svm_load_model(filename + '-model')
f = file(filename + '-characters', 'r')
self.character_map = load(f)
f.close()
else:
self.param = svm_parameter()
......@@ -18,8 +20,9 @@ class Classifier:
def save(self, filename):
"""Save the SVM model in the given filename."""
f = file(filename, 'w+')
dump((self.model, self.param, self.character_map), f)
svm_save_model(filename + '-model', self.model)
f = file(filename + '-characters', 'w+')
dump(self.character_map, f)
f.close()
def train(self, learning_set):
......@@ -27,8 +30,11 @@ class Classifier:
known values."""
classes = []
features = []
l = len(learning_set)
for char in learning_set:
for i, char in enumerate(learning_set):
print 'Training "%s" -- %d of %d (%d%% done)' \
% (char.value, i + 1, l, int(100 * (i + 1) / l))
# Map the character to an integer for use in the SVM model
if char.value not in self.character_map:
self.character_map[char.value] = len(self.character_map)
......@@ -36,15 +42,13 @@ class Classifier:
classes.append(self.character_map[char.value])
features.append(char.get_feature_vector())
problem = svm_problem(self.c, features)
self.model = svm_model(problem, self.param)
# Add prediction function that returns a numeric class prediction
self.model.predict = lambda self, x: svm_predict([0], [x], self)[0][0]
problem = svm_problem(classes, features)
self.model = svm_train(problem, self.param)
def classify(self, character):
"""Classify a character object and assign its value."""
prediction = self.model.predict(character.get_feature_vector())
predict = lambda x: svm_predict([0], [x], self.model)[0][0]
prediction = predict(character.get_feature_vector())
for value, svm_class in self.character_map.iteritems():
if svm_class == prediction:
......
#!/usr/bin/python
from LicensePlate import LicensePlate
from Classifier import Classifier
from cPickle import dump, load
#chars = []
#
#for i in range(9):
# for j in range(100):
# try:
# filename = '%04d/00991_%04d%02d.info' % (i, i, j)
# print 'loading file "%s"' % filename
# plate = LicensePlate(i, j)
#
# if hasattr(plate, 'characters'):
# chars.extend(plate.characters)
# except:
# print 'epic fail'
#
#print 'loaded %d chars' % len(chars)
#
#dump(chars, file('chars', 'w+'))
#----------------------------------------------------------------
#chars = load(file('chars', 'r'))
#learned = []
#learning_set = []
#test_set = []
#
#for char in chars:
# if learned.count(char.value) > 80:
# test_set.append(char)
# else:
# learning_set.append(char)
# learned.append(char.value)
#
#dump(learning_set, file('learning_set', 'w+'))
#dump(test_set, file('test_set', 'w+'))
#----------------------------------------------------------------
learning_set = load(file('learning_set', 'r'))
# Train the classifier with the learning set
classifier = Classifier(c=3)
classifier.train(learning_set)
#classifier.save('classifier')
#----------------------------------------------------------------
#classifier = Classifier(filename='classifier')
#test_set = load(file('test_set', 'r'))
#l = len(test_set)
#matches = 0
#
#for i, char in enumerate(test_set):
# prediction = classifier.classify(char)
#
# if char.value == prediction:
# print ':) ------> Successfully recognized "%s"' % char.value
# matches += 1
# else:
# print ':( Expected character "%s", got "%s"' \
# % (char.value, prediction),
#
# print ' -- %d of %d (%d%% done)' % (i + 1, l, int(100 * (i + 1) / l))
#
#print '\n%d matches (%d%%), %d fails' % (matches, \
# int(100 * matches / len(test_set)), \
# len(test_set) - matches)
......@@ -4,6 +4,7 @@ from Error import Error
from Point import Point
from Character import Character
from GrayscaleImage import GrayscaleImage
from NormalizedCharacterImage import NormalizedCharacterImage
'''
Creates a license plate object based on an XML file. The image should be
......@@ -13,15 +14,13 @@ from GrayscaleImage import GrayscaleImage
'''
class LicensePlate:
def __init__(self, xml_title):
try:
self.dom = parse('../XML/' + str(xml_title))
except IOError:
Error("Incorrect file name given.")
else:
def __init__(self, folder_nr, file_nr):
filename = '%04d/00991_%04d%02d' % (folder_nr, folder_nr, file_nr)
self.dom = parse('../images/Infos/%s.info' % filename)
properties = self.get_properties()
self.image = GrayscaleImage('../images/' + str(properties['uii']) + '.' + str(properties['type']))
self.image = GrayscaleImage('../images/Images/%s.jpg' % filename)
self.width = int(properties['width'])
self.height = int(properties['height'])
......
......@@ -45,4 +45,4 @@ class LocalBinaryPatternizer:
return (y / self.cell_size, x / self.cell_size)
def get_features_as_array(self):
return [item for sublist in self.features for item in sublist]
\ No newline at end of file
return [h.bins for h in [h for sub in self.features for h in sub]][0]
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