Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
licenseplates
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
licenseplates
Commits
7a67ea01
Commit
7a67ea01
authored
Dec 20, 2011
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented 5x5 neighbourhood patterns.
parent
2e1b2e8c
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
140 additions
and
40 deletions
+140
-40
src/.gitignore
src/.gitignore
+1
-1
src/Character.py
src/Character.py
+3
-2
src/Classifier.py
src/Classifier.py
+4
-4
src/LocalBinaryPatternizer.py
src/LocalBinaryPatternizer.py
+25
-8
src/NormalizedCharacterImage.py
src/NormalizedCharacterImage.py
+14
-6
src/find_svm_params.py
src/find_svm_params.py
+93
-19
No files found.
src/.gitignore
View file @
7a67ea01
*.dat
results.txt
results
*
.txt
src/Character.py
View file @
7a67ea01
...
...
@@ -7,11 +7,12 @@ class Character:
self
.
image
=
image
self
.
filename
=
filename
def
get_single_cell_feature_vector
(
self
):
def
get_single_cell_feature_vector
(
self
,
neighbours
=
5
):
if
hasattr
(
self
,
'feature'
):
return
self
.
feature
=
LBP
(
self
.
image
).
single_cell_features_vector
()
pattern
=
LBP
(
self
.
image
,
neighbours
=
neighbours
)
self
.
feature
=
pattern
.
single_cell_features_vector
()
def
get_feature_vector
(
self
,
cell_size
=
None
):
pattern
=
LBP
(
self
.
image
)
if
cell_size
==
None
\
...
...
src/Classifier.py
View file @
7a67ea01
...
...
@@ -3,8 +3,8 @@ from svmutil import svm_train, svm_problem, svm_parameter, svm_predict, \
class
Classifier
:
def
__init__
(
self
,
c
=
None
,
gamma
=
None
,
filename
=
None
,
cell_size
=
12
):
self
.
cell_size
=
cell_size
def
__init__
(
self
,
c
=
None
,
gamma
=
None
,
filename
=
None
,
neighbours
=
3
):
self
.
neighbours
=
neighbours
if
filename
:
# If a filename is given, load a model from the given filename
...
...
@@ -34,7 +34,7 @@ class Classifier:
%
(
char
.
value
,
i
+
1
,
l
,
int
(
100
*
(
i
+
1
)
/
l
))
classes
.
append
(
float
(
ord
(
char
.
value
)))
#features.append(char.get_feature_vector())
char
.
get_single_cell_feature_vector
()
char
.
get_single_cell_feature_vector
(
self
.
neighbours
)
features
.
append
(
char
.
feature
)
problem
=
svm_problem
(
classes
,
features
)
...
...
@@ -56,7 +56,7 @@ class Classifier:
"""Classify a character object, return its value."""
true_value
=
0
if
true_value
==
None
else
ord
(
true_value
)
#x = character.get_feature_vector(self.cell_size)
character
.
get_single_cell_feature_vector
()
character
.
get_single_cell_feature_vector
(
self
.
neighbours
)
p
=
svm_predict
([
true_value
],
[
character
.
feature
],
self
.
model
)
prediction_class
=
int
(
p
[
0
][
0
])
...
...
src/LocalBinaryPatternizer.py
View file @
7a67ea01
...
...
@@ -3,9 +3,13 @@ from math import ceil
class
LocalBinaryPatternizer
:
def
__init__
(
self
,
image
,
cell_size
=
16
):
def
__init__
(
self
,
image
,
cell_size
=
16
,
neighbours
=
3
):
self
.
cell_size
=
cell_size
self
.
image
=
image
self
.
pattern_callback
,
self
.
bins
=
{
3
:
(
self
.
pattern_3x3
,
256
),
5
:
(
self
.
pattern_5x5
,
4096
)
}[
neighbours
]
def
setup_histograms
(
self
):
cells_in_width
=
int
(
ceil
(
self
.
image
.
width
/
float
(
self
.
cell_size
)))
...
...
@@ -16,9 +20,9 @@ class LocalBinaryPatternizer:
self
.
histograms
.
append
([])
for
j
in
xrange
(
cells_in_width
):
self
.
histograms
[
i
].
append
(
Histogram
(
256
,
0
,
256
))
self
.
histograms
[
i
].
append
(
Histogram
(
self
.
bins
,
0
,
self
.
bins
))
def
local_binary_pattern
(
self
,
y
,
x
,
value
):
def
pattern_3x3
(
self
,
y
,
x
,
value
):
return
(
self
.
is_pixel_darker
(
y
-
1
,
x
-
1
,
value
)
<<
7
)
\
|
(
self
.
is_pixel_darker
(
y
-
1
,
x
,
value
)
<<
6
)
\
|
(
self
.
is_pixel_darker
(
y
-
1
,
x
+
1
,
value
)
<<
5
)
\
...
...
@@ -26,7 +30,21 @@ class LocalBinaryPatternizer:
|
(
self
.
is_pixel_darker
(
y
+
1
,
x
+
1
,
value
)
<<
3
)
\
|
(
self
.
is_pixel_darker
(
y
+
1
,
x
,
value
)
<<
2
)
\
|
(
self
.
is_pixel_darker
(
y
+
1
,
x
-
1
,
value
)
<<
1
)
\
|
(
self
.
is_pixel_darker
(
y
,
x
-
1
,
value
)
<<
0
)
|
(
self
.
is_pixel_darker
(
y
,
x
-
1
,
value
))
def
pattern_5x5
(
self
,
y
,
x
,
value
):
return
(
self
.
is_pixel_darker
(
y
-
1
,
x
-
2
,
value
)
<<
11
)
\
|
(
self
.
is_pixel_darker
(
y
,
x
-
2
,
value
)
<<
10
)
\
|
(
self
.
is_pixel_darker
(
y
+
1
,
x
-
2
,
value
)
<<
9
)
\
|
(
self
.
is_pixel_darker
(
y
+
2
,
x
-
1
,
value
)
<<
8
)
\
|
(
self
.
is_pixel_darker
(
y
+
2
,
x
,
value
)
<<
7
)
\
|
(
self
.
is_pixel_darker
(
y
+
2
,
x
+
1
,
value
)
<<
6
)
\
|
(
self
.
is_pixel_darker
(
y
+
1
,
x
+
2
,
value
)
<<
5
)
\
|
(
self
.
is_pixel_darker
(
y
,
x
+
2
,
value
)
<<
4
)
\
|
(
self
.
is_pixel_darker
(
y
-
1
,
x
+
2
,
value
)
<<
3
)
\
|
(
self
.
is_pixel_darker
(
y
-
2
,
x
+
1
,
value
)
<<
2
)
\
|
(
self
.
is_pixel_darker
(
y
-
2
,
x
,
value
)
<<
1
)
\
|
(
self
.
is_pixel_darker
(
y
-
2
,
x
-
1
,
value
))
def
create_features_vector
(
self
):
'''Walk around the pixels in clokwise order, shifting 1 bit less at
...
...
@@ -36,7 +54,7 @@ class LocalBinaryPatternizer:
for
y
,
x
,
value
in
self
.
image
:
cy
,
cx
=
self
.
get_cell_index
(
y
,
x
)
self
.
histograms
[
cy
][
cx
].
add
(
self
.
local_binary_pattern
(
y
,
x
,
value
))
self
.
histograms
[
cy
][
cx
].
add
(
self
.
pattern_callback
(
y
,
x
,
value
))
return
self
.
get_features_as_array
()
...
...
@@ -55,15 +73,14 @@ class LocalBinaryPatternizer:
f
.
extend
(
hist
.
bins
)
return
f
#return [h.bins for h in [h for sub in self.histograms for h in sub]][0]
def
get_single_histogram
(
self
):
"""Create a single histogram of the local binary patterns in the
image."""
h
=
Histogram
(
256
,
0
,
256
)
h
=
Histogram
(
self
.
bins
,
0
,
self
.
bins
)
for
y
,
x
,
value
in
self
.
image
:
h
.
add
(
self
.
local_binary_pattern
(
y
,
x
,
value
))
h
.
add
(
self
.
pattern_callback
(
y
,
x
,
value
))
h
.
normalize
()
...
...
src/NormalizedCharacterImage.py
View file @
7a67ea01
...
...
@@ -5,19 +5,22 @@ from GaussianFilter import GaussianFilter
class
NormalizedCharacterImage
(
GrayscaleImage
):
def
__init__
(
self
,
image
=
None
,
data
=
None
,
size
=
(
60
,
40
),
blur
=
1.1
,
\
crop_threshold
=
0.9
):
def
__init__
(
self
,
image
=
None
,
data
=
None
,
height
=
None
,
blur
=
1.1
):
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
.
gaussian_filter
()
self
.
increase_contrast
()
#self.crop_threshold = crop_threshold
#self.crop_to_letter()
#self.resize()
self
.
height
=
height
self
.
resize
()
def
increase_contrast
(
self
):
self
.
data
-=
self
.
data
.
min
()
...
...
@@ -31,4 +34,9 @@ class NormalizedCharacterImage(GrayscaleImage):
cropper
.
crop_to_letter
(
self
)
def
resize
(
self
):
GrayscaleImage
.
resize
(
self
,
self
.
size
)
"""Resize the image to a fixed height."""
if
self
.
height
==
None
:
return
h
,
w
=
self
.
data
.
shape
GrayscaleImage
.
resize
(
self
,
(
self
.
height
,
self
.
height
*
w
/
h
))
src/find_svm_params.py
View file @
7a67ea01
#!/usr/bin/python
from
cPickle
import
load
from
os
import
listdir
from
os.path
import
exists
from
cPickle
import
load
,
dump
from
sys
import
argv
,
exit
from
GrayscaleImage
import
GrayscaleImage
from
NormalizedCharacterImage
import
NormalizedCharacterImage
from
Character
import
Character
from
Classifier
import
Classifier
if
len
(
argv
)
<
3
:
print
'Usage: python %s NEIGHBOURS BLUR_SCALE'
%
argv
[
0
]
exit
(
1
)
neighbours
=
int
(
argv
[
1
])
blur_scale
=
float
(
argv
[
2
])
suffix
=
'_%s_%s'
%
(
blur_scale
,
neighbours
)
chars_file
=
'characters%s.dat'
%
suffix
learning_set_file
=
'learning_set%s.dat'
%
suffix
test_set_file
=
'test_set%s.dat'
%
suffix
classifier_file
=
'classifier%s.dat'
%
suffix
results_file
=
'results%s.txt'
%
suffix
# Load characters
if
exists
(
chars_file
):
print
'Loading characters...'
chars
=
load
(
open
(
chars_file
,
'r'
))
else
:
print
'Going to generate character objects...'
chars
=
[]
for
char
in
sorted
(
listdir
(
'../images/LearningSet'
)):
for
image
in
sorted
(
listdir
(
'../images/LearningSet/'
+
char
)):
f
=
'../images/LearningSet/'
+
char
+
'/'
+
image
image
=
GrayscaleImage
(
f
)
norm
=
NormalizedCharacterImage
(
image
,
blur
=
blur_scale
,
height
=
42
)
#imshow(norm.data, cmap='gray'); show()
character
=
Character
(
char
,
[],
norm
)
character
.
get_single_cell_feature_vector
(
neighbours
)
chars
.
append
(
character
)
print
char
print
'Saving characters...'
dump
(
chars
,
open
(
chars_file
,
'w+'
))
# Load learning set and test set
if
exists
(
learning_set_file
):
print
'Loading learning set...'
learning_set
=
load
(
open
(
learning_set_file
,
'r'
))
print
'Learning set:'
,
[
c
.
value
for
c
in
learning_set
]
print
'Loading test set...'
test_set
=
load
(
open
(
test_set_file
,
'r'
))
print
'Test set:'
,
[
c
.
value
for
c
in
test_set
]
else
:
print
'Going to generate learning set and test set...'
learning_set
=
[]
test_set
=
[]
learned
=
[]
for
char
in
chars
:
if
learned
.
count
(
char
.
value
)
==
70
:
test_set
.
append
(
char
)
else
:
learning_set
.
append
(
char
)
learned
.
append
(
char
.
value
)
print
'Learning set:'
,
[
c
.
value
for
c
in
learning_set
]
print
'
\
n
Test set:'
,
[
c
.
value
for
c
in
test_set
]
print
'
\
n
Saving learning set...'
dump
(
learning_set
,
file
(
learning_set_file
,
'w+'
))
print
'Saving test set...'
dump
(
test_set
,
file
(
test_set_file
,
'w+'
))
# Perform a grid-search to find the optimal values for C and gamma
C
=
[
float
(
2
**
p
)
for
p
in
xrange
(
-
5
,
16
,
2
)]
Y
=
[
float
(
2
**
p
)
for
p
in
xrange
(
-
15
,
4
,
2
)]
best_classifier
=
None
print
'Loading learning set...'
learning_set
=
load
(
file
(
'learning_set.dat'
,
'r'
))
print
'Learning set:'
,
[
c
.
value
for
c
in
learning_set
]
print
'Loading test set...'
test_set
=
load
(
file
(
'test_set.dat'
,
'r'
))
print
'Test set:'
,
[
c
.
value
for
c
in
test_set
]
# Perform a grid-search on different combinations of soft margin and gamma
results
=
[]
best
=
(
0
,)
i
=
0
for
c
in
C
:
for
y
in
Y
:
classifier
=
Classifier
(
c
=
c
,
gamma
=
y
)
classifier
=
Classifier
(
c
=
c
,
gamma
=
y
,
neighbours
=
neighbours
)
classifier
.
train
(
learning_set
)
result
=
classifier
.
test
(
test_set
)
...
...
@@ -33,22 +99,30 @@ for c in C:
%
(
i
,
len
(
C
)
*
len
(
Y
),
c
,
y
,
int
(
round
(
result
*
100
)))
i
=
0
s
=
' c
\
y
'
print
'
\
n
c
\
y
'
,
for y in Y:
print '
|
%
f' % y,
s += '
|
%
f' % y
print
s += '
\
n
'
for c in C:
print '
%
7
s
' % c,
s += '
%
7
s
' % c
for y in Y:
print '
|
%
8
d
' % int(round(results[i] * 100)),
s += '
|
%
8
d
' % int(round(results[i] * 100))
i += 1
print
s += '
\
n
'
s += '
\
nBest
result
:
%
.
3
f
%%
for
C
=
%
f
and
gamma
=
%
f' % best[:3]
print '
Saving
results
...
'
f = open(results_file, '
w
+
')
f.write(s)
f.close()
print '
\
nBest
result
:
%
.
3
f
%%
for
C
=
%
f
and
gamma
=
%
f' % best[:3]
print '
Saving
best
classifier
...
'
best[3].save(classifier_file)
best[3].save('
classifier
.
dat
')
print '
\
n
' + s
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment