Pastafarianist

Deskew+Scale+Align

Dec 26th, 2014
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.54 KB | None | 0 0
  1. def deskew(img, SZ, bbox=16):
  2.     m = cv2.moments(img)
  3.     if abs(m['mu02']) < 1e-2 or m['m00'] < 1:
  4.         return img.copy()
  5.     skew = m['mu11']/m['mu02']
  6.     cx, cy = m['m10']/m['m00'], m['m01']/m['m00']
  7.     M1 = np.float32([
  8.         [1, -skew],
  9.         [0, 1]
  10.     ])
  11.     b1 = np.float32([
  12.         [0.5*SZ*skew],
  13.         [0]
  14.     ])
  15.  
  16.     def deskew_pt((x, y)):
  17.         return x-skew*y+0.5*SZ*skew, y
  18.    
  19.     _cx, _cy = deskew_pt((cx, cy))
  20.     ctr = SZ/2
  21.     margin = (SZ-bbox)/2
  22.     if _cy <= img.shape[0]/2:
  23.         # center of mass is above the center of the image
  24.         # the bottom part is longer, so scaling will be counted from that
  25.         scale = (bbox/2) / (img.shape[0]-1-_cy)
  26.         vproj = deskew_pt((cx, img.shape[0]-1))
  27.         hproj = deskew_pt((0, cy))
  28.         src_tri = np.float32([(_cx, _cy), (_cx, vproj[1]), (hproj[0], _cy)])
  29.         dst_tri = np.float32([(ctr, ctr), (ctr, SZ-1-margin), (ctr-(img.shape[1]/2)*scale, ctr)])
  30.     else:
  31.         # the top part is longer
  32.         scale = (bbox/2) / _cy
  33.         vproj = deskew_pt((cx, 0))
  34.         hproj = deskew_pt((0, cy))
  35.         src_tri = np.float32([(_cx, _cy), (_cx, vproj[1]), (hproj[0], _cy)])
  36.         dst_tri = np.float32([(ctr, ctr), (ctr, margin), (ctr-(img.shape[1]/2)*scale, ctr)])
  37.     MM = cv2.getAffineTransform(src_tri, dst_tri)
  38.     M2 = MM[:, 0:2]
  39.     b2 = MM[:, 2:]
  40.  
  41.     M = np.empty((2, 3))
  42.     M[:, 0:2] = np.dot(M2, M1)
  43.     M[:, 2:] = b2 + np.dot(M2, b1)
  44.  
  45.     img = cv2.warpAffine(img, M, (SZ, SZ), flags=cv2.INTER_CUBIC)
  46.     return img
Add Comment
Please, Sign In to add comment