Switch to side-by-side view

--- a
+++ b/dsb2018_topcoders/selim/aug/functional.py
@@ -0,0 +1,402 @@
+import cv2
+cv2.setNumThreads(0)
+cv2.ocl.setUseOpenCL(False)
+import numpy as np
+import math
+from scipy.ndimage.filters import gaussian_filter
+from functools import wraps
+
+
+def vflip(img):
+    return cv2.flip(img, 0)
+
+
+def hflip(img):
+    return cv2.flip(img, 1)
+
+
+def random_flip(img, code):
+    return cv2.flip(img, code)
+
+
+def transpose(img):
+    return img.transpose(1, 0, 2) if len(img.shape) > 2 else img.transpose(1, 0)
+
+
+def rot90(img, factor):
+    img = np.rot90(img, factor)
+    return np.ascontiguousarray(img)
+
+
+def rotate(img, angle):
+    height, width = img.shape[0:2]
+    mat = cv2.getRotationMatrix2D((width/2, height/2), angle, 1.0)
+    img = cv2.warpAffine(img, mat, (width, height),
+                         flags=cv2.INTER_LINEAR,
+                         borderMode=cv2.BORDER_REFLECT_101)
+    return img
+
+
+def shift_scale_rotate(img, angle, scale, dx, dy):
+    height, width = img.shape[:2]
+
+    cc = math.cos(angle/180*math.pi) * scale
+    ss = math.sin(angle/180*math.pi) * scale
+    rotate_matrix = np.array([[cc, -ss], [ss, cc]])
+
+    box0 = np.array([[0, 0], [width, 0],  [width, height], [0, height], ])
+    box1 = box0 - np.array([width/2, height/2])
+    box1 = np.dot(box1, rotate_matrix.T) + np.array([width/2+dx*width, height/2+dy*height])
+
+    box0 = box0.astype(np.float32)
+    box1 = box1.astype(np.float32)
+    mat = cv2.getPerspectiveTransform(box0, box1)
+    img = cv2.warpPerspective(img, mat, (width, height),
+                              flags=cv2.INTER_LINEAR,
+                              borderMode=cv2.BORDER_REFLECT_101)
+
+    return img
+
+
+def center_crop(img, height, width):
+    h, w, c = img.shape
+    dy = (h-height)//2
+    dx = (w-width)//2
+    y1 = dy
+    y2 = y1 + height
+    x1 = dx
+    x2 = x1 + width
+    img = img[y1:y2, x1:x2, :]
+    return img
+
+
+def clip(img, dtype, maxval):
+    return np.clip(img, 0, maxval).astype(dtype)
+
+
+def clipped(func):
+    @wraps(func)
+    def wrapped_function(img, *args, **kwargs):
+        dtype, maxval = img.dtype, np.max(img)
+        return clip(func(img, *args, **kwargs), dtype, maxval)
+    return wrapped_function
+
+
+def shift_hsv(img, hue_shift, sat_shift, val_shift):
+    dtype = img.dtype
+    img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV).astype(np.int32)
+    h, s, v = cv2.split(img)
+    h = cv2.add(h, hue_shift)
+    h = np.where(h < 0, 255 - h, h)
+    h = np.where(h > 255, h - 255, h)
+    h = h.astype(dtype)
+    s = clip(cv2.add(s, sat_shift), dtype, 255 if dtype == np.uint8 else 1.)
+    v = clip(cv2.add(v, val_shift), dtype, 255 if dtype == np.uint8 else 1.)
+    img = cv2.merge((h, s, v)).astype(dtype)
+    img = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)
+    return img
+
+@clipped
+def shift_rgb(img, r_shift, g_shift, b_shift):
+    img[...,0] = img[...,0] + r_shift
+    img[...,1] = img[...,1] + g_shift
+    img[...,2] = img[...,2] + b_shift
+    return img
+
+def clahe(img, clipLimit=2.0, tileGridSize=(8,8)):
+    img_yuv = cv2.cvtColor(img, cv2.COLOR_RGB2LAB)
+    clahe = cv2.createCLAHE(clipLimit=clipLimit, tileGridSize=tileGridSize)
+    img_yuv[:, :, 0] = clahe.apply(img_yuv[:, :, 0])
+    img_output = cv2.cvtColor(img_yuv, cv2.COLOR_LAB2RGB)
+    return img_output
+
+def blur(img, ksize):
+    return cv2.blur(img, (ksize, ksize))
+
+def median_blur(img, ksize):
+    return cv2.medianBlur(img, ksize)
+
+def motion_blur(img):
+    kernel = np.zeros((9, 9))
+    xs, ys = np.random.randint(0, kernel.shape[1]), np.random.randint(0, kernel.shape[0])
+    xe, ye = np.random.randint(0, kernel.shape[1]), np.random.randint(0, kernel.shape[0])
+    cv2.line(kernel, (xs, ys), (xe, ye), 1, thickness=1)
+    return cv2.filter2D(img, -1, kernel / np.sum(kernel))
+
+def random_polosa(img):
+    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+    if np.mean(gray) < 100:
+        empty = np.zeros(img.shape[:2], dtype=np.uint8)
+        xs, ys = np.random.randint(0, empty.shape[1]), np.random.randint(0, empty.shape[0])
+        xe, ye = np.random.randint(0, empty.shape[1]), np.random.randint(0, empty.shape[0])
+        factor = np.random.randint(1, 10) / 3.
+        cv2.line(empty, (xs, ys), (xe, ye), np.max(gray) / factor, thickness=np.random.randint(10, 100))
+        empty = cv2.blur(empty, (5, 5))
+        empty = empty | gray
+        return cv2.cvtColor(empty, cv2.COLOR_GRAY2RGB)
+    return img
+
+def distort1(img, k=0, dx=0, dy=0):
+    """"
+    ## unconverntional augmnet ################################################################################3
+    ## https://stackoverflow.com/questions/6199636/formulas-for-barrel-pincushion-distortion
+
+    ## https://stackoverflow.com/questions/10364201/image-transformation-in-opencv
+    ## https://stackoverflow.com/questions/2477774/correcting-fisheye-distortion-programmatically
+    ## http://www.coldvision.io/2017/03/02/advanced-lane-finding-using-opencv/
+
+    ## barrel\pincushion distortion
+    """
+    height, width = img.shape[:2]
+    #  map_x, map_y =
+    # cv2.initUndistortRectifyMap(intrinsics, dist_coeffs, None, None, (width,height),cv2.CV_32FC1)
+    # https://stackoverflow.com/questions/6199636/formulas-for-barrel-pincushion-distortion
+    # https://stackoverflow.com/questions/10364201/image-transformation-in-opencv
+    k = k * 0.00001
+    dx = dx * width
+    dy = dy * height
+    x, y = np.mgrid[0:width:1, 0:height:1]
+    x = x.astype(np.float32) - width/2 - dx
+    y = y.astype(np.float32) - height/2 - dy
+    theta = np.arctan2(y, x)
+    d = (x*x + y*y)**0.5
+    r = d*(1+k*d*d)
+    map_x = r*np.cos(theta) + width/2 + dx
+    map_y = r*np.sin(theta) + height/2 + dy
+
+    img = cv2.remap(img, map_x, map_y, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)
+    return img
+
+
+def distort2(img, num_steps=10, xsteps=[], ysteps=[]):
+    """
+    #http://pythology.blogspot.sg/2014/03/interpolation-on-regular-distorted-grid.html
+    ## grid distortion
+    """
+    height, width = img.shape[:2]
+
+    x_step = width // num_steps
+    xx = np.zeros(width, np.float32)
+    prev = 0
+    for idx, x in enumerate(range(0, width, x_step)):
+        start = x
+        end = x + x_step
+        if end > width:
+            end = width
+            cur = width
+        else:
+            cur = prev + x_step*xsteps[idx]
+
+        xx[start:end] = np.linspace(prev, cur, end-start)
+        prev = cur
+
+    y_step = height // num_steps
+    yy = np.zeros(height, np.float32)
+    prev = 0
+    for idx, y in enumerate(range(0, height, y_step)):
+        start = y
+        end = y + y_step
+        if end > height:
+            end = height
+            cur = height
+        else:
+            cur = prev + y_step*ysteps[idx]
+
+        yy[start:end] = np.linspace(prev, cur, end-start)
+        prev = cur
+
+    map_x, map_y = np.meshgrid(xx, yy)
+    map_x = map_x.astype(np.float32)
+    map_y = map_y.astype(np.float32)
+    img = cv2.remap(img, map_x, map_y,
+                    interpolation=cv2.INTER_LINEAR,
+                    borderMode=cv2.BORDER_REFLECT_101)
+    return img
+
+def elastic_transform_fast(image, alpha, sigma, alpha_affine, random_state=None):
+    """Elastic deformation of images as described in [Simard2003]_ (with modifications).
+    .. [Simard2003] Simard, Steinkraus and Platt, "Best Practices for
+         Convolutional Neural Networks applied to Visual Document Analysis", in
+         Proc. of the International Conference on Document Analysis and
+         Recognition, 2003.
+
+     Based on https://gist.github.com/erniejunior/601cdf56d2b424757de5
+    """
+    if random_state is None:
+        random_state = np.random.RandomState(1234)
+
+    shape = image.shape
+    shape_size = shape[:2]
+
+
+    # Random affine
+    center_square = np.float32(shape_size) // 2
+    square_size = min(shape_size) // 3
+    alpha = float(alpha)
+    sigma = float(sigma)
+    alpha_affine = float(alpha_affine)
+
+    pts1 = np.float32([center_square + square_size, [center_square[0] + square_size, center_square[1] - square_size],
+                       center_square - square_size])
+    pts2 = pts1 + random_state.uniform(-alpha_affine, alpha_affine, size=pts1.shape).astype(np.float32)
+    M = cv2.getAffineTransform(pts1, pts2)
+
+    image = cv2.warpAffine(image, M, shape_size[::-1], borderMode=cv2.BORDER_REFLECT_101)
+
+    dx = np.float32(gaussian_filter((random_state.rand(*shape_size) * 2 - 1), sigma) * alpha)
+    dy = np.float32(gaussian_filter((random_state.rand(*shape_size) * 2 - 1), sigma) * alpha)
+
+    x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]))
+
+    mapx = np.float32(x + dx)
+    mapy = np.float32(y + dy)
+
+    return cv2.remap(image, mapx, mapy, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)
+
+
+def remap_color(img, bg, center, max):
+    def get_lut(img, bg, center, max):
+        ma = np.max(img)
+        # me = np.mean(img)
+        # th = np.mean([ma, me]) * 1.5
+        th = ma / 2
+        gap = 10
+        channels = [[], [], []]
+        range2 = ma - int(th)
+        for i in range(3):
+            channels[i].append(np.linspace(bg[i] - gap, center[i] - gap, int(th)).astype(np.uint8))
+            channels[i].append(np.linspace(center[i] - gap, max[i] + gap, range2).astype(np.uint8))
+            channels[i].append([max[i] + gap] * (256 - sum(map(len, channels[i]))))
+            channels[i] = np.hstack(channels[i])
+        return np.dstack(channels)
+
+    # img = adjust_gamma(img, 5.)
+    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+    if np.mean(gray) > 100:
+        return img
+    lut = get_lut(img, bg, center, max)
+    res = cv2.LUT(img, lut).astype(np.uint8)
+    return res
+
+def invert(img):
+    return 255 - img
+
+def channel_shuffle(img):
+    ch_arr = [0, 1, 2]
+    np.random.shuffle(ch_arr)
+    img = img[..., ch_arr]
+    return img
+
+@clipped
+def gauss_noise(image, var):
+    row, col, ch = image.shape
+    mean = var
+    # var = 30
+    sigma = var**0.5
+    gauss = np.random.normal(mean,sigma,(row,col,ch))
+    gauss = gauss.reshape(row,col,ch)
+    gauss = (gauss - np.min(gauss)).astype(np.uint8)
+    return image.astype(np.int32) + gauss
+
+def salt_pepper_noise(image):
+    #todo
+    s_vs_p = 0.5
+    amount = 0.004
+    noisy = image
+    # Salt mode
+    num_salt = np.ceil(amount * image.size * s_vs_p)
+    coords = [np.random.randint(0, i - 1, int(num_salt))
+              for i in image.shape]
+    noisy[coords] = 255
+
+    # Pepper mode
+    num_pepper = np.ceil(amount * image.size * (1. - s_vs_p))
+    coords = [np.random.randint(0, i - 1, int(num_pepper))
+              for i in image.shape]
+    noisy[coords] = 0
+    return noisy
+
+def poisson_noise(image):
+    #todo
+    vals = len(np.unique(image))
+    vals = 2 ** np.ceil(np.log2(vals))
+    noisy = np.random.poisson(image * vals) / float(vals)
+    return noisy
+
+def speckle_noise(image):
+    #todo
+    row, col, ch = image.shape
+    gauss = np.random.randn(row,col,ch)
+    gauss = gauss.reshape(row,col,ch)
+    noisy = image + image * gauss
+    return noisy
+
+@clipped
+def random_brightness(img, alpha):
+    return alpha * img
+
+@clipped
+def random_contrast(img, alpha):
+    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+    gray = (3.0 * (1.0 - alpha) / gray.size) * np.sum(gray)
+    return alpha * img + gray
+
+def to_three_channel_gray(img):
+    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+    invgray = 255 - gray
+    clahe = cv2.createCLAHE(clipLimit=2, tileGridSize=(8, 8))
+    if np.mean(invgray) < np.mean(gray):
+        invgray, gray = gray, invgray
+    res = [invgray, gray, clahe.apply(invgray)]
+    return cv2.merge(res)
+
+def to_gray(img):
+    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+    if np.mean(gray) > 127:
+        gray = 255 - gray
+    return cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB)
+
+
+def add_channel(img):
+    lab = cv2.cvtColor(img, cv2.COLOR_RGB2LAB)
+    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(21, 21))
+    lab = clahe.apply(lab[:, :, 0])
+    if lab.mean() > 127:
+        lab = 255 - lab
+    return np.dstack((img, lab))
+
+
+
+
+def fix_mask(msk):
+    # if len(msk.shape) > 2:
+    #     msk[..., 2] = (msk[..., 2] > 127)
+    #     msk[..., 1] = (msk[..., 1] > 127) * (msk[..., 2] == 0)
+    #     msk[..., 0] = (msk[..., 1] == 0) * (msk[..., 2] == 0)
+    # else:
+    msk = (msk > 127)
+    return msk.astype(np.uint8) * 255
+
+
+def img_to_tensor(im):
+    return np.moveaxis(im / (255. if im.dtype == np.uint8 else 1), -1, 0).astype(np.float32)
+
+
+def mask_to_tensor(mask, num_classes):
+    if num_classes > 1:
+        if 1:
+            #softmax
+            long_mask = np.zeros((mask.shape[:2]), dtype=np.int64)
+            if len(mask.shape) == 3:
+                for c in range(mask.shape[2]):
+                    long_mask[mask[...,c] > 0] = c
+            else:
+                long_mask[mask > 127] = 1
+                long_mask[mask == 0] = 0
+            return long_mask
+        else:
+            mask = img_to_tensor(mask)
+    else:
+        mask = np.expand_dims(mask / (255. if mask.dtype == np.uint8 else 1), 0).astype(np.float32)
+    return mask
+