Browse Source

merged conflicts

Fabien 14 years ago
parent
commit
cfd20b63f6
6 changed files with 77 additions and 26 deletions
  1. 4 1
      src/Character.py
  2. 51 0
      src/Classifier.py
  3. 3 3
      src/GrayscaleImage.py
  4. 7 8
      src/LetterCropper.py
  5. 10 7
      src/NormalizedCharacterImage.py
  6. 2 7
      src/combined_test.py

+ 4 - 1
src/Character.py

@@ -9,4 +9,7 @@ class Character:
     def show(self):
         from pylab import imshow, show
         imshow(self.data, cmap="gray")
-        show()
+        show()
+
+    def get_feature_vector(self):
+        pass

+ 51 - 0
src/Classifier.py

@@ -0,0 +1,51 @@
+from svmutil import svm_model, svm_problem, svm_parameter, svm_predict, LINEAR
+from cPicle 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)
+            f.close()
+        else:
+            self.param = svm_parameter()
+            self.param.kernel_type = LINEAR
+            self.param.C = c
+            self.character_map = {}
+            self.model = None
+
+    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)
+        f.close()
+
+    def train(self, learning_set):
+        """Train the classifier with a list of character objects that have
+        known values."""
+        classes = []
+        features = []
+
+        for char in learning_set:
+            # 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)
+
+            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]
+
+    def classify(self, character):
+        """Classify a character object and assign its value."""
+        prediction = self.model.predict(character.get_feature_vector())
+
+        for value, svm_class in self.character_map.iteritems():
+            if svm_class == prediction:
+                return value

+ 3 - 3
src/GrayscaleImage.py

@@ -6,7 +6,7 @@ from scipy.misc import imresize, imsave
 class GrayscaleImage:
 
     def __init__(self, image_path = None, data = None):
-        if image_path:
+        if image_path != None:
             self.data = imread(image_path)
             
             extension = image_path.split('.',3)[-1]
@@ -15,7 +15,7 @@ class GrayscaleImage:
               self.data = self.data[::-1]
               
             self.convert_to_grayscale()
-        elif data:
+        elif data != None:
             self.data = data
     
     def __iter__(self):
@@ -46,7 +46,7 @@ class GrayscaleImage:
                               
     def show(self):
         imshow(self.data, cmap="gray")
-        #show()
+        show()
     
     def make_histogram(self):
         return hist(self.data)

+ 7 - 8
src/LetterCropper.py

@@ -1,25 +1,24 @@
 from copy import deepcopy
 from Rectangle import Rectangle
+from GrayscaleImage import GrayscaleImage
 
 class LetterCropper:
 
     def __init__(self, threshold = 0.9):
-        self.source_image = image
         self.threshold = threshold
         
-    def get_cropped_letter(self):
+    def crop_to_letter(self, image):
+        self.image = image
         self.determine_letter_bounds()
-        self.result_image = deepcopy(self.source_image)
-        self.result_image.crop(self.letter_bounds)
-        return self.result_image
+        self.image.crop(self.letter_bounds)
 
     def determine_letter_bounds(self):
-        min_x = self.source_image.width
+        min_x = self.image.width
         max_x = 0
-        min_y = self.source_image.height
+        min_y = self.image.height
         max_y = 0
 
-        for y, x, value in self.source_image:
+        for y, x, value in self.image:
             if value < self.threshold:
                 if x < min_x: min_x = x
                 if y < min_y: min_y = y

+ 10 - 7
src/NormalizedCharacterImage.py

@@ -5,14 +5,17 @@ from GaussianFilter import GaussianFilter
 
 class NormalizedCharacterImage(GrayscaleImage):
     
-    def __init__(self, image, size=(60, 40), blur=1.1, crop_threshold=0.9):
-        GrayscaleImage.__init__(self, data=deepcopy(image.data))
+    def __init__(self, image=None, data=None, size=(60, 40), blur=1.1, crop_threshold=0.9):
+        if image != None:
+            GrayscaleImage.__init__(self, data=deepcopy(image.data))
+        elif data != None:
+            GrayscaleImage.__init__(self, data=deepcopy(data))
         self.blur = blur
         self.crop_threshold = crop_threshold
         self.size = size
         self.gausse_filter()
         self.increase_contrast()
-        self.crop()
+        self.crop_to_letter()
         self.resize()
 
     def increase_contrast(self):
@@ -23,9 +26,9 @@ class NormalizedCharacterImage(GrayscaleImage):
         filter = GaussianFilter(1.1)
         filter.filter(self)
         
-    def crop(self):
-        cropper = LetterCropper(self, 0.9)
-        self.data = cropper.get_cropped_letter().data
+    def crop_to_letter(self):
+        cropper = LetterCropper(0.9)
+        cropper.crop_to_letter(self)
 
     def resize(self):
-        self.resize(self.size)
+        GrayscaleImage.resize(self, self.size)

+ 2 - 7
src/combined_test.py

@@ -1,12 +1,7 @@
 from GrayscaleImage import GrayscaleImage
 from NormalizedCharacterImage import NormalizedCharacterImage 
-
-# Comment added by Richard Torenvliet
-# Steps in this test files are
-# 1. crop image 
-# 2. resize to default hight (in future also to width)
-# 3. plot
+from LetterCropper import LetterCropper
 
 image = GrayscaleImage("../images/test10.png")
 normalized_character_image = NormalizedCharacterImage(image)
-normalized_character_image.show()
+normalized_character_image.show()