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

deskew.py 3.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #coding=utf-8
  2. import numpy as np
  3. import cv2
  4. import time
  5. from matplotlib import pyplot as plt
  6. import math
  7. from scipy.ndimage import filters
  8. #
  9. # def strokeFiter():
  10. # pass;
  11. def angle(x,y):
  12. return int(math.atan2(float(y),float(x))*180.0/3.1415)
  13. def h_rot(src, angle, scale=1.0):
  14. w = src.shape[1]
  15. h = src.shape[0]
  16. rangle = np.deg2rad(angle)
  17. nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale
  18. nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale
  19. rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)
  20. rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))
  21. rot_mat[0,2] += rot_move[0]
  22. rot_mat[1,2] += rot_move[1]
  23. return cv2.warpAffine(src, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)
  24. pass
  25. def v_rot(img, angel, shape, max_angel):
  26. size_o = [shape[1],shape[0]]
  27. size = (shape[1]+ int(shape[0]*np.cos((float(max_angel )/180) * 3.14)),shape[0])
  28. interval = abs( int( np.sin((float(angel) /180) * 3.14)* shape[0]))
  29. pts1 = np.float32([[0,0],[0,size_o[1]],[size_o[0],0],[size_o[0],size_o[1]]])
  30. if(angel>0):
  31. pts2 = np.float32([[interval,0],[0,size[1] ],[size[0],0 ],[size[0]-interval,size_o[1]]])
  32. else:
  33. pts2 = np.float32([[0,0],[interval,size[1] ],[size[0]-interval,0 ],[size[0],size_o[1]]])
  34. M = cv2.getPerspectiveTransform(pts1,pts2)
  35. dst = cv2.warpPerspective(img,M,size)
  36. return dst,M
  37. def skew_detection(image_gray):
  38. h, w = image_gray.shape[:2]
  39. eigen = cv2.cornerEigenValsAndVecs(image_gray,12, 5)
  40. angle_sur = np.zeros(180,np.uint)
  41. eigen = eigen.reshape(h, w, 3, 2)
  42. flow = eigen[:,:,2]
  43. vis = image_gray.copy()
  44. vis[:] = (192 + np.uint32(vis)) / 2
  45. d = 12
  46. points = np.dstack( np.mgrid[d/2:w:d, d/2:h:d] ).reshape(-1, 2)
  47. for x, y in points:
  48. vx, vy = np.int32(flow[int(y), int(x)]*d)
  49. # cv2.line(rgb, (x-vx, y-vy), (x+vx, y+vy), (0, 355, 0), 1, cv2.LINE_AA)
  50. ang = angle(vx,vy)
  51. angle_sur[(ang+180)%180] +=1
  52. # torr_bin = 30
  53. angle_sur = angle_sur.astype(np.float)
  54. angle_sur = (angle_sur-angle_sur.min())/(angle_sur.max()-angle_sur.min())
  55. angle_sur = filters.gaussian_filter1d(angle_sur,5)
  56. skew_v_val = angle_sur[20:180-20].max()
  57. skew_v = angle_sur[30:180-30].argmax() + 30
  58. skew_h_A = angle_sur[0:30].max()
  59. skew_h_B = angle_sur[150:180].max()
  60. skew_h = 0
  61. if (skew_h_A > skew_v_val*0.3 or skew_h_B > skew_v_val*0.3):
  62. if skew_h_A>=skew_h_B:
  63. skew_h = angle_sur[0:20].argmax()
  64. else:
  65. skew_h = - angle_sur[160:180].argmax()
  66. return skew_h,skew_v
  67. def fastDeskew(image):
  68. image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
  69. skew_h,skew_v = skew_detection(image_gray)
  70. print("校正角度 h ",skew_h,"v",skew_v)
  71. deskew,M = v_rot(image,int((90-skew_v)*1.5),image.shape,60)
  72. return deskew,M
  73. if __name__ == '__main__':
  74. fn = './dataset/0.jpg'
  75. img = cv2.imread(fn)
  76. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  77. skew_h,skew_v = skew_detection(gray)
  78. img = v_rot(img,(90-skew_v ),img.shape,60)
  79. # img = h_rot(img,skew_h)
  80. # if img.shape[0]>img.shape[1]:
  81. # img = h_rot(img, -90)
  82. plt.show()
  83. cv2.waitKey()