In [ ]:
import menpo.io as mio

image1 = mio.import_builtin_asset.takeo_ppm()
image1.crop_to_landmarks_proportion_inplace(0.3)
image1 = image1.as_greyscale()

image2 = mio.import_builtin_asset.breakingbad_jpg()
image2.crop_to_landmarks_proportion_inplace(0.3)

%matplotlib inline
image2.view_landmarks()

In [ ]:
from cvpr15.utils import build_patches_image, vectorize_patches_image
from menpo.image import Image

def warp2(image, centres, patch_shape):
    r"""
    Warp function F: It extracts the patches around each shape point
    returns an image object of size:
    n_points x patch_shape[0] x patch_shape[1] x n_channels
    """
    return build_patches_image(image, centres, patch_shape)

def vectorize2(patches_image):
    r"""
    Vectorization function A: It vectorizes a given patches image.
    Returns an ndarray of size:
    (n_points * patch_shape[0] * patch_shape[1] * n_channels) x 1
    """
    return vectorize_patches_image(patches_image)

def gradient2(patches):
    r"""
    Returns the gradients of the patches
    n_dims x n_channels x n_points x (w x h)
    """
    n_points = patches.pixels.shape[0]
    h = patches.pixels.shape[1]
    w = patches.pixels.shape[2]
    n_channels = patches.pixels.shape[3]
    
    # initial patches: n_parts x height x width x n_channels
    pixels = patches.pixels
    # move parts axis to end: height x width x n_channels x n_parts
    pixels = np.rollaxis(pixels, 0, pixels.ndim)
    # merge channels and parts axes: height x width x (n_channels * n_parts)
    pixels = np.reshape(pixels, (h, w, -1), order='F')
    # compute and vectorize gradient: (height * width) x (n_channels * n_parts * n_dims)
    g = Image(pixels).gradient().as_vector(keep_channels=True)
    # reshape gradient: (height * width) x n_parts x n_channels x n_dims
    # then trnspose it: n_dims x n_channels x n_parts x (height * width)
    return np.reshape(g, (-1, n_points, n_channels, 2)).T

In [ ]:
%matplotlib inline
import menpo.io as mio
from menpo.feature import no_op, igo, hog, sparse_hog

# method to load a database
def load_database(path_to_images, crop_percentage, max_images=None):
    images = []
    # load landmarked images
    for i in mio.import_images(path_to_images, max_images=max_images, verbose=True):
        # crop image
        i.crop_to_landmarks_proportion_inplace(crop_percentage)
        
        # convert it to grayscale if needed
        if i.n_channels == 4:
            i = i.as_greyscale(mode='luminosity')
            
        # append it to the list
        images.append(i)
    return images

In [ ]:
import numpy as np
from cvpr15 import APSBuilder
from cvpr15.fitter import LucasKanadeAPSFitter
from cvpr15.algorithm import Forward

training_images = load_database('/mnt/data/nontas/trainset/', 0.5)

adjacency_array = np.empty((67, 2), dtype=np.int32)
for i in range(68):
    if i < 34:
        adjacency_array[i, 0] = 34
        adjacency_array[i, 1] = i
    elif i > 34:
        adjacency_array[i-1, 0] = 34
        adjacency_array[i-1, 1] = i

root_vertex = 34

aps = APSBuilder(adjacency_array=adjacency_array, 
                 root_vertex=0, 
                 features=no_op, 
                 patch_shape=(6, 6),
                 normalization_diagonal=100,
                 n_levels=1, 
                 downscale=2, 
                 scaled_shape_models=True,
                 max_shape_components=None,
                 n_appearance_parameters=100).build(training_images, verbose=True)

fitter = LucasKanadeAPSFitter(aps, 
                              algorithm=Forward, 
                              n_shape=3)

ds_dp = np.rollaxis(fitter._fitters[0].transform.d_dp(None), -1)
print ds_dp.shape

In [ ]:
def steepest_descent_images(gradient, ds_dp):
    # compute steepest descent images
    # gradient: n_dims x n_channels x n_parts x (w x h)
    # ds_dp:    n_dims x            x n_parts x         x n_params
    # sdi:               n_channels x n_parts x (w x h) x n_params
    sdi = 0
    a = gradient[..., None] * ds_dp[..., None, :, None, :]
    for d in a:
        sdi += d
    # sdi: n_parts x n_channels x (w x h) x n_params
    sdi = np.rollaxis(sdi, 1, 0)
    # sdi: n_parts x (w x h) x n_channels x n_params
    sdi = np.rollaxis(sdi, 2, 1)
    # sdi: (n_parts * w * h * n_channels) x n_params
    return sdi.reshape((-1, sdi.shape[3]))

In [ ]:
image = image2
patch_shape = (17, 17)
n_channels = image.n_channels

In [ ]:
i2 = warp2(image, image.landmarks['PTS']['all'], patch_shape)
vec_i2 = vectorize2(i2)
#e1 = vec_i1 - self.appearance_model[0]
gradient = gradient2(i2)
print i2.pixels.shape
print vec_i2.shape
print gradient.shape

In [ ]:
import numpy as np

k = 37

l = np.prod(patch_shape) * n_channels
ind = np.arange(k * l, (k+1) * l, 1)
Image(vec_i2[ind].reshape(patch_shape[0], patch_shape[1], n_channels)).view()

c = 0
ind = np.arange(k * l + c, (k+1) * l, n_channels)
Image(vec_i2[ind].reshape(patch_shape[0], patch_shape[1])).view()

d = 1
c = 0
Image(gradient[d, c, k, :].reshape(patch_shape[0], patch_shape[1])).view_new()

In [ ]:
sdi = steepest_descent_images(gradient, ds_dp)
print sdi.shape

k = 37
c = 0
param = 6

l = np.prod(patch_shape) * n_channels
ind = np.arange(k * l + c, (k+1) * l, n_channels)
Image(sdi[ind, param].reshape(patch_shape[0], patch_shape[1])).view_new()

ind = np.arange(k * l, (k+1) * l, 1)
Image(sdi[ind, param].reshape(patch_shape[0], patch_shape[1], n_channels)).view_new()

In [ ]: