Source code for reconstruction.reconstruction

import cv2
import numpy as np

import pca
import aam
from .texture import fill_triangle_src_dst


[docs]def cartesian2barycentric(r1, r2, r3, r): """ Given a triangle spanned by three cartesion points r1, r2, r2, and point r, return the barycentric weights l1, l2, l3. Returns: ndarray (of dim 3) weights of the barycentric coordinates """ x, y = r x1, y1 = r1 x2, y2 = r2 x3, y3 = r3 a = np.array([[x1, x2, x3], [y1, y2, y3], [1, 1, 1]]) b = np.array([x, y, 1]) return np.linalg.solve(a, b)
[docs]def barycentric2cartesian(r1, r2, r3, L): """ Given the barycentric weights in L, and cartesian r1, r2, r3 coordinates of points that span the triangle, return the cartesian coordinate of the points that is located at the weights of L. Returns: ndarray [x,y] cartesian points. """ x1, y1 = r1 x2, y2 = r2 x3, y3 = r3 a = np.array([[x1, x2, x3], [y1, y2, y3], [1, 1, 1]]) b = np.array(L) return np.asarray(np.dot(a, b), dtype=np.uint32)
def draw_shape(image, points, triangles, multiply=True): if multiply: h, w, c = image.shape points[:, 0] = points[:, 0] * w points[:, 1] = points[:, 1] * h dim, _ = points.shape point_indices = list(range(0, dim)) for t, tri in enumerate(triangles): p1, p2, p3 = points[tri] cv2.line(image, tuple(p1), tuple(p2), (255, 0, 100), 1) cv2.line(image, tuple(p2), tuple(p3), (255, 0, 100), 1) cv2.line(image, tuple(p3), tuple(p1), (255, 0, 100), 1) for i, p in enumerate(points): point_index = int(point_indices[i]) cv2.putText(image, str(point_index), (p[0], p[1]), cv2.FONT_HERSHEY_SIMPLEX, .5, (100, 0, 255)) cv2.putText(image, str(i), (p[0], p[1]), cv2.FONT_HERSHEY_SIMPLEX, .5, (100, 0, 255)) cv2.circle(image, tuple(p), 3, color=(0, 255, 100)) def get_texture(Points, flattened_texture): offset_x, offset_y, w_slice, h_slice = Points.get_bounding_box() # Make a rectangle image from the flattened texture array return np.asarray(flattened_texture, np.uint8).reshape((h_slice, w_slice, 3))
[docs]def reconstruct_texture(src_image, dst_image, texture_model, src_points, dst_points): """ Recontruct texture given the src and dst image Args: src_points(aam.AAMPoints) dst_points(aam.AAMPoints) """ Vt = texture_model.Vt triangles = texture_model.triangles mean_texture = texture_model.mean_values # n_components = texture_model.n_components # S_mean format h, w, c = src_image.shape input_texture = np.full((h, w, 3), fill_value=0, dtype=np.uint8) points2d_src = src_points.get_scaled_points(src_image.shape) points2d_dst = dst_points.get_scaled_points(dst_image.shape) aam.sample_from_triangles( src_image, points2d_src, points2d_dst, triangles, input_texture ) offset_x, offset_y, w_slice, h_slice = dst_points.get_bounding_box() input_texture = input_texture[offset_y: offset_y + h_slice, offset_x: offset_x + w_slice].flatten() # Still in S_mean format r_texture = pca.reconstruct(input_texture, Vt, mean_texture) # Make an image from the float data r_texture = np.asarray(r_texture, np.uint8).reshape((h_slice, w_slice, 3)) # subtract the offset points2d_dst[:, 0] -= offset_x points2d_dst[:, 1] -= offset_y for tri in triangles: src_p1, src_p2, src_p3 = points2d_src[tri] dst_p1, dst_p2, dst_p3 = points2d_dst[tri] fill_triangle_src_dst( r_texture, dst_image, dst_p1[0], dst_p1[1], dst_p2[0], dst_p2[1], dst_p3[0], dst_p3[1], src_p1[0], src_p1[1], src_p2[0], src_p2[1], src_p3[0], src_p3[1] )