""" Deskews file after getting skew angle """ """ This code is based on the following file: https://github.com/kakul/Alyn/blob/master/alyn/deskew.py """ import optparse import numpy as np import os from alyn3.skew_detect import SkewDetect import cv2 class Deskew: def __init__(self, input_file, output_file, r_angle=0, skew_max=4.0, acc_deg=0.1, method=1, roi_w=1.0, roi_h=1.0, gray=1.0, quality=100, short=None): self.input_file = input_file self.output_file = output_file self.r_angle = r_angle self.method = method self.gray = gray self.quality = quality self.short = short self.skew_obj = SkewDetect(self.input_file, skew_max=skew_max, acc_deg=acc_deg, roi_w=roi_w, roi_h=roi_h) def deskew(self): print('input: '+self.input_file) res = self.skew_obj.process_single_file() angle = res['Estimated Angle'] rot_angle = angle + self.r_angle img = cv2.imread(self.input_file, cv2.IMREAD_COLOR) g = self.gray * 255 rotated = self.rotate_expand(img, rot_angle, g) if self.short: h = rotated.shape[0] w = rotated.shape[1] print('origin w,h: {}, {}'.format(w, h)) if w < h: h = int(h*self.short/w+0.5) w = self.short else: w = int(w*self.short/h+0.5) h = self.short print('resized w,h: {}, {}'.format(w, h)) rotated = cv2.resize(rotated, (w, h)) if self.output_file: self.save_image(rotated) return res def deskew_on_memory(self, input_data): res = self.skew_obj.determine_skew_on_memory(input_data) angle = res['Estimated Angle'] rot_angle = angle + self.r_angle img = input_data g = self.gray * 255 rotated = self.rotate_expand(img, rot_angle, g) if self.short: h = rotated.shape[0] w = rotated.shape[1] print('origin w,h: {}, {}'.format(w, h)) if w < h: h = int(h*self.short/w+0.5) w = self.short else: w = int(w*self.short/h+0.5) h = self.short print('resized w,h: {}, {}'.format(w, h)) rotated = cv2.resize(rotated, (w, h)) return rotated def save_image(self, img): path = self.skew_obj.check_path(self.output_file) if os.path.splitext(path)[1] in ['.jpg', '.JPG', '.jpeg', '.JPEG']: cv2.imwrite(path, img, [cv2.IMWRITE_JPEG_QUALITY, 100]) else: cv2.imwrite(path, img) def rotate_expand(self, img, angle=0, g=255): h = img.shape[0] w = img.shape[1] angle_rad = angle/180.0*np.pi w_rot = int(np.round(h*np.absolute(np.sin(angle_rad)) + w*np.absolute(np.cos(angle_rad)))) h_rot = int(np.round(h*np.absolute(np.cos(angle_rad)) + w*np.absolute(np.sin(angle_rad)))) size_rot = (w_rot, h_rot) mat = cv2.getRotationMatrix2D((w/2, h/2), angle, 1.0) mat[0][2] = mat[0][2] - w/2 + w_rot/2 mat[1][2] = mat[1][2] - h/2 + h_rot/2 rotated = cv2.warpAffine(img, mat, size_rot, borderValue=(g, g, g)) return rotated def run(self): if self.input_file: return self.deskew() def optparse_args(): parser = optparse.OptionParser() parser.add_option( '-i', '--input', default=None, dest='input_file', help='Input file name') parser.add_option( '-o', '--output', default=None, dest='output_file', help='Output file name') parser.add_option( '-r', '--rotate', default=0, dest='r_angle', help='Rotate the image to desired axis', type=int) parser.add_option( '-g', '--gray', default=1.0, dest='gray', help='Gray level outside the input image boundaries.\n' 'between 0.0(black) and 1.0(white)\n' '[0.0, 1.0], default: 1.0', type=float) parser.add_option( '-q', '--quality', default=100, dest='quality', help='output jpeg image quality. i\n' '1 is worst quality and smallest file size,\n' 'and 100 is best quality and largest file size.\n' '[1, 100], default: 100', type=int) return parser.parse_args() if __name__ == '__main__': options, args = optparse_args() deskew_obj = Deskew( options.input_file, options.display_image, options.output_file, options.r_angle, options.gray, options.quality) deskew_obj.run()