xml_helper_functions.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. from os import mkdir
  2. from os.path import exists
  3. from pylab import imsave, array, zeros, inv, dot, norm, svd, floor
  4. from xml.dom.minidom import parse
  5. from Character import Character
  6. from GrayscaleImage import GrayscaleImage
  7. from NormalizedCharacterImage import NormalizedCharacterImage
  8. from LicensePlate import LicensePlate
  9. # Gets the character data from a picture with a license plate
  10. def retrieve_data(plate, corners):
  11. x0,y0, x1,y1, x2,y2, x3,y3 = corners
  12. M = max(x0, x1, x2, x3) - min(x0, x1, x2, x3)
  13. N = max(y0, y1, y2, y3) - min(y0, y1, y2, y3)
  14. matrix = array([
  15. [x0, y0, 1, 0, 0, 0, 0, 0, 0],
  16. [ 0, 0, 0, x0, y0, 1, 0, 0, 0],
  17. [x1, y1, 1, 0, 0, 0, -M * x0, -M * y1, -M],
  18. [ 0, 0, 0, x1, y1, 1, 0, 0, 0],
  19. [x2, y2, 1, 0, 0, 0, -M * x2, -M * y2, -M],
  20. [ 0, 0, 0, x2, y2, 1, -N * x2, -N * y2, -N],
  21. [x3, y3, 1, 0, 0, 0, 0, 0, 0],
  22. [ 0, 0, 0, x3, y3, 1, -N * x3, -N * y3, -N]
  23. ])
  24. P = get_transformation_matrix(matrix)
  25. data = array([zeros(M, float)] * N)
  26. for i in range(M):
  27. for j in range(N):
  28. or_coor = dot(P, ([[i],[j],[1]]))
  29. or_coor_h = (or_coor[1][0] / or_coor[2][0],
  30. or_coor[0][0] / or_coor[2][0])
  31. data[j][i] = pV(plate, or_coor_h[0], or_coor_h[1])
  32. return data
  33. def get_transformation_matrix(matrix):
  34. # Get the vector p and the values that are in there by taking the SVD.
  35. # Since D is diagonal with the eigenvalues sorted from large to small
  36. # on the diagonal, the optimal q in min ||Dq|| is q = [[0]..[1]].
  37. # Therefore, p = Vq means p is the last column in V.
  38. U, D, V = svd(matrix)
  39. p = V[8][:]
  40. return inv(array([[p[0],p[1],p[2]], [p[3],p[4],p[5]], [p[6],p[7],p[8]]]))
  41. def pV(image, x, y):
  42. #Get the value of a point (interpolated x, y) in the given image
  43. if not image.in_bounds(x, y):
  44. return 0
  45. x_low, x_high = floor(x), floor(x+1)
  46. y_low, y_high = floor(y), floor(y+1)
  47. x_y = (x_high - x_low) * (y_high - y_low)
  48. a = x_high - x
  49. b = y_high - y
  50. c = x - x_low
  51. d = y - y_low
  52. return image[x_low, y_low] / x_y * a * b \
  53. + image[x_high, y_low] / x_y * c * b \
  54. + image[x_low , y_high] / x_y * a * d \
  55. + image[x_high, y_high] / x_y * c * d
  56. def xml_to_LicensePlate(filename, save_character=None):
  57. plate = GrayscaleImage('../images/Images/%s.jpg' % filename)
  58. dom = parse('../images/Infos/%s.info' % filename)
  59. country = ''
  60. result = []
  61. version = get_node(dom, "current-version")
  62. infos = by_tag(dom, "info")
  63. for info in infos:
  64. if not version == get_node(info, "version"):
  65. continue
  66. country = get_node(info, "identification-letters")
  67. temp = by_tag(info, "characters")
  68. if not temp: # no characters where found in the file
  69. break
  70. characters = temp[0].childNodes
  71. for i, char in enumerate(characters):
  72. if not char.nodeName == "character":
  73. continue
  74. value = get_node(char, "char")
  75. corners = get_corners(char)
  76. if not len(corners) == 8:
  77. break
  78. data = retrieve_data(plate, corners)
  79. image = NormalizedCharacterImage(data=data)
  80. result.append(Character(value, corners, image, filename))
  81. if save_character:
  82. character_image = GrayscaleImage(data=data)
  83. path = "../images/LearningSet/%s" % value
  84. image_path = "%s/%d_%s.jpg" % (path, i, filename.split('/')[-1])
  85. if not exists(path):
  86. mkdir(path)
  87. if not exists(image_path):
  88. character_image.save(image_path)
  89. return LicensePlate(country, result)
  90. def get_node(node, tag):
  91. return by_tag(node, tag)[0].firstChild.data
  92. def by_tag(node, tag):
  93. return node.getElementsByTagName(tag)
  94. def get_attr(node, attr):
  95. return int(node.getAttribute(attr))
  96. def get_corners(dom):
  97. p = by_tag(dom, "point")
  98. # Extra padding
  99. y = 3
  100. x = 2
  101. # return 8 values (x0,y0, .., x3,y3)
  102. return get_attr(p[0], "x") - x, get_attr(p[0], "y") - y,\
  103. get_attr(p[1], "x") + x, get_attr(p[1], "y") - y,\
  104. get_attr(p[2], "x") + x, get_attr(p[2], "y") + y,\
  105. get_attr(p[3], "x") - x, get_attr(p[3], "y") + y