Commit 7148fc60 authored by Fabien's avatar Fabien

Even mooier getyped die functies in xml_helper_functs

parent 00a20f6d
...@@ -224,10 +224,9 @@ reader will only get results from this version. ...@@ -224,10 +224,9 @@ reader will only get results from this version.
Now we are only interested in the individual characters so we can skip the Now we are only interested in the individual characters so we can skip the
location of the entire license plate. Each character has location of the entire license plate. Each character has
a single character value, indicating what someone thought what the letter or a single character value, indicating what someone thought what the letter or
digit was and four coordinates to create a bounding box. To make things not to digit was and four coordinates to create a bounding box. If less then four points have been set the character will not be saved. Else, to make things not to
complicated a Character class and Point class are used. They complicated, a Character class is used. It acts as an associative list, but it gives some extra freedom when using the
act pretty much as associative lists, but it gives extra freedom on using the data.
data. If less then four points have been set the character will not be saved.
When four points have been gathered the data from the actual image is being When four points have been gathered the data from the actual image is being
requested. For each corner a small margin is added (around 3 pixels) so that no requested. For each corner a small margin is added (around 3 pixels) so that no
......
class LicensePlate: class LicensePlate:
def __init__(self, country=None, characters=None): def __init__(self, country=None, characters=None):
self.country = country self.country = country
self.characters = characters self.characters = characters
\ No newline at end of file
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def to_tuple(self):
return self.x, self.y
def __str__(self):
return str(self.x) + " " + str(self.y)
\ No newline at end of file
from os import mkdir from os import mkdir
from os.path import exists from os.path import exists
from math import acos
from pylab import imsave, array, zeros, inv, dot, norm, svd, floor from pylab import imsave, array, zeros, inv, dot, norm, svd, floor
from xml.dom.minidom import parse from xml.dom.minidom import parse
from Point import Point
from Character import Character from Character import Character
from GrayscaleImage import GrayscaleImage from GrayscaleImage import GrayscaleImage
from NormalizedCharacterImage import NormalizedCharacterImage from NormalizedCharacterImage import NormalizedCharacterImage
from LicensePlate import LicensePlate from LicensePlate import LicensePlate
# sets the entire license plate of an image # Gets the character data from a picture with a license plate
def retrieve_data(image, corners): def retrieve_data(plate, corners):
x0, y0 = corners[0].to_tuple() x0,y0, x1,y1, x2,y2, x3,y3 = corners
x1, y1 = corners[1].to_tuple()
x2, y2 = corners[2].to_tuple()
x3, y3 = corners[3].to_tuple()
M = int(1.2 * (max(x0, x1, x2, x3) - min(x0, x1, x2, x3))) M = max(x0, x1, x2, x3) - min(x0, x1, x2, x3)
N = max(y0, y1, y2, y3) - min(y0, y1, y2, y3) N = max(y0, y1, y2, y3) - min(y0, y1, y2, y3)
matrix = array([ matrix = array([
...@@ -30,7 +25,7 @@ def retrieve_data(image, corners): ...@@ -30,7 +25,7 @@ def retrieve_data(image, corners):
[ 0, 0, 0, x3, y3, 1, -N * x3, -N * y3, -N] [ 0, 0, 0, x3, y3, 1, -N * x3, -N * y3, -N]
]) ])
P = inv(get_transformation_matrix(matrix)) P = get_transformation_matrix(matrix)
data = array([zeros(M, float)] * N) data = array([zeros(M, float)] * N)
for i in range(M): for i in range(M):
...@@ -39,7 +34,7 @@ def retrieve_data(image, corners): ...@@ -39,7 +34,7 @@ def retrieve_data(image, corners):
or_coor_h = (or_coor[1][0] / or_coor[2][0], or_coor_h = (or_coor[1][0] / or_coor[2][0],
or_coor[0][0] / or_coor[2][0]) or_coor[0][0] / or_coor[2][0])
data[j][i] = pV(image, or_coor_h[0], or_coor_h[1]) data[j][i] = pV(plate, or_coor_h[0], or_coor_h[1])
return data return data
...@@ -51,108 +46,92 @@ def get_transformation_matrix(matrix): ...@@ -51,108 +46,92 @@ def get_transformation_matrix(matrix):
U, D, V = svd(matrix) U, D, V = svd(matrix)
p = V[8][:] p = V[8][:]
return array([ return inv(array([[p[0],p[1],p[2]], [p[3],p[4],p[5]], [p[6],p[7],p[8]]]))
[ p[0], p[1], p[2] ],
[ p[3], p[4], p[5] ],
[ p[6], p[7], p[8] ]
])
def pV(image, x, y): def pV(image, x, y):
#Get the value of a point (interpolated x, y) in the given image #Get the value of a point (interpolated x, y) in the given image
if image.in_bounds(x, y): if not image.in_bounds(x, y):
x_low = floor(x) return 0
x_high = floor(x + 1)
y_low = floor(y)
y_high = floor(y + 1)
x_y = (x_high - x_low) * (y_high - y_low)
a = x_high - x x_low, x_high = floor(x), floor(x+1)
b = y_high - y y_low, y_high = floor(y), floor(y+1)
c = x - x_low x_y = (x_high - x_low) * (y_high - y_low)
d = y - y_low
return image[x_low, y_low] / x_y * a * b \ a = x_high - x
+ image[x_high, y_low] / x_y * c * b \ b = y_high - y
+ image[x_low , y_high] / x_y * a * d \ c = x - x_low
+ image[x_high, y_high] / x_y * c * d d = y - y_low
return 0 return image[x_low, y_low] / x_y * a * b \
+ image[x_high, y_low] / x_y * c * b \
+ image[x_low , y_high] / x_y * a * d \
+ image[x_high, y_high] / x_y * c * d
def xml_to_LicensePlate(filename, save_character=None): def xml_to_LicensePlate(filename, save_character=None):
image = GrayscaleImage('../images/Images/%s.jpg' % filename) plate = GrayscaleImage('../images/Images/%s.jpg' % filename)
dom = parse('../images/Infos/%s.info' % filename) dom = parse('../images/Infos/%s.info' % filename)
result_characters = [] country = ''
result = []
version = dom.getElementsByTagName("current-version")[0].firstChild.data version = get_node(dom, "current-version")
info = dom.getElementsByTagName("info") infos = by_tag(dom, "info")
for i in info:
if version == i.getElementsByTagName("version")[0].firstChild.data:
country = i.getElementsByTagName("identification-letters")[0].firstChild.data for info in infos:
temp = i.getElementsByTagName("characters") if not version == get_node(info, "version"):
continue
if len(temp): country = get_node(info, "identification-letters")
characters = temp[0].childNodes temp = by_tag(info, "characters")
else:
characters = []
break
for i, character in enumerate(characters): if not temp: # no characters where found in the file
if character.nodeName == "character": break
value = character.getElementsByTagName("char")[0].firstChild.data
corners = get_corners(character)
if not len(corners) == 4: characters = temp[0].childNodes
break
character_data = retrieve_data(image, corners) for i, char in enumerate(characters):
character_image = NormalizedCharacterImage(data=character_data) if not char.nodeName == "character":
continue
result_characters.append(Character(value, corners, character_image, filename)) value = get_node(char, "char")
corners = get_corners(char)
if save_character:
single_character = GrayscaleImage(data=character_data)
path = "../images/LearningSet/%s" % value if not len(corners) == 8:
image_path = "%s/%d_%s.jpg" % (path, i, filename.split('/')[-1]) break
if not exists(path): data = retrieve_data(plate, corners)
mkdir(path) image = NormalizedCharacterImage(data=data)
result.append(Character(value, corners, image, filename))
if save_character:
character_image = GrayscaleImage(data=data)
path = "../images/LearningSet/%s" % value
image_path = "%s/%d_%s.jpg" % (path, i, filename.split('/')[-1])
if not exists(image_path): if not exists(path):
single_character.save(image_path) mkdir(path)
return LicensePlate(country, result_characters) if not exists(image_path):
character_image.save(image_path)
def get_corners(dom): return LicensePlate(country, result)
nodes = dom.getElementsByTagName("point")
corners = []
margin_y = 3
margin_x = 2
corners.append( def get_node(node, tag):
Point(get_coord(nodes[0], "x") - margin_x, return by_tag(node, tag)[0].firstChild.data
get_coord(nodes[0], "y") - margin_y)
)
corners.append( def by_tag(node, tag):
Point(get_coord(nodes[1], "x") + margin_x, return node.getElementsByTagName(tag)
get_coord(nodes[1], "y") - margin_y)
)
corners.append( def get_attr(node, attr):
Point(get_coord(nodes[2], "x") + margin_x, return int(node.getAttribute(attr))
get_coord(nodes[2], "y") + margin_y)
)
corners.append( def get_corners(dom):
Point(get_coord(nodes[3], "x") - margin_x, p = by_tag(dom, "point")
get_coord(nodes[3], "y") + margin_y)
)
return corners # Extra padding
y = 3
x = 2
def get_coord(node, attribute): # return 8 values (x0,y0, .., x3,y3)
return int(node.getAttribute(attribute)) return get_attr(p[0], "x") - x, get_attr(p[0], "y") - y,\
\ No newline at end of file get_attr(p[1], "x") + x, get_attr(p[1], "y") - y,\
get_attr(p[2], "x") + x, get_attr(p[2], "y") + y,\
get_attr(p[3], "x") - x, get_attr(p[3], "y") + y
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