from skimage import io
from skimage.transform import resize
from skimage.draw import polygon
import cv2
import numpy as np
from scipy.signal import convolve2d
from scipy.stats import mode
from scipy.spatial import Delaunay
from scipy.ndimage.interpolation import rotate
from scipy.linalg import fractional_matrix_power as fmp
from imutils import rotate #faster rotate
import matplotlib as mpl
mpl.use('TkAgg')
%matplotlib inline
from matplotlib import pyplot as plt
from IPython.display import HTML
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Jupytyer code hidden for viewing. Click to disable"></form>
<a href="https://stackoverflow.com/questions/27934885/how-to-hide-code-from-cells-in-ipython-notebook-visualized-with-nbviewer">
Source </a>
''')
clooney = io.imread('./data/george_small.jpg') / 255
me = io.imread('./data/not clooney.jpg')
md = me
me = resize(me[:, :3050], clooney.shape, anti_aliasing=True)
def show_vertical(imgs, names, h=None, w=None):
if h != None and w != None:
f = plt.figure(figsize=(w,h))
else: f = plt.figure(figsize=(len(imgs) * 4, 4))
for i in range(1, 1 + len(imgs)):
ax = f.add_subplot(1,len(imgs), i)
ax.imshow(imgs[i-1])
ax.title.set_text(names[i-1])
plt.show()
show_vertical([clooney, me], ['George', 'Not George'])
cp = np.load('data/clooney_points.npy')
mp = np.load('data/me_points.npy')
cp = np.append(cp, [[0,0],[601,0], [0,749], [601, 749]], axis=0)
mp = np.append(mp, [[0,0],[601,0], [0,749], [601, 749]], axis=0)
def plot(im, pts, n):
f = plt.figure(figsize=(len(im) * 4, 4))
for i in range(0, len(im)):
ax = f.add_subplot(1,len(im), i+1)
ax.imshow(im[i])
ax.title.set_text(n[i])
xs = [p[0] for p in pts[i]]
ys = [p[1] for p in pts[i]]
plt.plot(xs,ys, 'r+', mew='20')
plot([clooney, me], [cp, mp],['clooney', 'me'])
plt.imshow(io.imread('output/30.png'))
I think that for this photo, I chose too many points. Here if the full gif:
Compare this to the gif I made for the bells and whistles, which had significantly fewer points
The gif with less points looks to be slightly more natural at first glance, which the transition seeming smoother due to lack of small triangle artifacts present in the first image. A careful look, however, reveals certain losses of detail: The eyebrows and hair crossfade in instead of reshaping.
import os
imgs = []
pts = []
for p in range(5,41):
fname = "data/danes/{:02d}-1{}"
if os.path.exists(fname.format(p,'m.jpg')):
fn = fname.format(p,'m')
else:
fn = fname.format(p,'f')
imgs.append(io.imread(fn + '.jpg'))
asf = fn +'.asf'
with open(asf) as f:
while(f.readable()):
n = f.readline()
if n != '\n' and n[0] != '#':
n = int(n[:-1])
break
ipts = []
while(n > 0 and f.readable()):
l = f.readline()
if l != '\n' and l[0] != '#':
tmp = np.array([float(i) for i in l.split('\t')])
ipts.append( (tmp[2] * imgs[0].shape[1], tmp[3] * imgs[0].shape[0]))
n-=1
my = imgs[0].shape[0]
mx = imgs[0].shape[1]
ipts.extend([(0,0), (0, my-1), (mx-1, 0), (mx-1,my-1)])
pts.append(ipts)
pts = np.array(pts)
imgs = np.array(imgs)
avg = np.mean(imgs, axis=0)
plt.imshow(avg/255)
Some interesting things to note: A lot of the high frequency features go away before transforming into the negative - while the actual face is thin, the neutral face lacks a definite shape and the ultravague shape has a super broad jawline
Link to the Bells & Whistles
https://www.youtube.com/watch?v=sTT0-nN3vtc&feature=youtu.be