def test_init_from_edges(): g = PointDirectedGraph.init_from_edges( points, np.array([[1, 0], [2, 0], [1, 2], [2, 1], [1, 3], [2, 4], [3, 4], [3, 5]])) assert (pg_directed.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointUndirectedGraph.init_from_edges( points, np.array([[0, 1], [0, 2], [1, 2], [1, 3], [2, 4], [3, 4], [3, 5]])) assert (pg_undirected.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointUndirectedGraph.init_from_edges( points, np.array([[0, 1], [1, 0], [0, 2], [2, 0], [1, 2], [2, 1], [1, 3], [3, 1], [2, 4], [4, 2], [3, 4], [4, 3], [3, 5], [5, 3]])) assert (pg_undirected.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointTree.init_from_edges(points2, np.array([[0, 1], [0, 2], [1, 3], [1, 4], [2, 5], [3, 6], [4, 7], [5, 8]]), root_vertex=0) assert (pg_tree.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointUndirectedGraph.init_from_edges( points, np.array([[0, 2], [2, 4], [3, 4]])) assert (pg_isolated.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointDirectedGraph.init_from_edges(point, np.array([])) assert (pg_single.adjacency_matrix - g.adjacency_matrix).nnz == 0
def instance(self, shape_weights=None, scale_index=-1, as_graph=False): r""" Generates an instance of the shape model. Parameters ---------- shape_weights : ``(n_weights,)`` `ndarray` or `list` or ``None``, optional The weights of the shape model that will be used to create a novel shape instance. If ``None``, the weights are assumed to be zero, thus the mean shape is used. scale_index : `int`, optional The scale to be used. as_graph : `bool`, optional If ``True``, then the instance will be returned as a `menpo.shape.PointTree` or a `menpo.shape.PointDirectedGraph`, depending on the type of the deformation graph. """ if shape_weights is None: shape_weights = [0] sm = self.shape_models[scale_index].model shape_instance = sm.instance(shape_weights, normalized_weights=True) if as_graph: if isinstance(self.deformation_graph[scale_index], Tree): shape_instance = PointTree( shape_instance.points, self.deformation_graph[scale_index].adjacency_matrix, self.deformation_graph[scale_index].root_vertex) else: shape_instance = PointDirectedGraph( shape_instance.points, self.deformation_graph[scale_index].adjacency_matrix) return shape_instance
def test_init_2d_grid(): g = PointTree.init_2d_grid((5, 5)) assert g.adjacency_matrix.nnz == 24 assert g.n_points == 25 g = PointUndirectedGraph.init_2d_grid((5, 5)) assert g.adjacency_matrix.nnz == 80 assert g.n_points == 25 g = PointDirectedGraph.init_2d_grid((5, 5)) assert g.adjacency_matrix.nnz == 80 assert g.n_points == 25
def view_deformation_graph_widget(self, scale_index=-1, figure_size=(7, 7)): r""" Visualize the deformation graph using an interactive widget. Parameters ---------- scale_index : `int`, optional The scale to be used. figure_size : (`int`, `int`), optional The size of the rendered figure. """ if isinstance(self.deformation_graph[scale_index], Tree): dg = PointTree(self.shape_models[scale_index].model.mean().points, self.deformation_graph[scale_index].adjacency_matrix, self.deformation_graph[scale_index].root_vertex) else: dg = PointDirectedGraph( self.shape_models[scale_index].model.mean().points, self.deformation_graph[scale_index].adjacency_matrix) dg.view_widget(figure_size=figure_size)
def test_init_2d_grid_custom_adjacency(): tree_adj = np.array([[0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0], [0, 0, 1, 0]]) g = PointTree.init_2d_grid((2, 2), root_vertex=0, adjacency_matrix=tree_adj) assert g.adjacency_matrix.nnz == 3 assert g.n_points == 4 single_edge = lil_matrix((25, 25)) single_edge[[0, 1], [1, 0]] = 1 single_edge = single_edge.tocsr() g = PointUndirectedGraph.init_2d_grid((5, 5), adjacency_matrix=single_edge) assert g.adjacency_matrix.nnz == 2 assert g.n_points == 25 g = PointDirectedGraph.init_2d_grid((5, 5), adjacency_matrix=single_edge) assert g.adjacency_matrix.nnz == 2 assert g.n_points == 25
def test_init_from_depth_image(): fake_z = np.random.uniform(size=(10, 10)) g = PointTree.init_from_depth_image(Image(fake_z)) assert g.n_dims == 3 assert g.root_vertex == 55 assert g.adjacency_matrix.nnz == 99 assert g.n_points == 100 g = PointUndirectedGraph.init_from_depth_image(Image(fake_z)) assert g.n_dims == 3 assert g.adjacency_matrix.nnz == 360 assert g.n_points == 100 g = PointDirectedGraph.init_from_depth_image(Image(fake_z)) assert g.n_dims == 3 assert g.adjacency_matrix.nnz == 360 assert g.n_points == 100
def test_init_from_depth_image_masked(): fake_z = np.random.uniform(size=(10, 10)) mask = np.zeros(fake_z.shape, dtype=np.bool) mask[2:6, 2:6] = True im = MaskedImage(fake_z, mask=mask) g = PointTree.init_from_depth_image(im) assert g.n_dims == 3 assert g.root_vertex == 0 assert g.adjacency_matrix.nnz == 15 assert g.n_points == 16 g = PointUndirectedGraph.init_from_depth_image(im) assert g.n_dims == 3 assert g.adjacency_matrix.nnz == 48 assert g.n_points == 16 g = PointDirectedGraph.init_from_depth_image(im) assert g.n_dims == 3 assert g.adjacency_matrix.nnz == 48 assert g.n_points == 16
def test_init_2d_grid_custom_adjacency(): tree_adj = np.array([[0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0], [0, 0, 1, 0]]) g = PointTree.init_2d_grid((2, 2), root_vertex=0, adjacency_matrix=tree_adj) assert g.adjacency_matrix.nnz == 3 assert g.n_points == 4 single_edge = lil_matrix((25, 25)) single_edge[[0, 1], [1, 0]] = 1 single_edge = single_edge.tocsr() g = PointUndirectedGraph.init_2d_grid( (5, 5), adjacency_matrix=single_edge) assert g.adjacency_matrix.nnz == 2 assert g.n_points == 25 g = PointDirectedGraph.init_2d_grid( (5, 5), adjacency_matrix=single_edge) assert g.adjacency_matrix.nnz == 2 assert g.n_points == 25
def random_instance(self, level=-1, as_graph=False): r""" """ sm = self.shape_models[level] shape_weights = (np.random.randn(sm.n_active_components) * sm.eigenvalues[:sm.n_active_components]**0.5) shape_instance = sm.instance(shape_weights) if as_graph: if isinstance(self.graph_deformation, Tree): shape_instance = PointTree( shape_instance.points, self.graph_deformation.adjacency_array, self.graph_deformation.root_vertex) else: shape_instance = PointDirectedGraph( shape_instance.points, self.graph_deformation.adjacency_array) return shape_instance
def instance(self, shape_weights=None, level=-1, as_graph=False): r""" """ sm = self.shape_models[level] if shape_weights is None: shape_weights = [0] n_shape_weights = len(shape_weights) shape_weights *= sm.eigenvalues[:n_shape_weights] ** 0.5 shape_instance = sm.instance(shape_weights) if as_graph: if isinstance(self.graph_deformation, Tree): shape_instance = PointTree( shape_instance.points, self.graph_deformation.adjacency_array, self.graph_deformation.root_vertex) else: shape_instance = PointDirectedGraph( shape_instance.points, self.graph_deformation.adjacency_array) return shape_instance
def _get_relative_locations(shapes, graph, level_str, verbose): r""" returns numpy.array of size 2 x n_images x n_edges """ # convert given shapes to point graphs if isinstance(graph, Tree): point_graphs = [ PointTree(shape.points, graph.adjacency_array, graph.root_vertex) for shape in shapes ] else: point_graphs = [ PointDirectedGraph(shape.points, graph.adjacency_array) for shape in shapes ] # initialize an output numpy array rel_loc_array = np.empty((2, graph.n_edges, len(point_graphs))) # get relative locations for c, pt in enumerate(point_graphs): # print progress if verbose: print_dynamic('{}Computing relative locations from ' 'shapes - {}'.format( level_str, progress_bar_str(float(c + 1) / len(point_graphs), show_bar=False))) # get relative locations from this shape rl = pt.relative_locations() # store rel_loc_array[..., c] = rl.T # rollaxis and return return np.rollaxis(rel_loc_array, 2, 1)
def test_init_from_edges(): g = PointDirectedGraph.init_from_edges( points, np.array([[1, 0], [2, 0], [1, 2], [2, 1], [1, 3], [2, 4], [3, 4], [3, 5]])) assert (pg_directed.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointUndirectedGraph.init_from_edges( points, np.array([[0, 1], [0, 2], [1, 2], [1, 3], [2, 4], [3, 4], [3, 5]])) assert (pg_undirected.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointUndirectedGraph.init_from_edges( points, np.array([[0, 1], [1, 0], [0, 2], [2, 0], [1, 2], [2, 1], [1, 3], [3, 1], [2, 4], [4, 2], [3, 4], [4, 3], [3, 5], [5, 3]])) assert (pg_undirected.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointTree.init_from_edges( points2, np.array([[0, 1], [0, 2], [1, 3], [1, 4], [2, 5], [3, 6], [4, 7], [5, 8]]), root_vertex=0) assert (pg_tree.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointUndirectedGraph.init_from_edges( points, np.array([[0, 2], [2, 4], [3, 4]])) assert (pg_isolated.adjacency_matrix - g.adjacency_matrix).nnz == 0 g = PointDirectedGraph.init_from_edges(point, np.array([])) assert (pg_single.adjacency_matrix - g.adjacency_matrix).nnz == 0
def plot_deformation_model(aps, level, n_std): mean_shape = aps.shape_models[level].mean().points for e in range(aps.graph_deformation.n_edges): # find vertices parent = aps.graph_deformation.adjacency_array[e, 0] child = aps.graph_deformation.adjacency_array[e, 1] # relative location mean rel_loc_mean = mean_shape[child, :] - mean_shape[parent, :] # relative location cov n_points = aps.deformation_models[0].shape[0] / 2 s1 = -aps.deformation_models[level][2 * child, 2 * parent] s2 = -aps.deformation_models[level][2 * child + 1, 2 * parent + 1] s3 = -aps.deformation_models[level][2 * child, 2 * parent + 1] cov_mat = np.linalg.inv(np.array([[s1, s3], [s3, s2]])) # plot ellipse plot_gaussian_ellipse(cov_mat, mean_shape[parent, :] + rel_loc_mean, n_std=n_std, facecolor='none', edgecolor='r') # plot mean shape points plt.scatter(aps.shape_models[level].mean().points[:, 0], aps.shape_models[level].mean().points[:, 1]) #aps.shape_models[level].mean().pointsview_on(plt.gcf().number) # create and plot edge connections if isinstance(aps.graph_deformation, Tree): PointTree(mean_shape, aps.graph_deformation.adjacency_array, aps.graph_deformation.root_vertex).view_on(plt.gcf().number) else: PointDirectedGraph(mean_shape, aps.graph_deformation.adjacency_array).view_on( plt.gcf().number)
def view_deformation_model(self, scale_index=-1, n_std=2, render_colour_bar=False, colour_map='jet', image_view=True, figure_id=None, new_figure=False, render_graph_lines=True, graph_line_colour='b', graph_line_style='-', graph_line_width=1., ellipse_line_colour='r', ellipse_line_style='-', ellipse_line_width=1., render_markers=True, marker_style='o', marker_size=5, marker_face_colour='k', marker_edge_colour='k', marker_edge_width=1., render_axes=False, axes_font_name='sans-serif', axes_font_size=10, axes_font_style='normal', axes_font_weight='normal', crop_proportion=0.1, figure_size=(10, 8)): r""" Visualize the deformation model by plotting a Gaussian ellipsis per graph edge. Parameters ---------- scale_index : `int`, optional The scale to be used. n_std : `float`, optional This defines the size of the ellipses in terms of number of standard deviations. render_colour_bar : `bool`, optional If ``True``, then the ellipses will be coloured based on their normalized standard deviations and a colour bar will also appear on the side. If ``False``, then all the ellipses will have the same colour. colour_map : `str`, optional A valid Matplotlib colour map. For more info, please refer to `matplotlib.cm`. image_view : `bool`, optional If ``True`` the ellipses will be rendered in the image coordinates system. figure_id : `object`, optional The id of the figure to be used. new_figure : `bool`, optional If ``True``, a new figure is created. render_graph_lines : `bool`, optional Defines whether to plot the graph's edges. graph_line_colour : See Below, optional The colour of the lines of the graph's edges. Example options:: {r, g, b, c, m, k, w} or (3, ) ndarray graph_line_style : ``{-, --, -., :}``, optional The style of the lines of the graph's edges. graph_line_width : `float`, optional The width of the lines of the graph's edges. ellipse_line_colour : See Below, optional The colour of the lines of the ellipses. Example options:: {r, g, b, c, m, k, w} or (3, ) ndarray ellipse_line_style : ``{-, --, -., :}``, optional The style of the lines of the ellipses. ellipse_line_width : `float`, optional The width of the lines of the ellipses. render_markers : `bool`, optional If ``True``, the centers of the ellipses will be rendered. marker_style : See Below, optional The style of the centers of the ellipses. Example options :: {., ,, o, v, ^, <, >, +, x, D, d, s, p, *, h, H, 1, 2, 3, 4, 8} marker_size : `int`, optional The size of the centers of the ellipses in points. marker_face_colour : See Below, optional The face (filling) colour of the centers of the ellipses. Example options :: {r, g, b, c, m, k, w} or (3, ) ndarray marker_edge_colour : See Below, optional The edge colour of the centers of the ellipses. Example options :: {r, g, b, c, m, k, w} or (3, ) ndarray marker_edge_width : `float`, optional The edge width of the centers of the ellipses. render_axes : `bool`, optional If ``True``, the axes will be rendered. axes_font_name : See Below, optional The font of the axes. Example options :: {serif, sans-serif, cursive, fantasy, monospace} axes_font_size : `int`, optional The font size of the axes. axes_font_style : ``{normal, italic, oblique}``, optional The font style of the axes. axes_font_weight : See Below, optional The font weight of the axes. Example options :: {ultralight, light, normal, regular, book, medium, roman, semibold,demibold, demi, bold, heavy, extra bold, black} crop_proportion : `float`, optional The proportion to be left around the centers' pointcloud. figure_size : (`float`, `float`) `tuple` or ``None`` optional The size of the figure in inches. """ from menpo.visualize import plot_gaussian_ellipses mean_shape = self.shape_models[scale_index].model.mean().points deformation_graph = self.deformation_graph[scale_index] # get covariance matrices covariances = [] means = [] for e in range(deformation_graph.n_edges): # find vertices parent = deformation_graph.edges[e, 0] child = deformation_graph.edges[e, 1] # relative location mean means.append(mean_shape[child, :]) # relative location cov s1 = -self.deformation_models[scale_index].precision[2 * child, 2 * parent] s2 = -self.deformation_models[scale_index].precision[2 * child + 1, 2 * parent + 1] s3 = -self.deformation_models[scale_index].precision[2 * child, 2 * parent + 1] covariances.append(np.linalg.inv(np.array([[s1, s3], [s3, s2]]))) # plot deformation graph if isinstance(deformation_graph, Tree): renderer = PointTree(mean_shape, deformation_graph.adjacency_matrix, deformation_graph.root_vertex).view( figure_id=figure_id, new_figure=new_figure, image_view=image_view, render_lines=render_graph_lines, line_colour=graph_line_colour, line_style=graph_line_style, line_width=graph_line_width, render_markers=render_markers, marker_style=marker_style, marker_size=marker_size, marker_face_colour=marker_face_colour, marker_edge_colour=marker_edge_colour, marker_edge_width=marker_edge_width, render_axes=render_axes, axes_font_name=axes_font_name, axes_font_size=axes_font_size, axes_font_style=axes_font_style, axes_font_weight=axes_font_weight, figure_size=figure_size) else: renderer = PointDirectedGraph( mean_shape, deformation_graph.adjacency_matrix).view( figure_id=figure_id, new_figure=new_figure, image_view=image_view, render_lines=render_graph_lines, line_colour=graph_line_colour, line_style=graph_line_style, line_width=graph_line_width, render_markers=render_markers, marker_style=marker_style, marker_size=marker_size, marker_face_colour=marker_face_colour, marker_edge_colour=marker_edge_colour, marker_edge_width=marker_edge_width, render_axes=render_axes, axes_font_name=axes_font_name, axes_font_size=axes_font_size, axes_font_style=axes_font_style, axes_font_weight=axes_font_weight, figure_size=figure_size) # plot ellipses renderer = plot_gaussian_ellipses( covariances, means, n_std=n_std, render_colour_bar=render_colour_bar, colour_bar_label='Normalized Standard Deviation', colour_map=colour_map, figure_id=renderer.figure_id, new_figure=False, image_view=image_view, line_colour=ellipse_line_colour, line_style=ellipse_line_style, line_width=ellipse_line_width, render_markers=render_markers, marker_edge_colour=marker_edge_colour, marker_face_colour=marker_face_colour, marker_edge_width=marker_edge_width, marker_size=marker_size, marker_style=marker_style, render_axes=render_axes, axes_font_name=axes_font_name, axes_font_size=axes_font_size, axes_font_style=axes_font_style, axes_font_weight=axes_font_weight, crop_proportion=crop_proportion, figure_size=figure_size) return renderer
# Define tree and pointtree adj_tree = np.array( [ [0, 1, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], ] ) g_tree = Tree(adj_tree, 0) pg_tree = PointTree(points2, adj_tree, 0) # Define undirected graph and pointgraph with isolated vertices adj_isolated = csr_matrix( ([1] * 6, ([0, 2, 2, 4, 3, 4], [2, 0, 4, 2, 4, 3])), shape=(6, 6) ) g_isolated = UndirectedGraph(adj_isolated) pg_isolated = PointUndirectedGraph(points, adj_isolated) # Define undirected graph and pointgraph with a single vertex adj_single = np.array([[0]]) g_single = DirectedGraph(adj_single) pg_single = PointDirectedGraph(point, adj_single) def test_create_graph_exception():