|
|
|
import cv2 |
|
import numpy as np |
|
from PIL import Image, ImageOps |
|
|
|
''' |
|
PIL resize (W,H) |
|
Torch resize is (H,W) |
|
''' |
|
class Stretch: |
|
def __init__(self): |
|
self.tps = cv2.createThinPlateSplineShapeTransformer() |
|
|
|
def __call__(self, img, mag=-1, prob=1.): |
|
if np.random.uniform(0,1) > prob: |
|
return img |
|
|
|
W, H = img.size |
|
img = np.array(img) |
|
srcpt = list() |
|
dstpt = list() |
|
|
|
W_33 = 0.33 * W |
|
W_50 = 0.50 * W |
|
W_66 = 0.66 * W |
|
|
|
H_50 = 0.50 * H |
|
|
|
P = 0 |
|
|
|
|
|
b = [.2, .3, .4] |
|
if mag<0 or mag>=len(b): |
|
index = len(b)-1 |
|
else: |
|
index = mag |
|
frac = b[index] |
|
|
|
|
|
srcpt.append([P, P]) |
|
srcpt.append([P, H-P]) |
|
srcpt.append([P, H_50]) |
|
x = np.random.uniform(0, frac)*W_33 |
|
dstpt.append([P+x, P]) |
|
dstpt.append([P+x, H-P]) |
|
dstpt.append([P+x, H_50]) |
|
|
|
|
|
srcpt.append([P+W_33, P]) |
|
srcpt.append([P+W_33, H-P]) |
|
x = np.random.uniform(-frac, frac)*W_33 |
|
dstpt.append([P+W_33+x, P]) |
|
dstpt.append([P+W_33+x, H-P]) |
|
|
|
|
|
srcpt.append([P+W_66, P]) |
|
srcpt.append([P+W_66, H-P]) |
|
x = np.random.uniform(-frac, frac)*W_33 |
|
dstpt.append([P+W_66+x, P]) |
|
dstpt.append([P+W_66+x, H-P]) |
|
|
|
|
|
srcpt.append([W-P, P]) |
|
srcpt.append([W-P, H-P]) |
|
srcpt.append([W-P, H_50]) |
|
x = np.random.uniform(-frac, 0)*W_33 |
|
dstpt.append([W-P+x, P]) |
|
dstpt.append([W-P+x, H-P]) |
|
dstpt.append([W-P+x, H_50]) |
|
|
|
N = len(dstpt) |
|
matches = [cv2.DMatch(i, i, 0) for i in range(N)] |
|
dst_shape = np.array(dstpt).reshape((-1, N, 2)) |
|
src_shape = np.array(srcpt).reshape((-1, N, 2)) |
|
self.tps.estimateTransformation(dst_shape, src_shape, matches) |
|
img = self.tps.warpImage(img) |
|
img = Image.fromarray(img) |
|
|
|
return img |
|
|
|
|
|
class Distort: |
|
def __init__(self): |
|
self.tps = cv2.createThinPlateSplineShapeTransformer() |
|
|
|
def __call__(self, img, mag=-1, prob=1.): |
|
if np.random.uniform(0,1) > prob: |
|
return img |
|
|
|
W, H = img.size |
|
img = np.array(img) |
|
srcpt = list() |
|
dstpt = list() |
|
|
|
W_33 = 0.33 * W |
|
W_50 = 0.50 * W |
|
W_66 = 0.66 * W |
|
|
|
H_50 = 0.50 * H |
|
|
|
P = 0 |
|
|
|
|
|
b = [.2, .3, .4] |
|
if mag<0 or mag>=len(b): |
|
index = len(b)-1 |
|
else: |
|
index = mag |
|
frac = b[index] |
|
|
|
|
|
srcpt.append([P, P]) |
|
x = np.random.uniform(0, frac)*W_33 |
|
y = np.random.uniform(0, frac)*H_50 |
|
dstpt.append([P+x, P+y]) |
|
|
|
srcpt.append([P+W_33, P]) |
|
x = np.random.uniform(-frac, frac)*W_33 |
|
y = np.random.uniform(0, frac)*H_50 |
|
dstpt.append([P+W_33+x, P+y]) |
|
|
|
srcpt.append([P+W_66, P]) |
|
x = np.random.uniform(-frac, frac)*W_33 |
|
y = np.random.uniform(0, frac)*H_50 |
|
dstpt.append([P+W_66+x, P+y]) |
|
|
|
srcpt.append([W-P, P]) |
|
x = np.random.uniform(-frac, 0)*W_33 |
|
y = np.random.uniform(0, frac)*H_50 |
|
dstpt.append([W-P+x, P+y]) |
|
|
|
|
|
srcpt.append([P, H-P]) |
|
x = np.random.uniform(0, frac)*W_33 |
|
y = np.random.uniform(-frac, 0)*H_50 |
|
dstpt.append([P+x, H-P+y]) |
|
|
|
srcpt.append([P+W_33, H-P]) |
|
x = np.random.uniform(-frac, frac)*W_33 |
|
y = np.random.uniform(-frac, 0)*H_50 |
|
dstpt.append([P+W_33+x, H-P+y]) |
|
|
|
srcpt.append([P+W_66, H-P]) |
|
x = np.random.uniform(-frac, frac)*W_33 |
|
y = np.random.uniform(-frac, 0)*H_50 |
|
dstpt.append([P+W_66+x, H-P+y]) |
|
|
|
srcpt.append([W-P, H-P]) |
|
x = np.random.uniform(-frac, 0)*W_33 |
|
y = np.random.uniform(-frac, 0)*H_50 |
|
dstpt.append([W-P+x, H-P+y]) |
|
|
|
N = len(dstpt) |
|
matches = [cv2.DMatch(i, i, 0) for i in range(N)] |
|
dst_shape = np.array(dstpt).reshape((-1, N, 2)) |
|
src_shape = np.array(srcpt).reshape((-1, N, 2)) |
|
self.tps.estimateTransformation(dst_shape, src_shape, matches) |
|
img = self.tps.warpImage(img) |
|
img = Image.fromarray(img) |
|
|
|
return img |
|
|
|
|
|
class Curve: |
|
def __init__(self, square_side=224): |
|
self.tps = cv2.createThinPlateSplineShapeTransformer() |
|
self.side = square_side |
|
|
|
def __call__(self, img, mag=-1, prob=1.): |
|
if np.random.uniform(0,1) > prob: |
|
return img |
|
|
|
W, H = img.size |
|
|
|
if H!=self.side or W!=self.side: |
|
img = img.resize((self.side, self.side), Image.BICUBIC) |
|
|
|
isflip = np.random.uniform(0,1) > 0.5 |
|
if isflip: |
|
img = ImageOps.flip(img) |
|
|
|
|
|
img = np.array(img) |
|
w = self.side |
|
h = self.side |
|
w_25 = 0.25 * w |
|
w_50 = 0.50 * w |
|
w_75 = 0.75 * w |
|
|
|
b = [1.1, .95, .8] |
|
if mag<0 or mag>=len(b): |
|
index = 0 |
|
else: |
|
index = mag |
|
rmin = b[index] |
|
|
|
r = np.random.uniform(rmin, rmin+.1)*h |
|
x1 = (r**2 - w_50**2)**0.5 |
|
h1 = r - x1 |
|
|
|
t = np.random.uniform(0.4, 0.5)*h |
|
|
|
w2 = w_50*t/r |
|
hi = x1*t/r |
|
h2 = h1 + hi |
|
|
|
sinb_2 = ((1 - x1/r)/2)**0.5 |
|
cosb_2 = ((1 + x1/r)/2)**0.5 |
|
w3 = w_50 - r*sinb_2 |
|
h3 = r - r*cosb_2 |
|
|
|
w4 = w_50 - (r-t)*sinb_2 |
|
h4 = r - (r-t)*cosb_2 |
|
|
|
w5 = 0.5*w2 |
|
h5 = h1 + 0.5*hi |
|
h_50 = 0.50*h |
|
|
|
srcpt = [(0,0 ), (w,0 ), (w_50,0), (0,h ), (w,h ), (w_25,0), (w_75,0 ), (w_50,h), (w_25,h), (w_75,h ), (0,h_50), (w,h_50 )] |
|
dstpt = [(0,h1), (w,h1), (w_50,0), (w2,h2), (w-w2,h2), (w3, h3), (w-w3,h3), (w_50,t), (w4,h4 ), (w-w4,h4), (w5,h5 ), (w-w5,h5)] |
|
|
|
N = len(dstpt) |
|
matches = [cv2.DMatch(i, i, 0) for i in range(N)] |
|
dst_shape = np.array(dstpt).reshape((-1, N, 2)) |
|
src_shape = np.array(srcpt).reshape((-1, N, 2)) |
|
self.tps.estimateTransformation(dst_shape, src_shape, matches) |
|
img = self.tps.warpImage(img) |
|
img = Image.fromarray(img) |
|
|
|
if isflip: |
|
|
|
img = ImageOps.flip(img) |
|
rect = (0, self.side//2, self.side, self.side) |
|
else: |
|
rect = (0, 0, self.side, self.side//2) |
|
|
|
img = img.crop(rect) |
|
img = img.resize((W, H), Image.BICUBIC) |
|
return img |
|
|
|
|
|
|