選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

234 行
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])