| |
|
|
| |
| |
| |
| |
|
|
| import os |
| import cv2 |
| import argparse |
| import numpy as np |
| from alyn3.deskew import Deskew |
| from alyn3.skew_detect import SkewDetect |
|
|
| os.environ["OPENCV_IO_ENABLE_JASPER"] = "true" |
|
|
|
|
| def deskew_image(input, output, r_angle=0, |
| skew_max=4.0, acc_deg=0.5, roi_w=1.0, roi_h=1.0, |
| method=1, gray=1.0, quality=100, short=None, |
| log=None): |
|
|
| image_name = os.path.basename(input) |
| print('process: '+image_name) |
| d = Deskew(input, output, |
| r_angle=r_angle, |
| skew_max=skew_max, |
| acc_deg=acc_deg, |
| method=method, |
| gray=gray, |
| quality=quality, |
| short=short, |
| roi_w=roi_w, |
| roi_h=roi_h) |
| res = d.run() |
|
|
| if log: |
| with open(log, mode='a') as f: |
| line = '{}\t{:.6f}\n'.format( |
| res['Image File'], (-res['Estimated Angle'])) |
| f.write(line) |
|
|
|
|
| def deskew_dir(input_dir_path, output_dir_path, r_angle=0, |
| skew_max=4.0, acc_deg=0.5, roi_w=1.0, roi_h=1.0, |
| method=1, gray=1.0, quality=100, short=None, |
| log=None): |
| image_list = os.listdir(input_dir_path) |
|
|
| for image_name in image_list: |
| input_path = os.path.join(input_dir_path, image_name) |
| if(os.path.isdir(input_path)): |
| continue |
| print('process: '+str(image_name)) |
| output_path = os.path.join(output_dir_path, image_name) |
| d = Deskew(input_path, output_path, |
| r_angle=r_angle, |
| skew_max=skew_max, |
| acc_deg=acc_deg, |
| method=method, |
| gray=gray, |
| quality=quality, |
| short=short, |
| roi_w=roi_w, |
| roi_h=roi_h) |
| res = d.run() |
|
|
| if log: |
| with open(log, mode='a') as f: |
| line = '{}\t{:.6f}\n'.format( |
| res['Image File'], (-res['Estimated Angle'])) |
| f.write(line) |
|
|
|
|
| def add_detected_lines(input_path, output_path, |
| skew_max=4.0, acc_deg=0.5, |
| roi_w=1.0, roi_h=1.0, |
| bgr=[0, 0, 255]): |
| line_len = 4000 |
|
|
| print("Add the detected lines to "+os.path.basename(input_path)) |
| sd = SkewDetect(input_path, skew_max=skew_max, acc_deg=acc_deg, |
| roi_w=roi_w, roi_h=roi_h) |
| acc, ang_rad, distance = sd.determine_line(input_path) |
| img = cv2.imread(input_path) |
| if len(acc) == 0: |
| print('Image file:{} has no lines detected'.format(input_path)) |
| else: |
| max_val = max(acc) |
| for val, theta, rho in zip(acc[::-1], ang_rad[::-1], distance[::-1]): |
| a = np.cos(theta) |
| b = np.sin(theta) |
| x0 = a * rho + int(img.shape[1] * (0.5-roi_w/2.0)) |
| y0 = b * rho + int(img.shape[0] * (0.5-roi_h/2.0)) |
| x1 = int(x0 + line_len*(-b)) |
| y1 = int(y0 + line_len*(a)) |
| x2 = int(x0 - line_len*(-b)) |
| y2 = int(y0 - line_len*(a)) |
| tmp_bgr = bgr.copy() |
| tmp_bgr[0] = 255.0 * (1.0 - val / max_val) |
| tmp_bgr[1] = tmp_bgr[0] |
| |
| cv2.line(img, (x1, y1), (x2, y2), tmp_bgr, 2) |
|
|
| cv2.imwrite(output_path, img) |
|
|
|
|
| def add_detected_lines_dir(input_dir_path, output_dir_path, |
| skew_max=4.0, acc_deg=0.1, |
| roi_w=1.0, roi_h=1.0, |
| bgr=[0, 0, 255]): |
| |
| |
| image_list = os.listdir(input_dir_path) |
|
|
| for image_name in image_list: |
| input_path = os.path.join(input_dir_path, image_name) |
| if(os.path.isdir(input_path)): |
| continue |
| output_path = os.path.join(output_dir_path, image_name) |
| add_detected_lines(input_path, output_path, |
| skew_max=skew_max, acc_deg=acc_deg, |
| roi_w=roi_w, roi_h=roi_h, |
| bgr=[0, 0, 255]) |
|
|
|
|
| def parse_args(): |
| usage = 'python3 {} INPUT [-o OUTPUT] [-s SKEW_MAX] [-a ANGLE_ACC] [-m METHOD]'.format( |
| __file__) |
| argparser = argparse.ArgumentParser( |
| usage=usage, |
| description='Deskew image(when INPUT is an image) or images in INPUT(when INPUT is a directory).', |
| formatter_class=argparse.RawTextHelpFormatter) |
| argparser.add_argument( |
| 'input', |
| help='input image file or directory path', |
| type=str) |
| argparser.add_argument( |
| '-o', |
| '--out', |
| default='out.jpg', |
| help='output file or directory path', |
| type=str) |
| argparser.add_argument( |
| '-l', |
| '--log', |
| default=None, |
| help='estimated skew log file path\n' |
| 'output format:\n' |
| 'Image_file_path <tab> Estimated_skew_angle[deg]') |
| argparser.add_argument( |
| '-s', |
| '--skew_max', |
| default=4.0, |
| help='maximum expected skew angle[deg], default: 4.0', |
| type=float) |
| argparser.add_argument( |
| '-a', |
| '--angle_acc', |
| default=0.5, |
| help='estimated skew angle accuracy[deg], default: 0.5', |
| type=float) |
| argparser.add_argument( |
| '-rw', |
| '--roi_width', |
| default=1.0, |
| help='horizontal cropping ratio of the region of interest \n' |
| 'to the whole image. (0.0, 1.0] default: 1.0(whole image)', |
| type=float) |
| argparser.add_argument( |
| '-rh', |
| '--roi_height', |
| default=1.0, |
| help='vertical cropping ratio of the region of interest \n' |
| 'to the whole image. (0.0, 1.0] default: 1.0(whole image)', |
| type=float) |
| argparser.add_argument( |
| '-m', |
| '--method', |
| default=1, |
| help='interpolation method.\n' |
| '0: Nearest-neighbor 1: Bi-linear(default)\n' |
| '2: Bi-quadratic 3: Bi-cubic\n' |
| '4: Bi-quartic 5: Bi-quintic\n', |
| type=int) |
| argparser.add_argument( |
| '-g', |
| '--gray', |
| default=1.0, |
| dest='gray', |
| help='gray value outside the input image boundaries.\n' |
| '[0.0(black), 1.0(white)], default: 1.0', |
| type=float) |
| argparser.add_argument( |
| '-q', '--quality', |
| default=100, |
| dest='quality', |
| help='output jpeg image quality.\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) |
| argparser.add_argument( |
| '--short', |
| default=None, |
| dest='short', |
| help='the length of the short side of the output image.', |
| type=int) |
| argparser.add_argument( |
| '-v', |
| '--version', |
| version='deskew version 1.0.0', |
| action='version') |
| argparser.add_argument( |
| '--debug', |
| action='store_true') |
|
|
| return argparser.parse_args() |
|
|
|
|
| if __name__ == '__main__': |
|
|
| args = parse_args() |
|
|
| input = args.input |
| output = args.out |
| print('input directory/image: '+input) |
|
|
| if(os.path.isdir(input)): |
| if output[-4:] == '.jpg': |
| output = output[:-4] |
| print('output: '+output) |
| os.makedirs(output, exist_ok=True) |
| deskew_dir(input, output, |
| r_angle=0, |
| skew_max=args.skew_max, |
| acc_deg=args.angle_acc, |
| roi_w=args.roi_width, |
| roi_h=args.roi_height, |
| method=args.method, |
| gray=args.gray, |
| quality=args.quality, |
| short=args.short, |
| log=args.log) |
| if args.debug: |
| print('[Debug] Dump input images with detected lines') |
| os.makedirs(output+'_withL', exist_ok=True) |
| add_detected_lines_dir(input, output+'_withL', |
| roi_w=args.roi_width, |
| roi_h=args.roi_height, |
| skew_max=args.skew_max, |
| acc_deg=args.angle_acc) |
| else: |
| print('output: '+output) |
| deskew_image(input, output, |
| r_angle=0, |
| skew_max=args.skew_max, |
| acc_deg=args.angle_acc, |
| roi_w=args.roi_width, |
| roi_h=args.roi_height, |
| method=args.method, |
| gray=args.gray, |
| quality=args.quality, |
| short=args.short, |
| log=args.log) |
| if args.debug: |
| print('[Debug] Dump input image with detected lines') |
| add_detected_lines(input, output+'_withL.jpg', |
| roi_w=args.roi_width, |
| roi_h=args.roi_height, |
| skew_max=args.skew_max, |
| acc_deg=args.angle_acc) |
|
|