You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
8.2KB

  1. import os
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import scipy as scp
  5. def levenshteinDistance(s1, s2):
  6. if len(s1) > len(s2):
  7. s1, s2 = s2, s1
  8. distances = range(len(s1) + 1)
  9. for i2, c2 in enumerate(s2):
  10. distances_ = [i2+1]
  11. for i1, c1 in enumerate(s1):
  12. if c1 == c2:
  13. distances_.append(distances[i1])
  14. else:
  15. distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
  16. distances = distances_
  17. return distances[-1]
  18. def unit_gaussian_filter(sigma):
  19. """Create and returns a 2D square gaussian filter"""
  20. x_grid = np.linspace(-3*int(sigma+1),3*int(sigma+1), 6*int(sigma+1)+1)
  21. X,Y = np.meshgrid(x_grid, x_grid)
  22. R = X*0
  23. for i in range(0,R.shape[0]):
  24. for j in range(0,R.shape[1]):
  25. R[i,j] = 1 / (2*np.pi*sigma*sigma) * np.exp(-(X[i,j]*X[i,j] + Y[i,j]*Y[i,j]) / (2*sigma*sigma))
  26. return R
  27. def calculate_img_correlation(img1, img2):
  28. """Calculation of the correlation between the two images.
  29. Produces a 2D map, and returns the maximum of it."""
  30. if(img2.size > img1.size):
  31. img2, img1 = img1, img2
  32. #img_template = scp.signal.correlate2d(img1, img1, "same")
  33. img_corr = scp.signal.correlate2d(img1, img2, "same")
  34. # sum_template = np.sum(img_template)
  35. # sum_test = np.sum(img_test)
  36. # ratio = sum_template/sum_test
  37. # img_test = img_test*ratio
  38. # max_template = np.amax(img_template)
  39. max_corr = np.amax(img_corr)
  40. index = np.where(img_corr == max_corr)
  41. # ratio_max = max_template/max_test
  42. return max_corr, index
  43. def otsu_algo(img):
  44. """Calculates the threshold between upper and lower values in an image.
  45. Uses the Otsu algorithm and returns the lower threshold value."""
  46. histo, edges = np.histogram(img, bins=255, range=(0,255))
  47. sum_tot = np.sum(histo)
  48. w = np.zeros(len(histo))
  49. mu = np.zeros(len(histo))
  50. w[0] = histo[0]
  51. mu[0] = 1*histo[0]
  52. for i in range(1,len(histo)):
  53. w[i] = w[i-1] + histo[i]
  54. mu[i] = mu[i-1] + (i+1)*histo[i]
  55. w = w/sum_tot
  56. mu = mu/sum_tot
  57. muN = mu[len(histo)-1]
  58. crit = np.zeros(len(histo))
  59. for i in range(0,len(histo)):
  60. crit[i] = w[i]*(muN-mu[i])*(muN-mu[i]) + (1-w[i])*mu[i]*mu[i]
  61. max_crit = np.amax(crit)
  62. place = np.where(crit == max_crit)
  63. if(type(place) != int):
  64. place = place[0]
  65. thresh = int(np.floor(place[0]/len(histo)*np.amax(img)))
  66. thresh = edges[thresh]
  67. return thresh
  68. def img_cells_zero(img_origin, img_gauss, threshold):
  69. """Switches off all the values of ing_gauss lower than the threshold in img_origin."""
  70. for i in range(0,img_origin.shape[0]):
  71. for j in range(0,img_origin.shape[1]):
  72. if(img_gauss[i,j]<=threshold):
  73. img_origin[i,j]=0
  74. def img_one_border_remove(img, start="begin", axis=0):
  75. """Find the limit of a black border in an image.
  76. Use "begin" or "end" through the selected axis (0 or 1) to
  77. find the limit from the upper/left or lower/right borders of the image.
  78. Returns the index limit."""
  79. if(start=="begin"):
  80. add = 1
  81. i = 0
  82. else:
  83. add = -1
  84. i = img.shape[axis-1]-1
  85. axis_sum = np.sum(img, axis=axis)
  86. while(axis_sum[i] == 0):
  87. i = i+add
  88. return i
  89. def img_black_borders_remove(img):
  90. """Find the borders of an image and removes them."""
  91. y_beg = img_one_border_remove(img)
  92. x_beg = img_one_border_remove(img, axis=1)
  93. y_end = img_one_border_remove(img, start="end")
  94. x_end = img_one_border_remove(img, start="end", axis=1)
  95. return img[x_beg:x_end, y_beg:y_end]
  96. def resize(img, shape):
  97. """Resizes an image to a different shape with the bilinear method."""
  98. img_final = np.zeros(shape)
  99. y_vect = np.linspace(0, img.shape[0]-1, shape[0])
  100. x_vect = np.linspace(0, img.shape[1]-1, shape[1])
  101. for j in range(0,shape[0]):
  102. for i in range(0,shape[1]):
  103. y0 = int(np.floor(y_vect[j]))
  104. y1 = int(np.ceil(y_vect[j]))
  105. x0 = int(np.floor(x_vect[i]))
  106. x1 = int(np.ceil(x_vect[i]))
  107. x_coma = x_vect[i]-np.floor(x_vect[i])
  108. y_coma = y_vect[j]-np.floor(y_vect[j])
  109. img_final[j,i] = (1-x_coma)*(1-y_coma)*img[y0,x0] + (x_coma)*(1-y_coma)*img[y0,x1] + (1-x_coma)*(y_coma)*img[y1,x0] + (x_coma)*(y_coma)*img[y1,x1]
  110. return img_final
  111. def signal_processing_process(img_template, img_scanned):
  112. img_gauss = scp.signal.correlate2d(img_scanned, unit_gaussian_filter(1.5), "same")
  113. thresh = otsu_algo(img_gauss)
  114. img_cells_zero(img_scanned, img_gauss, thresh)
  115. im_trunc = img_black_borders_remove(img_scanned)
  116. ratio = (img_template.shape[0]/im_trunc.shape[0], img_template.shape[1]/im_trunc.shape[1])
  117. shape1 = (int(img_template.shape[0]/ratio[0]), int(img_template.shape[1]/ratio[0]))
  118. shape2 = (int(img_template.shape[0]/ratio[1]), int(img_template.shape[1]/ratio[1]))
  119. if(shape1[0] != shape2[0] or shape1[1] != shape2[1]):
  120. img_final_1 = resize(img_template, shape1)
  121. img_final_2 = resize(img_template, shape2)
  122. max1, location1 = calculate_img_correlation(img_final_1, im_trunc)
  123. max2, location2 = calculate_img_correlation(img_final_2, im_trunc)
  124. if(max1 > max2):
  125. img_final = img_final_1
  126. ratio = ratio[0]
  127. location = location1
  128. else:
  129. img_final = img_final_2
  130. ratio = ratio[1]
  131. location = location2
  132. offset = (img_final.shape[0]//2-location[0], img_final.shape[1]//2-location[1])
  133. return img_final, im_trunc, ratio, offset
  134. # to be tried:
  135. # - delete black borders (gauss to highlight written content, blacken and delete what is not the paper)
  136. # - resize with root method
  137. # no rotation !
  138. if __name__ == "__main__":
  139. #used for tests
  140. im1 = plt.imread("/home/inc0nnu-rol/Documents/La Gemme/OCR_paper_form/test.png")
  141. im2 = plt.imread("/home/inc0nnu-rol/Documents/La Gemme/OCR_paper_form/test2.png")
  142. im3 = plt.imread("/home/inc0nnu-rol/Documents/La Gemme/OCR_paper_form/test3.png")
  143. im1 = (im1[:,:,0]+im1[:,:,1]+im1[:,:,2])*255//3
  144. im2 = (im2[:,:,0]+im2[:,:,1]+im2[:,:,2])*255//3
  145. im3 = (im3[:,:,0]+im3[:,:,1]+im3[:,:,2])*255//3
  146. img_fin, ratios, offset = signal_processing_process(im1, im3)
  147. # img_gauss = scp.signal.correlate2d(im3, unit_gaussian_filter(1.5), "same")
  148. #
  149. # thresh = otsu_algo(img_gauss)
  150. # img_cells_zero(im3, img_gauss, thresh)
  151. # im_trunc = img_black_borders_remove(im3)
  152. #
  153. # plt.imshow(im_trunc)
  154. # plt.show()
  155. #
  156. # ratio = (im1.shape[0]/im_trunc.shape[0], im1.shape[1]/im_trunc.shape[1])
  157. #
  158. # shape1 = (int(im1.shape[0]/ratio[0]), int(im1.shape[1]/ratio[0]))
  159. # shape2 = (int(im1.shape[0]/ratio[1]), int(im1.shape[1]/ratio[1]))
  160. #
  161. # if(shape1[0] != shape2[0] or shape1[1] != shape2[1]):
  162. # img_final_1 = resize(im1, shape1)
  163. # img_final_2 = resize(im1, shape2)
  164. # max1 = calculate_img_correlation(img_final_1, im_trunc)
  165. # max2 = calculate_img_correlation(img_final_2, im_trunc)
  166. # if(max1 > max2):
  167. # img_final = img_final_1
  168. # else:
  169. # img_final = img_final_2
  170. print(ratios, offset)
  171. plt.imshow(img_fin)
  172. plt.show()
  173. # Gauss = unit_gaussian_filter(1.5)
  174. # im_template = scp.signal.correlate2d(im1, im1, "same")
  175. # im_filt = scp.signal.correlate2d(im2, im_trunc, "same")
  176. #
  177. # plt.imshow(im_test)
  178. # plt.show()
  179. #
  180. # sum_template = np.sum(im_template)
  181. # sum3 = np.sum(im_test)
  182. # ratio = sum_template/sum3
  183. # im_test = im_test*ratio
  184. #
  185. # max_template = np.amax(im_template)
  186. # min_template = np.amin(im_template)
  187. # max_im_test = np.amax(im_test)
  188. # min_im_test = np.amin(im_test)
  189. #
  190. # ratio_max = max_template/max_im_test
  191. # ratio_min = min_template/min_im_test
  192. #
  193. # index_max_template = np.where(im_template == np.amax(im_template))
  194. # index_min_template = np.where(im_template == np.amin(im_template))
  195. # index_max_im_test = np.where(im_test == np.amax(im_test))
  196. # index_min_im_test = np.where(im_test == np.amin(im_test))
  197. # Gauss = unit_gaussian_filter(5)
  198. # plt.imshow(Gauss)
  199. # plt.show()
  200. # print(np.sum(Gauss))
  201. #max_index = (bla[0][0], bla[1][0])