Commit f7da1d93 authored by Richard Torenvliet's avatar Richard Torenvliet

Refactoring a bit

parent 3c33b0b3
......@@ -6,7 +6,9 @@ data/imm_face_db: data/imm_face_db.tar.gz
tar -xvzf imm_face_db.tar.gz -C imm_face_db
)
train_model: data/pca_shape_model.npy data/pca_texture_model.npy
train_model:train_shape
train_texture: data/pca_texture_model.npy
train_shape: data/pca_shape_model.npy
data/imm_face_db.tar.gz:
(cd data; wget http://www.imm.dtu.dk/~aam/datasets/imm_face_db.tar.gz)
......
......@@ -84,16 +84,16 @@ def save_pca_model_texture(args):
assert args.model_shape_file, '--model_texture_file needs to be provided to save the pca model'
assert args.model_texture_file, '--model_texture_file needs to be provided to save the pca model'
Vt, s, mean_shape, triangles = pca.load(args.model_shape_file)
Vt, s, n_components, mean_shape, triangles = pca.load(args.model_shape_file)
textures = aam.build_texture_feature_vectors(
args.files, imm.get_imm_image_with_landmarks, mean_shape, triangles
)
mean_texture = aam.get_mean(textures)
_, s, Vt = pca.pca(textures, mean_texture)
_, s, Vt, n_components = pca.pca(textures, mean_texture)
pca.save(Vt, s, mean_texture, triangles, args.model_texture_file)
pca.save(Vt, s, n_components, mean_texture, triangles, args.model_texture_file)
logger.info('texture pca model saved in %s', args.model_texture_file)
......@@ -123,12 +123,12 @@ def save_pca_model_shape(args):
mean_values = aam.get_mean(points)
_, s, Vt = pca.pca(points, mean_values)
_, s, Vt, n_components = pca.pca(points, mean_values)
mean_xy = mean_values.reshape((-1, 2))
triangles = aam.get_triangles(mean_xy[:, 0], mean_xy[:, 1])
pca.save(Vt, s, mean_values, triangles, args.model_shape_file)
pca.save(Vt, s, n_components, mean_values, triangles, args.model_shape_file)
logger.info('shape pca model saved in %s', args.model_shape_file + '_shape')
......@@ -142,8 +142,9 @@ def reconstruct_with_model(args):
sys.argv[1:] = []
from view.reconstruct import ReconstructApp
Vt_shape, mean_values_shape, triangles = pca.load(args.model_shape_file)
Vt_texture, mean_values_texture, _ = pca.load(args.model_texture_file)
Vt_shape, s, n_shape_components, mean_values_shape, triangles = pca.load(args.model_shape_file)
Vt_texture, s_texture, n_texture_components, mean_values_texture, _ = pca.load(args.model_texture_file)
app = ReconstructApp()
......@@ -152,7 +153,9 @@ def reconstruct_with_model(args):
eigenv_shape=Vt_shape,
eigenv_texture=Vt_texture,
mean_values_shape=mean_values_shape,
n_shape_components=n_shape_components,
mean_values_texture=mean_values_texture,
n_texture_components=n_texture_components,
triangles=triangles
)
......@@ -165,19 +168,8 @@ def show_pca_model(args):
from utils.triangles import draw_shape, draw_texture
Vt_shape, s, mean_values_shape, triangles = pca.load(args.model_shape_file)
Vt_texture, s_texture, mean_values_texture, _ = pca.load(args.model_texture_file)
# calculate n_components which captures 90 percent of the variance
total = s_texture.sum()
subtotal = 0.0
i = 0
while (subtotal * 100.0) / total <= 90.0:
subtotal += s_texture[i]
i += 1
n_components = i
Vt_shape, s, n_shape_components, mean_values_shape, triangles = pca.load(args.model_shape_file)
Vt_texture, s_texture, n_texture_components, mean_values_texture, _ = pca.load(args.model_texture_file)
image = np.full((480, 640, 3), fill_value=255, dtype=np.uint8)
......@@ -195,7 +187,7 @@ def show_pca_model(args):
while True:
draw_texture(input_image, image, Vt_texture, input_points, mean_values_shape,
mean_values_texture, triangles)
mean_values_texture, triangles, n_texture_components)
#draw_shape(image, mean_values_shape, triangles, multiply=False)
cv2.imshow('input_image', input_image)
......
import numpy as np
def pca(data, mean_values):
def pca(data, mean_values, variance_percentage=90):
"""
Perform Singlar Value Decomposition
......@@ -14,10 +14,21 @@ def pca(data, mean_values):
zero_mean = data - mean_values
U, s, Vt = np.linalg.svd(zero_mean, full_matrices=False)
return U, s, Vt
# calculate n_components which captures 90 percent of the variance
total = s.sum()
subtotal = 0.0
i = 0
while (subtotal * 100.0) / total <= variance_percentage:
subtotal += s[i]
i += 1
def reconstruct(feature_vector, Vt, mean_values, n_components=10):
n_components = i
return U, s, Vt, n_components
def reconstruct(feature_vector, Vt, mean_values, n_components=None):
"""
Reconstruct with U, s, Vt
......@@ -28,15 +39,18 @@ def reconstruct(feature_vector, Vt, mean_values, n_components=10):
Vt (numpy ndarray): Two dimensional array with dimensions
(n_features, n_features)
mean_values (numpy ndarray): mean values of the features of the model,
this should have dimensions (n_featurs, )
this should have dimensions (n_features, )
"""
if n_components is None:
n_components = Vt.shape[1]
zm = feature_vector - mean_values
yk = np.dot(Vt[:n_components], zm.T)
return np.dot(Vt[:n_components].T, yk) + mean_values
def save(Vt, s, mean_values, triangles, filename):
def save(Vt, s, n_components, mean_values, triangles, filename):
"""
Store the U, s, Vt and mean of all the asf datafiles given by the asf
files.
......@@ -52,7 +66,7 @@ def save(Vt, s, mean_values, triangles, filename):
triangles = Vtm[2]
"""
saving = np.asarray([Vt, s, [mean_values], triangles])
saving = np.asarray([Vt, s, n_components, [mean_values], triangles])
np.save(filename, saving)
......@@ -77,10 +91,11 @@ def load(filename):
Vt = Vtm[0]
s = Vtm[1]
mean_values = Vtm[2][0]
triangles = Vtm[3]
n_components = Vtm[2]
mean_values = Vtm[3][0]
triangles = Vtm[4]
return Vt, s, mean_values, triangles
return Vt, s, n_components, mean_values, triangles
def flatten_feature_vectors(data, dim=0):
......
......@@ -67,7 +67,7 @@ def draw_shape(image, points, triangles, multiply=True):
cv2.circle(image, tuple(p), 3, color=(0, 255, 100))
def draw_texture(src, dest, Vt, points2d_src, points2d_dst, texture, triangles):
def draw_texture(src, dest, Vt, points2d_src, points2d_dst, texture, triangles, n_components):
# texture = np.asarray(texture, dtype=np.uint8).reshape((-1, 3))
texture = np.asarray(texture, np.uint8)
offset = 0
......
......@@ -20,6 +20,8 @@ from functools import partial
from math import cos, sin, pi
import imm_points as imm
from utils.triangles import draw_texture
from utils.generate_head_texture import fill_triangle
#import IMMPoints, build_feature_vectors, \
# flatten_feature_vectors
import pca
......@@ -76,48 +78,53 @@ class ImageCanvas(Widget):
self.canvas.ask_update()
def build_texture(self, r_shape, r_texture, triangles):
self.texture.clear()
return
#self.texture.clear()
image_width, image_height = self.get_rendered_size()
#image_width, image_height = self.get_rendered_size()
bary_centric_range = np.linspace(0, 1, num=20)
texture = Texture.create(size=(image_width, image_height), colorfmt='bgr')
buf = np.zeros((image_width, image_height, 3), dtype=np.uint8)
#bary_centric_range = np.linspace(0, 1, num=20)
#texture = Texture.create(size=(image_width, image_height), colorfmt='bgr')
#buf = np.zeros((image_width, image_height, 3), dtype=np.uint8)
for tri in triangles[:1]:
points = r_shape[tri]
pixels = r_texture[tri].reshape((-1, 3))
#offset = 0
x = points[:, 0] * image_width + self.get_image_left(image_width)
y = (1.0 - points[:, 1]) * image_height + self.get_image_bottom(image_height)
#for t, tri in enumerate(triangles):
# src_p1, src_p2, src_p3 = r_shape[tri]
# x = r_shape[:, 0] * image_width + self.get_image_left(image_width)
# y = (1.0 - r_shape[:, 1]) * image_height + self.get_image_bottom(image_height)
p1 = [x[0], y[0]]
p2 = [x[1], y[1]]
p3 = [x[2], y[2]]
# for t, tri in enumerate(triangles):
# offset += fill_triangle(
# r_texture, buf,
# src_p1[0], src_p1[1],
# src_p2[0], src_p2[1],
# src_p3[0], src_p3[1],
# dst_p1[0], dst_p1[1],
# dst_p2[0], dst_p2[1],
# dst_p3[0], dst_p3[1],
# offset,
# t
# )
L = np.zeros((3, 1))
# print offset
for s_i, s in enumerate(bary_centric_range):
for t_i, t in enumerate(bary_centric_range):
if s + t <= 1:
# build lambda's
L[0] = s
L[1] = t
L[2] = 1 - s - t
# #p1 = [x[0], y[0]]
# #p2 = [x[1], y[1]]
# #p3 = [x[2], y[2]]
cart_x, cart_y, _ = aam.barycentric2cartesian(p1, p2, p3, L)
buf[s_i, t_i, :] = pixels[s_i * 20 + t_i, :]
#buf = b''.join(map(chr, buf))
cv2.imshow('image', buf)
cv2.waitKey(0)
##buf = b''.join(map(chr, buf))
#cv2.imshow('image', buf)
#cv2.waitKey(0)
#texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
#self.texture.add(Rectangle(texture=texture, pos=(0, 100),
# size=(image_width, image_height)))
self.canvas.add(self.texture)
self.canvas.ask_update()
#self.canvas.add(self.texture)
#self.canvas.ask_update()
def build_line_grid(self, r_shape, triangles):
......@@ -175,28 +182,40 @@ class RootWidget(BoxLayout):
self.eigenv_shape = kwargs['eigenv_shape']
self.eigenv_texture = kwargs['eigenv_texture']
self.triangles = kwargs['triangles']
self.n_components = kwargs['args'].n_components
self.n_shape_components = kwargs['args'].n_components
self.n_texture_components = kwargs['n_texture_components']
self.multipliers = np.ones(self.eigenv_shape.shape[1])
self.mean_values_shape_reshaped = np.copy(self.mean_values_shape).reshape((58, 2))
# slider index
self.index = 0
self.filename = ''
self.shape_list = aam.build_shape_feature_vectors(self.files, imm.get_imm_points, flattened=True)
# sliders
self.add_shape_sliders()
self.add_image_slider()
self.add_components_slider()
# ======= #
# event binders
self.ids['image_viewer'].bind(size=self.on_resize)
def add_components_slider(self):
n_components_slider = self.ids['n_shape_components']
n_components_slider.value = self.n_shape_components
n_components_slider.bind(value=self.update_n_components)
def add_image_slider(self):
image_slider = self.ids['image_slider']
image_slider.max = len(self.files) - 1
image_slider.bind(value=self.update_image)
n_components_slider = self.ids['n_components']
n_components_slider.value = self.n_components
n_components_slider.bind(value=self.update_n_components)
self.ids['image_viewer'].bind(size=self.on_resize)
def add_shape_sliders(self):
box_layout = self.ids['eigenvalues']
self.shape_list = aam.build_shape_feature_vectors(
self.files, imm.get_imm_points, flattened=True)
for c in range(self.n_components):
for c in range(self.n_shape_components):
slider = Slider(min=-10, max=10, value=0, id=str(c))
box_layout.add_widget(slider)
slider.bind(value=self.update_eigenvalues)
......@@ -215,10 +234,26 @@ class RootWidget(BoxLayout):
r_shape = pca.reconstruct(
self.shape_list[self.index], Vt_shape, self.mean_values_shape,
n_components=self.n_components
n_components=self.n_shape_components
).reshape((-1, 2))
# image = cv2.imread(self.filename)
#image = cv2.imread(self.filename)
#h, w = image.shape[0], image.shape[1]
#mean_values_shape = np.copy(self.mean_values_shape_reshaped)
#mean_values_shape[:, 0] = mean_values_shape[:, 0] * w
#mean_values_shape[:, 1] = mean_values_shape[:, 1] * h
#texture = aam.sample_from_triangles(
# image, r_shape, mean_values_shape, self.triangles
#)
#r_texture = pca.reconstruct(
# texture, self.eigenv_texture, self.mean_values_texture
#)
#r_texture = np.asarray(texture, np.uint8)
# pixels = aam.sample_from_triangles(image, r_shape, self.triangles)
# pixels = np.ndarray.flatten(pixels)
......@@ -230,12 +265,13 @@ class RootWidget(BoxLayout):
self.ids['image_viewer'].update_rect()
self.ids['image_viewer'].update_image(self.filename)
self.ids['image_viewer'].build_line_grid(r_shape, self.triangles)
#self.ids['image_viewer'].build_texture(r_shape, r_texture, self.triangles)
def on_resize(self, *args):
self.update_image_viewer()
def update_n_components(self, slider, index):
self.n_components = int(index)
self.n_shape_components = int(index)
self.update_image_viewer()
def update_image(self, slider, index):
......@@ -265,7 +301,9 @@ class ReconstructApp(App):
eigenv_shape=self.eigenv_shape,
eigenv_texture=self.eigenv_texture,
mean_values_shape=self.mean_values_shape,
n_shape_components=self.n_shape_components,
mean_values_texture=self.mean_values_texture,
n_texture_components=self.n_texture_components,
triangles=self.triangles
)
......
......@@ -27,9 +27,9 @@
max: 100
value: 0
Label:
text: "Using {} components".format(int(n_components.value))
text: "Using {} components".format(int(n_shape_components.value))
Slider:
id: n_components
id: n_shape_components
min: 0
max: 58
value: 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment