Spaces:
Sleeping
Sleeping
| from config import * | |
| from time import time | |
| from copy import copy | |
| import functools, os, re | |
| import sys, cv2, math, numpy as np | |
| na = np.array | |
| ################################################################################ | |
| rows, columns = os.popen('stty size', 'r').read().split() | |
| __strip_ansi_re = re.compile(r""" | |
| \x1b # literal ESC | |
| \[ # literal [ | |
| [;\d]* # zero or more digits or semicolons | |
| [A-Za-z] # a letter | |
| """, re.VERBOSE).sub | |
| def __strip_ansi(s): | |
| return __strip_ansi_re("", s) | |
| ################################################################################ | |
| def clock(): | |
| global NC_CLOCK; return "(%8s)s" % round((time() - NC_CLOCK), 3) | |
| def reset(): global NC_CLOCK; NC_CLOCK = time() | |
| def warn(msg): print("\x1b[0;33;40m warn: \x1b[4;33;40m" + msg + "\x1b[0m") | |
| def errn(msg): print("\n\x1b[0;37;41m errn: " + msg + "\x1b[0m\n"); sys.exit(1) | |
| def head(msg): return "\x1b[5;30;43m " + msg + " \x1b[0m" | |
| def call(msg): return "--> \x1b[5;31;40m@" + msg + "\x1b[0m" | |
| def ribb(*msg, sep='-'): | |
| msg = ' '.join(msg) | |
| return msg + sep * int(int(columns) - len(__strip_ansi(msg))) | |
| ################################################################################ | |
| def image_scale(pts, scale): | |
| """scale to original image size""" | |
| def __loop(x, y): return [x[0] * y, x[1] * y] | |
| return list(map(functools.partial(__loop, y=1/scale), pts)) | |
| def image_resize(img, height=500): | |
| """resize image to same normalized area (height**2)""" | |
| pixels = height * height; shape = list(np.shape(img)) | |
| scale = math.sqrt(float(pixels)/float(shape[0]*shape[1])) | |
| shape[0] *= scale; shape[1] *= scale | |
| img = cv2.resize(img, (int(shape[1]), int(shape[0]))) | |
| img_shape = np.shape(img) | |
| return img, img_shape, scale | |
| def image_transform(img, points, square_length=150): | |
| """crop original image using perspective warp""" | |
| board_length = square_length * 8 | |
| def __dis(a, b): return np.linalg.norm(na(a)-na(b)) | |
| def __shi(seq, n=0): return seq[-(n % len(seq)):] + seq[:-(n % len(seq))] | |
| best_idx, best_val = 0, 10**6 | |
| for idx, val in enumerate(points): | |
| val = __dis(val, [0, 0]) | |
| if val < best_val: | |
| best_idx, best_val = idx, val | |
| pts1 = np.float32(__shi(points, 4 - best_idx)) | |
| pts2 = np.float32([[0, 0], [board_length, 0], \ | |
| [board_length, board_length], [0, board_length]]) | |
| M = cv2.getPerspectiveTransform(pts1, pts2) | |
| W = cv2.warpPerspective(img, M, (board_length, board_length)) | |
| return W | |
| class ImageObject(object): | |
| images = {}; scale = 1; shape = (0, 0) | |
| def __init__(self, img): | |
| """save and prepare image array""" | |
| self.images['orig'] = img | |
| self.images['main'], self.shape, self.scale = \ | |
| image_resize(img) # downscale for speed | |
| self.images['test'] = copy(self.images['main']) | |
| def __getitem__(self, attr): | |
| """return image as array""" | |
| return self.images[attr] | |
| def __setitem__(self, attr, val): | |
| """save image to object""" | |
| self.images[attr] = val | |
| def crop(self, pts): | |
| """crop using 4 points transform""" | |
| pts_orig = image_scale(pts, self.scale) | |
| img_crop = image_transform(self.images['orig'], pts_orig) | |
| self.__init__(img_crop) |