|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- import os
- import numpy as np
- import matplotlib.pyplot as plt
- import scipy as scp
-
-
-
- def levenshteinDistance(s1, s2):
- if len(s1) > len(s2):
- s1, s2 = s2, s1
-
- distances = range(len(s1) + 1)
- for i2, c2 in enumerate(s2):
- distances_ = [i2+1]
- for i1, c1 in enumerate(s1):
- if c1 == c2:
- distances_.append(distances[i1])
- else:
- distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
- distances = distances_
- return distances[-1]
-
- def unit_gaussian_filter(sigma):
- """Create and returns a 2D square gaussian filter"""
- x_grid = np.linspace(-3*int(sigma+1),3*int(sigma+1), 6*int(sigma+1)+1)
- X,Y = np.meshgrid(x_grid, x_grid)
- R = X*0
- for i in range(0,R.shape[0]):
- for j in range(0,R.shape[1]):
- 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))
- return R
-
- def calculate_img_correlation(img1, img2):
- """Calculation of the correlation between the two images.
- Produces a 2D map, and returns the maximum of it."""
- if(img2.size > img1.size):
- img2, img1 = img1, img2
-
- #img_template = scp.signal.correlate2d(img1, img1, "same")
- img_corr = scp.signal.correlate2d(img1, img2, "same")
-
- # sum_template = np.sum(img_template)
- # sum_test = np.sum(img_test)
- # ratio = sum_template/sum_test
- # img_test = img_test*ratio
-
- # max_template = np.amax(img_template)
- max_corr = np.amax(img_corr)
- index = np.where(img_corr == max_corr)
- # ratio_max = max_template/max_test
-
- return max_corr, index
-
- def otsu_algo(img):
- """Calculates the threshold between upper and lower values in an image.
- Uses the Otsu algorithm and returns the lower threshold value."""
- histo, edges = np.histogram(img, bins=255, range=(0,255))
- sum_tot = np.sum(histo)
- w = np.zeros(len(histo))
- mu = np.zeros(len(histo))
- w[0] = histo[0]
- mu[0] = 1*histo[0]
- for i in range(1,len(histo)):
- w[i] = w[i-1] + histo[i]
- mu[i] = mu[i-1] + (i+1)*histo[i]
-
- w = w/sum_tot
- mu = mu/sum_tot
- muN = mu[len(histo)-1]
-
- crit = np.zeros(len(histo))
- for i in range(0,len(histo)):
- crit[i] = w[i]*(muN-mu[i])*(muN-mu[i]) + (1-w[i])*mu[i]*mu[i]
-
- max_crit = np.amax(crit)
- place = np.where(crit == max_crit)
- if(type(place) != int):
- place = place[0]
- thresh = int(np.floor(place[0]/len(histo)*np.amax(img)))
- thresh = edges[thresh]
- return thresh
-
- def img_cells_zero(img_origin, img_gauss, threshold):
- """Switches off all the values of ing_gauss lower than the threshold in img_origin."""
- for i in range(0,img_origin.shape[0]):
- for j in range(0,img_origin.shape[1]):
- if(img_gauss[i,j]<=threshold):
- img_origin[i,j]=0
-
- def img_one_border_remove(img, start="begin", axis=0):
- """Find the limit of a black border in an image.
- Use "begin" or "end" through the selected axis (0 or 1) to
- find the limit from the upper/left or lower/right borders of the image.
- Returns the index limit."""
- if(start=="begin"):
- add = 1
- i = 0
- else:
- add = -1
- i = img.shape[axis-1]-1
- axis_sum = np.sum(img, axis=axis)
- while(axis_sum[i] == 0):
- i = i+add
- return i
-
- def img_black_borders_remove(img):
- """Find the borders of an image and removes them."""
- y_beg = img_one_border_remove(img)
- x_beg = img_one_border_remove(img, axis=1)
- y_end = img_one_border_remove(img, start="end")
- x_end = img_one_border_remove(img, start="end", axis=1)
- return img[x_beg:x_end, y_beg:y_end]
-
- def resize(img, shape):
- """Resizes an image to a different shape with the bilinear method."""
- img_final = np.zeros(shape)
- y_vect = np.linspace(0, img.shape[0]-1, shape[0])
- x_vect = np.linspace(0, img.shape[1]-1, shape[1])
- for j in range(0,shape[0]):
- for i in range(0,shape[1]):
- y0 = int(np.floor(y_vect[j]))
- y1 = int(np.ceil(y_vect[j]))
- x0 = int(np.floor(x_vect[i]))
- x1 = int(np.ceil(x_vect[i]))
- x_coma = x_vect[i]-np.floor(x_vect[i])
- y_coma = y_vect[j]-np.floor(y_vect[j])
-
- 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]
- return img_final
-
- def signal_processing_process(img_template, img_scanned):
- img_gauss = scp.signal.correlate2d(img_scanned, unit_gaussian_filter(1.5), "same")
- thresh = otsu_algo(img_gauss)
- img_cells_zero(img_scanned, img_gauss, thresh)
- im_trunc = img_black_borders_remove(img_scanned)
- ratio = (img_template.shape[0]/im_trunc.shape[0], img_template.shape[1]/im_trunc.shape[1])
-
- shape1 = (int(img_template.shape[0]/ratio[0]), int(img_template.shape[1]/ratio[0]))
- shape2 = (int(img_template.shape[0]/ratio[1]), int(img_template.shape[1]/ratio[1]))
-
- if(shape1[0] != shape2[0] or shape1[1] != shape2[1]):
- img_final_1 = resize(img_template, shape1)
- img_final_2 = resize(img_template, shape2)
- max1, location1 = calculate_img_correlation(img_final_1, im_trunc)
- max2, location2 = calculate_img_correlation(img_final_2, im_trunc)
- if(max1 > max2):
- img_final = img_final_1
- ratio = ratio[0]
- location = location1
- else:
- img_final = img_final_2
- ratio = ratio[1]
- location = location2
- offset = (img_final.shape[0]//2-location[0], img_final.shape[1]//2-location[1])
- return img_final, im_trunc, ratio, offset
-
-
- # to be tried:
- # - delete black borders (gauss to highlight written content, blacken and delete what is not the paper)
- # - resize with root method
- # no rotation !
-
- if __name__ == "__main__":
- #used for tests
- im1 = plt.imread("/home/inc0nnu-rol/Documents/La Gemme/OCR_paper_form/test.png")
- im2 = plt.imread("/home/inc0nnu-rol/Documents/La Gemme/OCR_paper_form/test2.png")
- im3 = plt.imread("/home/inc0nnu-rol/Documents/La Gemme/OCR_paper_form/test3.png")
- im1 = (im1[:,:,0]+im1[:,:,1]+im1[:,:,2])*255//3
- im2 = (im2[:,:,0]+im2[:,:,1]+im2[:,:,2])*255//3
- im3 = (im3[:,:,0]+im3[:,:,1]+im3[:,:,2])*255//3
-
- img_fin, ratios, offset = signal_processing_process(im1, im3)
- # img_gauss = scp.signal.correlate2d(im3, unit_gaussian_filter(1.5), "same")
- #
- # thresh = otsu_algo(img_gauss)
- # img_cells_zero(im3, img_gauss, thresh)
- # im_trunc = img_black_borders_remove(im3)
- #
- # plt.imshow(im_trunc)
- # plt.show()
- #
- # ratio = (im1.shape[0]/im_trunc.shape[0], im1.shape[1]/im_trunc.shape[1])
- #
- # shape1 = (int(im1.shape[0]/ratio[0]), int(im1.shape[1]/ratio[0]))
- # shape2 = (int(im1.shape[0]/ratio[1]), int(im1.shape[1]/ratio[1]))
- #
- # if(shape1[0] != shape2[0] or shape1[1] != shape2[1]):
- # img_final_1 = resize(im1, shape1)
- # img_final_2 = resize(im1, shape2)
- # max1 = calculate_img_correlation(img_final_1, im_trunc)
- # max2 = calculate_img_correlation(img_final_2, im_trunc)
- # if(max1 > max2):
- # img_final = img_final_1
- # else:
- # img_final = img_final_2
-
- print(ratios, offset)
- plt.imshow(img_fin)
- plt.show()
-
-
-
- # Gauss = unit_gaussian_filter(1.5)
- # im_template = scp.signal.correlate2d(im1, im1, "same")
- # im_filt = scp.signal.correlate2d(im2, im_trunc, "same")
- #
- # plt.imshow(im_test)
- # plt.show()
- #
- # sum_template = np.sum(im_template)
- # sum3 = np.sum(im_test)
- # ratio = sum_template/sum3
- # im_test = im_test*ratio
- #
- # max_template = np.amax(im_template)
- # min_template = np.amin(im_template)
- # max_im_test = np.amax(im_test)
- # min_im_test = np.amin(im_test)
- #
- # ratio_max = max_template/max_im_test
- # ratio_min = min_template/min_im_test
- #
- # index_max_template = np.where(im_template == np.amax(im_template))
- # index_min_template = np.where(im_template == np.amin(im_template))
- # index_max_im_test = np.where(im_test == np.amax(im_test))
- # index_min_im_test = np.where(im_test == np.amin(im_test))
-
- # Gauss = unit_gaussian_filter(5)
- # plt.imshow(Gauss)
- # plt.show()
- # print(np.sum(Gauss))
-
- #max_index = (bla[0][0], bla[1][0])
|