In [ ]:
%load_ext autoreload
%autoreload 2

In [ ]:
import sys
sys.path.insert(0, '../')

In [ ]:
from __future__ import division
import os
import numpy as np
import pandas as pd
from skimage.io import imread
from skimage.color import gray2rgb
import cv2
from pandas import read_csv
import matplotlib.pyplot as plt
import glob

In [ ]:
%matplotlib inline

Theano loss function - SmoothL1 and IoU


In [ ]:
import theano
import theano.tensor as T

In [ ]:
npr = np.random.random((10,4)).astype(np.float32)
nta = np.random.random((10,4)).astype(np.float32)

In [ ]:
p = T.fmatrix('p')
t = T.fmatrix('t')

SmoothL1 loss


In [ ]:
def ff(p, t):
    c = T.abs_(p - t)
    e = T.switch(T.lt(c, 1.), 0.5 * c * c, c - 0.5)
    return T.mean(T.sum(e, axis=1))

In [ ]:
g = ff(p, t)

In [ ]:
f = theano.function(
    inputs=[p, t],
    outputs=g
)

In [ ]:
nc = np.abs(npr - nta)
td = f(npr, nta)
print td

In [ ]:
T.grad(g, p)

IoU loss - Intersection over Union loss


In [ ]:
pn = np.array([[0.1, 0.1, 0.5, 0.8],
               [0.1, 0.1, 0.2, 0.2]], dtype=np.float32)
tn = np.array([[0.3, 0.5, 0.4, 0.9], 
               [0.3, 0.2, 0.7, 0.8]], dtype=np.float32)

In [ ]:
def hh(p, t):
    hund = np.float32(100)
    pt = (p * hund).astype(np.int32)
    tt = (t * hund).astype(np.int32)
    imp = np.zeros((pt.shape[0], 100, 100), dtype=np.uint8)
    imt = np.zeros((tt.shape[0], 100, 100), dtype=np.uint8)
    for i in range(pt.shape[0]):
        imp[i, pt[i, 1]:pt[i, 3], pt[i, 0]:pt[i, 2]] = 1
        imt[i, tt[i, 1]:tt[i, 3], tt[i, 0]:tt[i, 2]] = 1
    intersection = np.logical_and(imp, imt).astype(np.float32).sum(axis=2).sum(axis=1)
    union = np.logical_or(imp, imt).astype(np.float32).sum(axis=2).sum(axis=1)
    loss = 1. - intersection / union
    plt.imshow(imp[0, ...])
    return loss

hh(pn, tn)

In [ ]:
def gg(p, t):
    tp, tt = p.reshape((p.shape[0], 2, 2)), t.reshape((t.shape[0], 2, 2))
    overlaps = np.zeros_like(tp, dtype=np.float32)
    
    overlaps[:, 0, :] = np.maximum(tp[:, 0, :], tt[:, 0, :])
    overlaps[:, 1, :] = np.minimum(tp[:, 1, :], tt[:, 1, :])
    intersection = overlaps[:, 1, :] - overlaps[:, 0, :]
    bool_overlap = np.min(intersection, axis=1) > 0
    intersection = intersection[:, 0] * intersection[:, 1]
    intersection[bool_overlap==False] == 0.
    dims_p = tp[:, 1, :] - tp[:, 0, :]
    areas_p = dims_p[:, 0] * dims_p[:, 1]
    dims_t = tt[:, 1, :] - tt[:, 0, :]
    areas_t = dims_t[:, 0] * dims_t[:, 1]
    union = areas_p + areas_t - intersection
    ratio = 1. - np.minimum(np.exp(np.log(np.abs(intersection)) - np.log(np.abs(union) + 1e-5)), 1.)
#     no_overlap_penalty = 1. + np.abs(tp - tt).sum(axis=2).max(axis=1)
    loss = ratio.copy()
#     loss[bool_overlap==False] = no_overlap_penalty[bool_overlap==False]
    return loss
    print tp
    print "-"
    print tt
    print "-"
    print no_overlap_penalty
    print no_overlap_penalty
    print "overlap"
    print overlaps
    print "int/union"
    print intersection, union
    print "bool overlap"
    print bool_overlap
    print "loss"
    print loss
    

gg(pn, tn)

In [ ]:
tp, tt = p.reshape((p.shape[0], 2, 2)), t.reshape((t.shape[0], 2, 2))
overlaps_t0 = T.maximum(tp[:, 0, :], tt[:, 0, :])
overlaps_t1 = T.minimum(tp[:, 1, :], tt[:, 1, :])
intersection = overlaps_t1 - overlaps_t0
bool_overlap = T.min(intersection, axis=1) > 0
intersection = intersection[:, 0] * intersection[:, 1]
intersection[bool_overlap==False] == 0.
dims_p = tp[:, 1, :] - tp[:, 0, :]
areas_p = dims_p[:, 0] * dims_p[:, 1]
dims_t = tt[:, 1, :] - tt[:, 0, :]
areas_t = dims_t[:, 0] * dims_t[:, 1]
union = areas_p + areas_t - intersection
loss = 1. - T.minimum(T.exp(T.log(T.abs_(intersection)) - T.log(T.abs_(union) + np.float32(1e-5))), np.float32(1.))
print "done"

theano_iou = theano.function(
    inputs=[p, t],
    outputs=loss
)

In [ ]:
theano_iou(pn, tn)

In [ ]:
def theano_hh(p, t):
    hund = np.float32(100)
    pt = (p * hund).astype(np.int32)
    tt = (t * hund).astype(np.int32)
    imp = np.zeros((pt.shape[0], 100, 100), dtype=np.uint8)
    imt = np.zeros((tt.shape[0], 100, 100), dtype=np.uint8)
    for i in range(pt.shape[0]):
        imp[i, pt[i, 1]:pt[i, 3], pt[i, 0]:pt[i, 2]] = 1
        imt[i, tt[i, 1]:tt[i, 3], tt[i, 0]:tt[i, 2]] = 1
    intersection = np.logical_and(imp, imt).astype(np.float32).sum(axis=2).sum(axis=1)
    union = np.logical_or(imp, imt).astype(np.float32).sum(axis=2).sum(axis=1)
    loss = 1. - intersection / union
    return loss

hh(pn, tn)

In [ ]:


In [ ]:
z = tn.reshape((2, 2, 2))
z[:, 0, :], z

In [ ]:

Augmentation


In [ ]:
from utils import get_file_list
import glob
from train_val_split import read_facescrub_img_list
from plotting import plot_face_bb

Train data split


In [ ]:
folder = '/media/shared/faceScrub/train_face_det/'
path = folder
actor_label_txt = '/media/shared/faceScrub/facescrub_actors.txt'
actress_label_txt = '/media/shared/faceScrub/facescrub_actresses.txt'
accept_pattern = '*/*.jpg'

In [ ]:
fnames, bboxes = read_facescrub_img_list(path, actor_label_txt, actress_label_txt, accept_pattern='*/*.jpg')

In [ ]:
len(fnames), len(bboxes)

Data augment


In [ ]:
train_csv = 'train.csv'

In [ ]:
train_df = read_csv(train_csv, sep='\t')
X = np.asarray(train_df['name'].as_matrix())
y_str = train_df['bbox']
y_l = map(lambda k: [np.float32(v)
                     for v in k.split(',')], y_str)
y = np.asarray(y_l)

In [ ]:
x_1 = X[1]
y_1 = y[1, :]

In [ ]:
im = imread(x_1)
plot_face_bb(im, y_1, scale=False, path=False)
img = cv2.cvtColor(im, cv2.COLOR_RGB2BGR)

In [ ]:
img_size = (256, 256, 3)
MAX_FACE_SIZE = 220
MIN_FACE_SIZE = 64

In [ ]:
h0, w0, _ = img_size
w1, h1, w2, h2 = y_1
wc, hc = (y_1[0] + y_1[2]) / 2, (y_1[1] + y_1[3]) / 2
face_width = (h2 - h1) / 2
print "Original center coords: (%.1f, %.1f)" % (wc, hc)
print "Face coords: (%.1f, %.1f) (%.1f, %.1f) and face width: %.0f" % (h1, w1, h2, w2, face_width * 2)

In [ ]:
rng = np.random.RandomState(seed=1234)

In [ ]:
# Possible scales of computation
high_scale = MAX_FACE_SIZE/2/face_width
low_scale = MIN_FACE_SIZE/2/face_width
print "Scales of computation: %.3f - %.3f" % (low_scale, high_scale)

scale_comp = rng.choice(np.arange(low_scale, high_scale, (high_scale-low_scale)/100), 1)[0]
new_face_width = round(face_width * scale_comp)
swc, shc = round(wc * scale_comp), round(hc * scale_comp)
sh1, sw1, sh2, sw2 = (shc-new_face_width, swc-new_face_width, 
                      shc+new_face_width, swc+new_face_width)
print "Chosen scale of computation: %.3f," % (scale_comp)
print "New face center: (%.1f, %.1f)\nface width: %.0f" % (
    shc, swc, new_face_width * 2)
res = cv2.resize(img, None, fx=scale_comp, fy=scale_comp)
h, w, _ = res.shape

In [ ]:
print "Face width: %.1f" % (new_face_width * 2)
plot_face_bb(res[:,:,::-1], y_1*scale_comp, scale=False, path=False)

In [ ]:
# Possible location of the face
min_pad = new_face_width + 30
lw, lh, hw, hh = (min(min_pad, w0 - min_pad), min(min_pad, h0 - min_pad), 
                  max(min_pad, w0 - min_pad), max(min_pad, h0 - min_pad))
print "Get face center in the given window: (%.1f, %.1f) (%.1f, %.1f)" % (lh, lw, hh, hw)
twc = rng.randint(lw, hw, 1)[0]
thc = rng.randint(lh, hh, 1)[0]
print "New center location: (%.1f, %.1f)" % (thc, twc)

In [ ]:
out = np.random.randint(0, high=255, size=img_size).astype(np.uint8)
sfh = shc - thc
tfh = int(0 if sfh > 0 else abs(sfh))
sfh = int(0 if sfh < 0 else sfh)
sfw = swc - twc
tfw = int(0 if sfw > 0 else abs(sfw))
sfw = int(0 if sfw < 0 else sfw)
print "source begin: (%.0f, %.0f) target begin: (%.0f, %.0f)" % (sfh, sfw, tfh, tfw)

In [ ]:
seh = shc - thc + h0
teh = int(h0 if seh <= h else h0 - seh + h)
seh = int(h if seh > h else seh)
sew = swc - twc + w0
tew = int(w0 if sew <= w else w0 - sew + w)
sew = int(w if sew > w else sew)
print "source end: (%.0f, %.0f) target end: (%.0f, %.0f)" % (seh, sew, teh, tew)

In [ ]:
ty_1 = np.array([twc-new_face_width, thc-new_face_width, twc+new_face_width, thc+new_face_width])
out[tfh:teh, tfw:tew, :] = res[sfh:seh, sfw:sew, :]
out = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)
plot_face_bb(out, ty_1, scale=False, path=False)
print "new face center: (%.0f, %.0f)" % (thc, twc)

In [ ]:
for i in glob.glob('*.jpg'):
    plt.figure()
    plt.imshow(imread(i))

In [ ]: