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 __init__(self, points, adjacency_matrix, labels_to_masks, copy=True, skip_checks=False): PointUndirectedGraph.__init__(self, points, adjacency_matrix, copy=copy, skip_checks=skip_checks) if not labels_to_masks: raise ValueError("Labelled point graphs are designed to be " "immutable. Empty label sets are not permitted.") if np.vstack(list( labels_to_masks.values())).shape[1] != points.shape[0]: raise ValueError("Each mask must have the same number of points " "as the given points.") if not isinstance(labels_to_masks, OrderedDict): raise ValueError("Must provide an OrderedDict to maintain the " "semantic meaning of the labels.") # Another sanity check self._labels_to_masks = labels_to_masks self._verify_all_labels_masked() if copy: self._labels_to_masks = OrderedDict([ (l, m.copy()) for l, m in labels_to_masks.items() ])
def car_streetscene_20_to_car_streetscene_view_5_10(pcloud): r""" Apply the 10-point semantic labels of "view 5" from the MIT Street Scene Car dataset (originally a 20-point markup). The semantic labels applied are as follows: - right_side References ---------- .. [1] http://www.cs.cmu.edu/~vboddeti/alignment.html """ from menpo.shape import PointUndirectedGraph n_expected_points = 20 validate_input(pcloud, n_expected_points) right_side_indices = np.array([0, 1, 2, 3, 4, 5, 6, 7, 9, 8]) right_side_connectivity = connectivity_from_array(right_side_indices, close_loop=True) all_connectivity = right_side_connectivity ind = np.array([1, 3, 5, 7, 9, 11, 13, 15, 17, 19]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points[ind], all_connectivity) mapping = OrderedDict() mapping['right_side'] = right_side_indices return new_pcloud, mapping
def eye_ibug_close_17_to_eye_ibug_close_17(pcloud): r""" Apply the IBUG 17-point close eye semantic labels. The semantic labels applied are as follows: - upper_eyelid - lower_eyelid """ from menpo.shape import PointUndirectedGraph n_expected_points = 17 validate_input(pcloud, n_expected_points) upper_indices, upper_connectivity = _build_upper_eyelid() middle_indices = np.arange(12, 17) bottom_indices = np.arange(6, 12) lower_indices = np.hstack((bottom_indices, 0, middle_indices)) lower_connectivity = list(zip(bottom_indices, bottom_indices[1:])) lower_connectivity += [(0, 12)] lower_connectivity += list(zip(middle_indices, middle_indices[1:])) lower_connectivity += [(11, 0)] all_connectivity = np.asarray(upper_connectivity + lower_connectivity) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['upper_eyelid'] = upper_indices mapping['lower_eyelid'] = lower_indices return new_pcloud, mapping
def view_appearance_graph_widget(self, scale_index=-1, figure_size=(10, 8)): r""" Visualize the appearance 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. Raises ------ ValueError Scale level {scale_index} uses a PCA appearance model, so there is no graph """ if self.appearance_graph[scale_index] is not None: PointUndirectedGraph( self.shape_models[scale_index].model.mean().points, self.appearance_graph[scale_index].adjacency_matrix).\ view_widget(figure_size=figure_size) else: raise ValueError("Scale level {} uses a PCA appearance model, " "so there is no graph".format(scale_index))
def face_ibug_49_to_face_ibug_49(pcloud): r""" Apply the IBUG 49-point semantic labels. The semantic labels applied are as follows: - left_eyebrow - right_eyebrow - nose - left_eye - right_eye - mouth References ---------- .. [1] http://www.multipie.org/ .. [2] http://ibug.doc.ic.ac.uk/resources/300-W/ """ from menpo.shape import PointUndirectedGraph n_expected_points = 49 validate_input(pcloud, n_expected_points) lbrow_indices = np.arange(0, 5) rbrow_indices = np.arange(5, 10) upper_nose_indices = np.arange(10, 14) lower_nose_indices = np.arange(14, 19) leye_indices = np.arange(19, 25) reye_indices = np.arange(25, 31) outer_mouth_indices = np.arange(31, 43) inner_mouth_indices = np.hstack((31, np.arange(43, 46), 37, np.arange(46, 49))) lbrow_connectivity = connectivity_from_array(lbrow_indices) rbrow_connectivity = connectivity_from_array(rbrow_indices) nose_connectivity = np.vstack([ connectivity_from_array(upper_nose_indices), connectivity_from_array(lower_nose_indices)]) leye_connectivity = connectivity_from_array(leye_indices, close_loop=True) reye_connectivity = connectivity_from_array(reye_indices, close_loop=True) mouth_connectivity = np.vstack([ connectivity_from_array(outer_mouth_indices, close_loop=True), connectivity_from_array(inner_mouth_indices, close_loop=True)]) all_connectivity = np.vstack([ lbrow_connectivity, rbrow_connectivity, nose_connectivity, leye_connectivity, reye_connectivity, mouth_connectivity]) # Ignore the two inner mouth points new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['left_eyebrow'] = lbrow_indices mapping['right_eyebrow'] = rbrow_indices mapping['nose'] = np.hstack([upper_nose_indices, lower_nose_indices]) mapping['left_eye'] = leye_indices mapping['right_eye'] = reye_indices mapping['mouth'] = np.hstack([outer_mouth_indices, inner_mouth_indices]) return new_pcloud, mapping
def eye_ibug_open_38_to_eye_ibug_open_38(pcloud): r""" Apply the IBUG 38-point open eye semantic labels. The semantic labels applied are as follows: - upper_eyelid - lower_eyelid - iris - pupil - sclera """ from menpo.shape import PointUndirectedGraph n_expected_points = 38 validate_input(pcloud, n_expected_points) upper_el_indices, upper_el_connectivity = _build_upper_eyelid() iris_range = (22, 30) pupil_range = (30, 38) sclera_top = np.arange(12, 17) sclera_bottom = np.arange(17, 22) sclera_indices = np.hstack((0, sclera_top, 6, sclera_bottom)) lower_el_top = np.arange(17, 22) lower_el_bottom = np.arange(7, 12) lower_el_indices = np.hstack((6, lower_el_top, 0, lower_el_bottom)) iris_connectivity = connectivity_from_range(iris_range, close_loop=True) pupil_connectivity = connectivity_from_range(pupil_range, close_loop=True) sclera_connectivity = list(zip(sclera_top, sclera_top[1:])) sclera_connectivity += [(0, 21)] sclera_connectivity += list(zip(sclera_bottom, sclera_bottom[1:])) sclera_connectivity += [(6, 17)] lower_el_connectivity = list(zip(lower_el_top, lower_el_top[1:])) lower_el_connectivity += [(6, 7)] lower_el_connectivity += list(zip(lower_el_bottom, lower_el_bottom[1:])) lower_el_connectivity += [(11, 0)] all_connectivity = np.asarray(upper_el_connectivity + lower_el_connectivity + iris_connectivity.tolist() + pupil_connectivity.tolist() + sclera_connectivity) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['upper_eyelid'] = upper_el_indices mapping['lower_eyelid'] = lower_el_indices mapping['pupil'] = np.arange(*pupil_range) mapping['iris'] = np.arange(*iris_range) mapping['sclera'] = sclera_indices return new_pcloud, mapping
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 plot_shape_graph(aps, level): mean_shape = aps.shape_models[level].mean().points # plot mean shape points plt.scatter(aps.shape_models[level].mean().points[:, 0], aps.shape_models[level].mean().points[:, 1]) # create and plot edge connections PointUndirectedGraph(mean_shape, aps.graph_shape.adjacency_array).view_on( plt.gcf().number)
def hand_ibug_39_to_hand_ibug_39(pcloud): r""" Apply the IBUG 39-point semantic labels. The semantic labels applied are as follows: - thumb - index - middle - ring - pinky - palm """ from menpo.shape import PointUndirectedGraph n_expected_points = 39 validate_input(pcloud, n_expected_points) thumb_indices = np.arange(0, 5) index_indices = np.arange(5, 12) middle_indices = np.arange(12, 19) ring_indices = np.arange(19, 26) pinky_indices = np.arange(26, 33) palm_indices = np.hstack((np.array([32, 25, 18, 11, 33, 34, 4]), np.arange(35, 39))) thumb_connectivity = connectivity_from_array(thumb_indices, close_loop=False) index_connectivity = connectivity_from_array(index_indices, close_loop=False) middle_connectivity = connectivity_from_array(middle_indices, close_loop=False) ring_connectivity = connectivity_from_array(ring_indices, close_loop=False) pinky_connectivity = connectivity_from_array(pinky_indices, close_loop=False) palm_connectivity = connectivity_from_array(palm_indices, close_loop=True) all_connectivity = np.vstack([thumb_connectivity, index_connectivity, middle_connectivity, ring_connectivity, pinky_connectivity, palm_connectivity]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['thumb'] = thumb_indices mapping['index'] = index_indices mapping['middle'] = middle_indices mapping['ring'] = ring_indices mapping['pinky'] = pinky_indices mapping['palm'] = palm_indices return new_pcloud, mapping
def hand_ibug_39_to_hand_ibug_39(pcloud): r""" Apply the IBUG 39-point semantic labels. The semantic labels applied are as follows: - thumb - index - middle - ring - pinky - palm """ from menpo.shape import PointUndirectedGraph n_expected_points = 39 validate_input(pcloud, n_expected_points) thumb_indices = np.arange(0, 5) index_indices = np.arange(5, 12) middle_indices = np.arange(12, 19) ring_indices = np.arange(19, 26) pinky_indices = np.arange(26, 33) palm_indices = np.hstack((np.array([32, 25, 18, 11, 33, 34, 4]), np.arange(35, 39))) thumb_connectivity = connectivity_from_array(thumb_indices, close_loop=False) index_connectivity = connectivity_from_array(index_indices, close_loop=False) middle_connectivity = connectivity_from_array(middle_indices, close_loop=False) ring_connectivity = connectivity_from_array(ring_indices, close_loop=False) pinky_connectivity = connectivity_from_array(pinky_indices, close_loop=False) palm_connectivity = connectivity_from_array(palm_indices, close_loop=True) all_connectivity = np.vstack([ thumb_connectivity, index_connectivity, middle_connectivity, ring_connectivity, pinky_connectivity, palm_connectivity ]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['thumb'] = thumb_indices mapping['index'] = index_indices mapping['middle'] = middle_indices mapping['ring'] = ring_indices mapping['pinky'] = pinky_indices mapping['palm'] = palm_indices return new_pcloud, mapping
def __init__(self, points, adjacency_matrix, labels_to_masks, copy=True, skip_checks=False): PointUndirectedGraph.__init__(self, points, adjacency_matrix, copy=copy, skip_checks=skip_checks) if not labels_to_masks: raise ValueError('Labelled point graphs are designed to be ' 'immutable. Empty label sets are not permitted.') if np.vstack(labels_to_masks.values()).shape[1] != points.shape[0]: raise ValueError('Each mask must have the same number of points ' 'as the given points.') if not isinstance(labels_to_masks, OrderedDict): raise ValueError('Must provide an OrderedDict to maintain the ' 'semantic meaning of the labels.') # Another sanity check self._labels_to_masks = labels_to_masks self._verify_all_labels_masked() if copy: self._labels_to_masks = OrderedDict([(l, m.copy()) for l, m in labels_to_masks.items()])
def car_streetscene_20_to_car_streetscene_view_1_14(pcloud): """ Apply the 14-point semantic labels of "view 1" from the MIT Street Scene Car dataset (originally a 20-point markup). The semantic labels applied are as follows: - front - bonnet - windshield - left_side References ---------- .. [1] http://www.cs.cmu.edu/~vboddeti/alignment.html """ from menpo.shape import PointUndirectedGraph n_expected_points = 20 validate_input(pcloud, n_expected_points) front_indices = np.array([0, 1, 3, 2]) bonnet_indices = np.array([2, 3, 5, 4]) windshield_indices = np.array([4, 5, 7, 6]) left_side_indices = np.array([0, 2, 4, 6, 8, 9, 10, 11, 13, 12]) front_connectivity = connectivity_from_array(front_indices, close_loop=True) bonnet_connectivity = connectivity_from_array(bonnet_indices, close_loop=True) windshield_connectivity = connectivity_from_array(windshield_indices, close_loop=True) left_side_connectivity = connectivity_from_array(left_side_indices, close_loop=True) all_connectivity = np.vstack([ front_connectivity, bonnet_connectivity, windshield_connectivity, left_side_connectivity ]) ind = np.hstack((np.arange(9), np.array([10, 12, 14, 16, 18]))) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points[ind], all_connectivity) mapping = OrderedDict() mapping['front'] = front_indices mapping['bonnet'] = bonnet_indices mapping['windshield'] = windshield_indices mapping['left_side'] = left_side_indices return new_pcloud, mapping
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 car_streetscene_20_to_car_streetscene_view_6_14(pcloud): r""" Apply the 14-point semantic labels of "view 6" from the MIT Street Scene Car dataset (originally a 20-point markup). The semantic labels applied are as follows: - right_side - rear_windshield - trunk - rear References ---------- .. [1] http://www.cs.cmu.edu/~vboddeti/alignment.html """ from menpo.shape import PointUndirectedGraph n_expected_points = 20 validate_input(pcloud, n_expected_points) right_side_indices = np.array([0, 1, 2, 3, 5, 7, 9, 11, 13, 12]) rear_windshield_indices = np.array([4, 5, 7, 6]) trunk_indices = np.array([6, 7, 9, 8]) rear_indices = np.array([8, 9, 11, 10]) right_side_connectivity = connectivity_from_array(right_side_indices, close_loop=True) rear_windshield_connectivity = connectivity_from_array( rear_windshield_indices, close_loop=True) trunk_connectivity = connectivity_from_array(trunk_indices, close_loop=True) rear_connectivity = connectivity_from_array(rear_indices, close_loop=True) all_connectivity = np.vstack([ right_side_connectivity, rear_windshield_connectivity, trunk_connectivity, rear_connectivity ]) ind = np.array([1, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points[ind], all_connectivity) mapping = OrderedDict() mapping['right_side'] = right_side_indices mapping['rear_windshield'] = rear_windshield_indices mapping['trunk'] = trunk_indices mapping['rear'] = rear_indices return new_pcloud, mapping
def pose_lsp_14_to_pose_lsp_14(pcloud): r""" Apply the lsp 14-point semantic labels. The semantic labels applied are as follows: - left_leg - right_leg - left_arm - right_arm - head References ---------- .. [1] http://www.comp.leeds.ac.uk/mat4saj/lsp.html """ from menpo.shape import PointUndirectedGraph n_expected_points = 14 validate_input(pcloud, n_expected_points) left_leg_indices = np.arange(0, 3) right_leg_indices = np.arange(3, 6) left_arm_indices = np.arange(6, 9) right_arm_indices = np.arange(9, 12) head_indices = np.arange(12, 14) left_leg_connectivity = connectivity_from_array(left_leg_indices) right_leg_connectivity = connectivity_from_array(right_leg_indices) left_arm_connectivity = connectivity_from_array(left_arm_indices) right_arm_connectivity = connectivity_from_array(right_arm_indices) head_connectivity = connectivity_from_array(head_indices) all_connectivity = np.vstack([ left_leg_connectivity, right_leg_connectivity, left_arm_connectivity, right_arm_connectivity, head_connectivity ]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['left_leg'] = left_leg_indices mapping['right_leg'] = right_leg_indices mapping['left_arm'] = left_arm_indices mapping['right_arm'] = right_arm_indices mapping['head'] = head_indices return new_pcloud, mapping
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 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 tojson(self): r""" Convert this `LabelledPointUndirectedGraph` to a dictionary JSON representation. Returns ------- json : ``dict`` Dictionary conforming to the LJSON v2 specification. """ labels = [{'mask': mask.nonzero()[0].tolist(), 'label': label} for label, mask in self._labels_to_masks.items()] lms_dict = PointUndirectedGraph.tojson(self) lms_dict['labels'] = labels return lms_dict
def pcloud_and_lgroup_from_ranges(pointcloud, labels_to_ranges): """ Label the given pointcloud according to the given ordered dictionary of labels to ranges. This assumes that you can semantically label the group by using ranges in to the existing points e.g :: labels_to_ranges = {'jaw': (0, 17, False)} The third element of the range tuple is whether the range is a closed loop or not. For example, for an eye landmark this would be ``True``, as you do want to create a closed loop for an eye. Parameters ---------- pointcloud : :map:`PointCloud` The pointcloud to apply semantic labels to. labels_to_ranges : `ordereddict` {`str` -> (`int`, `int`, `bool`)} Ordered dictionary of string labels to range tuples. Returns ------- new_pcloud : :map:`PointCloud` New pointcloud with specific connectivity information applied. mapping : `ordereddict` {`str` -> `int ndarray`} For each label, the indices in to the pointcloud that belong to the label. """ from menpo.shape import PointUndirectedGraph mapping = OrderedDict() all_connectivity = [] for label, tup in labels_to_ranges.items(): range_tuple = tup[:-1] close_loop = tup[-1] connectivity = connectivity_from_range(range_tuple, close_loop=close_loop) all_connectivity.append(connectivity) mapping[label] = np.arange(*range_tuple) all_connectivity = np.vstack(all_connectivity) new_pcloud = PointUndirectedGraph.init_from_edges(pointcloud.points, all_connectivity) return new_pcloud, mapping
def _parse_ljson_v2(lms_dict): labels_to_mask = OrderedDict() # masks into the full pointcloud per label points = _ljson_parse_null_values(lms_dict['landmarks']['points']) connectivity = lms_dict['landmarks'].get('connectivity') # Don't create a PointUndirectedGraph with no connectivity if connectivity is None or len(connectivity) == 0: pcloud = PointCloud(points) else: pcloud = PointUndirectedGraph.init_from_edges(points, connectivity) for label in lms_dict['labels']: mask = np.zeros(pcloud.n_points, dtype=np.bool) mask[label['mask']] = True labels_to_mask[label['label']] = mask return pcloud, labels_to_mask
def get_label(self, label): """ Returns a new :map:`PointUndirectedGraph` that contains the subset of points that this label represents. Parameters ---------- label : `string` Label to filter on. Returns ------- graph : :map:`PointUndirectedGraph` The PointUndirectedGraph containing the subset of points that this label masks. Will be a subset of the entire group's points. """ mask = self._labels_to_masks[label] return PointUndirectedGraph.from_mask(self, mask)
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 face_ibug_68_to_face_ibug_65(pcloud): r""" Apply the IBUG 68 point semantic labels, but ignore the 3 points that are coincident for a closed mouth (bottom of the inner mouth). The semantic labels applied are as follows: - jaw - left_eyebrow - right_eyebrow - nose - left_eye - right_eye - mouth References ---------- .. [1] http://www.multipie.org/ .. [2] http://ibug.doc.ic.ac.uk/resources/300-W/ """ from menpo.shape import PointUndirectedGraph # Apply face_ibug_68_to_face_ibug_68 new_pcloud, mapping = face_ibug_68_to_face_ibug_68(pcloud, return_mapping=True) # The coincident points are considered the final 3 landmarks (bottom of # the inner mouth points). We remove all the edges for the inner mouth # which are the last 8. edges = new_pcloud.edges[:-8] # Re-add the inner mouth without the bottom 3 points edges = np.vstack([edges, connectivity_from_range((60, 65), close_loop=True)]) new_pcloud = PointUndirectedGraph.init_from_edges( new_pcloud.points[:-3], edges) # Luckily, OrderedDict maintains the original ordering despite updates outer_mouth_indices = np.arange(48, 60) inner_mouth_indices = np.arange(60, 65) mapping['mouth'] = np.hstack([outer_mouth_indices, inner_mouth_indices]) return new_pcloud, mapping
def _parse_ljson_v1(lms_dict): from menpo.base import MenpoDeprecationWarning warnings.warn( "LJSON v1 is deprecated. export_landmark_file{s}() will " "only save out LJSON v2 files. Please convert all LJSON " "files to v2 by importing into Menpo and re-exporting to " "overwrite the files.", MenpoDeprecationWarning, ) all_points = [] labels = [] # label per group labels_slices = [] # slices into the full pointcloud per label offset = 0 connectivity = [] for group in lms_dict["groups"]: lms = group["landmarks"] labels.append(group["label"]) labels_slices.append(slice(offset, len(lms) + offset)) # Create the connectivity if it exists conn = group.get("connectivity", []) if conn: # Offset relative connectivity according to the current index conn = offset + np.asarray(conn) connectivity += conn.tolist() for p in lms: all_points.append(p["point"]) offset += len(lms) # Don't create a PointUndirectedGraph with no connectivity points = _ljson_parse_null_values(all_points) if len(connectivity) == 0: pcloud = PointCloud(points) else: pcloud = PointUndirectedGraph.init_from_edges(points, connectivity) labels_to_masks = OrderedDict() # go through each label and build the appropriate boolean array for label, l_slice in zip(labels, labels_slices): mask = np.zeros(pcloud.n_points, dtype=np.bool) mask[l_slice] = True labels_to_masks[label] = mask return pcloud, labels_to_masks
def _parse_ljson_v1(lms_dict): from menpo.base import MenpoDeprecationWarning warnings.warn( 'LJSON v1 is deprecated. export_landmark_file{s}() will ' 'only save out LJSON v2 files. Please convert all LJSON ' 'files to v2 by importing into Menpo and re-exporting to ' 'overwrite the files.', MenpoDeprecationWarning) all_points = [] labels = [] # label per group labels_slices = [] # slices into the full pointcloud per label offset = 0 connectivity = [] for group in lms_dict['groups']: lms = group['landmarks'] labels.append(group['label']) labels_slices.append(slice(offset, len(lms) + offset)) # Create the connectivity if it exists conn = group.get('connectivity', []) if conn: # Offset relative connectivity according to the current index conn = offset + np.asarray(conn) connectivity += conn.tolist() for p in lms: all_points.append(p['point']) offset += len(lms) # Don't create a PointUndirectedGraph with no connectivity points = _ljson_parse_null_values(all_points) if len(connectivity) == 0: pcloud = PointCloud(points) else: pcloud = PointUndirectedGraph.init_from_edges(points, connectivity) labels_to_masks = OrderedDict() # go through each label and build the appropriate boolean array for label, l_slice in zip(labels, labels_slices): mask = np.zeros(pcloud.n_points, dtype=np.bool) mask[l_slice] = True labels_to_masks[label] = mask return pcloud, labels_to_masks
def _parse_format(self, asset=None): with open(self.filepath, 'rb') as f: # lms_dict is now a dict rep of the JSON lms_dict = json.load(f, object_pairs_hook=OrderedDict) all_points = [] labels = [] # label per group labels_slices = [] # slices into the full pointcloud per label offset = 0 connectivity = [] for group in lms_dict['groups']: lms = group['landmarks'] labels.append(group['label']) labels_slices.append(slice(offset, len(lms) + offset)) # Create the connectivity if it exists conn = group.get('connectivity', []) if conn: # Offset relative connectivity according to the current index conn = offset + np.asarray(conn) connectivity.append(conn) for p in lms: all_points.append(p['point']) offset += len(lms) # Don't create a PointUndirectedGraph with no connectivity points = np.array(all_points) if len(connectivity) == 0: self.pointcloud = PointCloud(points) else: self.pointcloud = PointUndirectedGraph(points, np.vstack(connectivity)) self.labels_to_masks = OrderedDict() # go through each label and build the appropriate boolean array for label, l_slice in zip(labels, labels_slices): mask = np.zeros(self.pointcloud.n_points, dtype=np.bool) mask[l_slice] = True self.labels_to_masks[label] = mask
def pose_human36M_32_to_pose_human36M_32(pcloud): r""" Apply the human3.6M 32-point semantic labels. The semantic labels applied are as follows: - pelvis - right_leg - left_leg - spine - head - left_arm - left_hand - right_arm - right_hand - torso References ---------- .. [1] http://vision.imar.ro/human3.6m/ """ from menpo.shape import PointUndirectedGraph n_expected_points = 32 validate_input(pcloud, n_expected_points) pelvis_indices = np.array([1, 0, 6]) right_leg_indices = np.array(range(1, 6)) left_leg_indices = np.array(range(6, 11)) spine_indices = np.array([11, 12, 13]) head_indices = np.array([13, 14, 15]) left_arm_indices = np.array([16, 17, 18, 19, 23]) left_hand_indices = np.array([20, 21, 22]) right_arm_indices = np.array([24, 25, 26, 27, 29, 31]) right_hand_indices = np.array([28, 29, 30]) torso_indices = np.array([0, 1, 25, 13, 17, 6]) pelvis_connectivity = connectivity_from_array(pelvis_indices) right_leg_connectivity = connectivity_from_array(right_leg_indices) left_leg_connectivity = connectivity_from_array(left_leg_indices) spine_connectivity = connectivity_from_array(spine_indices) head_connectivity = connectivity_from_array(head_indices) left_arm_connectivity = connectivity_from_array(left_arm_indices) left_hand_connectivity = connectivity_from_array(left_hand_indices) right_arm_connectivity = connectivity_from_array(right_arm_indices) right_hand_connectivity = connectivity_from_array(right_hand_indices) torso_connectivity = connectivity_from_array(torso_indices, close_loop=True) all_connectivity = np.vstack([ pelvis_connectivity, right_leg_connectivity, left_leg_connectivity, spine_connectivity, head_connectivity, left_arm_connectivity, left_hand_connectivity, right_arm_connectivity, right_hand_connectivity, torso_connectivity ]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['pelvis'] = pelvis_indices mapping['right_leg'] = right_leg_indices mapping['left_leg'] = left_leg_indices mapping['spine'] = spine_indices mapping['head'] = head_indices mapping['left_arm'] = left_arm_indices mapping['left_hand'] = left_hand_indices mapping['right_arm'] = right_arm_indices mapping['right_hand'] = right_hand_indices mapping['torso'] = torso_indices return new_pcloud, mapping
def pose_human36M_32_to_pose_human36M_17(pcloud): r""" Apply the human3.6M 17-point semantic labels (based on the original semantic labels of Human3.6 but removing the annotations corresponding to duplicate points, soles and palms), originally 32-points. The semantic labels applied are as follows: - pelvis - right_leg - left_leg - spine - head - left_arm - right_arm - torso References ---------- .. [1] http://vision.imar.ro/human3.6m/ """ from menpo.shape import PointUndirectedGraph n_expected_points = 32 validate_input(pcloud, n_expected_points) pelvis_indices = np.array([1, 0, 4]) right_leg_indices = np.arange(1, 4) left_leg_indices = np.arange(4, 7) spine_indices = np.array([0, 7, 8]) head_indices = np.array([8, 9, 10]) left_arm_indices = np.array([8, 11, 12, 13]) right_arm_indices = np.array([8, 14, 15, 16]) torso_indices = np.array([0, 1, 14, 8, 11, 4]) pelvis_connectivity = connectivity_from_array(pelvis_indices) right_leg_connectivity = connectivity_from_array(right_leg_indices) left_leg_connectivity = connectivity_from_array(left_leg_indices) spine_connectivity = connectivity_from_array(spine_indices) head_connectivity = connectivity_from_array(head_indices) left_arm_connectivity = connectivity_from_array(left_arm_indices) right_arm_connectivity = connectivity_from_array(right_arm_indices) torso_connectivity = connectivity_from_array(torso_indices, close_loop=True) all_connectivity = np.vstack([ pelvis_connectivity, right_leg_connectivity, left_leg_connectivity, spine_connectivity, head_connectivity, left_arm_connectivity, right_arm_connectivity, torso_connectivity ]) # Ignore duplicate points, sole and palms ind = np.hstack([ np.arange(0, 4), np.arange(6, 9), np.arange(12, 16), np.arange(17, 20), np.arange(25, 28) ]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points[ind], all_connectivity) mapping = OrderedDict() mapping['pelvis'] = pelvis_indices mapping['right_leg'] = right_leg_indices mapping['left_leg'] = left_leg_indices mapping['spine'] = spine_indices mapping['head'] = head_indices mapping['left_arm'] = left_arm_indices mapping['right_arm'] = right_arm_indices mapping['torso'] = torso_indices return new_pcloud, mapping
def pose_human36M_32_to_pose_human36M_17(pcloud): r""" Apply the human3.6M 17-point semantic labels (based on the original semantic labels of Human3.6 but removing the annotations corresponding to duplicate points, soles and palms), originally 32-points. The semantic labels applied are as follows: - pelvis - right_leg - left_leg - spine - head - left_arm - right_arm - torso References ---------- .. [1] http://vision.imar.ro/human3.6m/ """ from menpo.shape import PointUndirectedGraph n_expected_points = 32 validate_input(pcloud, n_expected_points) pelvis_indices = np.array([1, 0, 4]) right_leg_indices = np.arange(1, 4) left_leg_indices = np.arange(4, 7) spine_indices = np.array([0, 7, 8]) head_indices = np.array([8, 9, 10]) left_arm_indices = np.array([8, 11, 12, 13]) right_arm_indices = np.array([8, 14, 15, 16]) torso_indices = np.array([0, 1, 14, 8, 11, 4]) pelvis_connectivity = connectivity_from_array(pelvis_indices) right_leg_connectivity = connectivity_from_array(right_leg_indices) left_leg_connectivity = connectivity_from_array(left_leg_indices) spine_connectivity = connectivity_from_array(spine_indices) head_connectivity = connectivity_from_array(head_indices) left_arm_connectivity = connectivity_from_array(left_arm_indices) right_arm_connectivity = connectivity_from_array(right_arm_indices) torso_connectivity = connectivity_from_array(torso_indices, close_loop=True) all_connectivity = np.vstack([ pelvis_connectivity, right_leg_connectivity, left_leg_connectivity, spine_connectivity, head_connectivity, left_arm_connectivity, right_arm_connectivity, torso_connectivity ]) # Ignore duplicate points, sole and palms ind = np.hstack([np.arange(0, 4), np.arange(6, 9), np.arange(12, 16), np.arange(17, 20), np.arange(25, 28)]) new_pcloud = PointUndirectedGraph.init_from_edges( pcloud.points[ind], all_connectivity) mapping = OrderedDict() mapping['pelvis'] = pelvis_indices mapping['right_leg'] = right_leg_indices mapping['left_leg'] = left_leg_indices mapping['spine'] = spine_indices mapping['head'] = head_indices mapping['left_arm'] = left_arm_indices mapping['right_arm'] = right_arm_indices mapping['torso'] = torso_indices return new_pcloud, mapping
) point = np.array([[10, 10]]) # Define undirected graph and pointgraph adj_undirected = np.array( [ [0, 1, 1, 0, 0, 0], [1, 0, 1, 1, 0, 0], [1, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 1], [0, 0, 1, 1, 0, 0], [0, 0, 0, 1, 0, 0], ] ) g_undirected = UndirectedGraph(adj_undirected) pg_undirected = PointUndirectedGraph(points, adj_undirected) # Define directed graph and pointgraph adj_directed = csr_matrix( ([1] * 8, ([1, 2, 1, 2, 1, 2, 3, 3], [0, 0, 2, 1, 3, 4, 4, 5])), shape=(6, 6) ) g_directed = DirectedGraph(adj_directed) pg_directed = PointDirectedGraph(points, adj_directed) # 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],
def face_ibug_68_to_face_ibug_68(pcloud): r""" Apply the IBUG 68-point semantic labels. The semantic labels are as follows: - jaw - left_eyebrow - right_eyebrow - nose - left_eye - right_eye - mouth References ---------- .. [1] http://www.multipie.org/ .. [2] http://ibug.doc.ic.ac.uk/resources/300-W/ """ from menpo.shape import PointUndirectedGraph n_expected_points = 68 validate_input(pcloud, n_expected_points) jaw_indices = np.arange(0, 17) lbrow_indices = np.arange(17, 22) rbrow_indices = np.arange(22, 27) upper_nose_indices = np.arange(27, 31) lower_nose_indices = np.arange(31, 36) leye_indices = np.arange(36, 42) reye_indices = np.arange(42, 48) outer_mouth_indices = np.arange(48, 60) inner_mouth_indices = np.arange(60, 68) jaw_connectivity = connectivity_from_array(jaw_indices) lbrow_connectivity = connectivity_from_array(lbrow_indices) rbrow_connectivity = connectivity_from_array(rbrow_indices) nose_connectivity = np.vstack([ connectivity_from_array(upper_nose_indices), connectivity_from_array(lower_nose_indices)]) leye_connectivity = connectivity_from_array(leye_indices, close_loop=True) reye_connectivity = connectivity_from_array(reye_indices, close_loop=True) mouth_connectivity = np.vstack([ connectivity_from_array(outer_mouth_indices, close_loop=True), connectivity_from_array(inner_mouth_indices, close_loop=True)]) all_connectivity = np.vstack([ jaw_connectivity, lbrow_connectivity, rbrow_connectivity, nose_connectivity, leye_connectivity, reye_connectivity, mouth_connectivity ]) new_pcloud = PointUndirectedGraph.init_from_edges( pcloud.points, all_connectivity) mapping = OrderedDict() mapping['jaw'] = jaw_indices mapping['left_eyebrow'] = lbrow_indices mapping['right_eyebrow'] = rbrow_indices mapping['nose'] = np.hstack((upper_nose_indices, lower_nose_indices)) mapping['left_eye'] = leye_indices mapping['right_eye'] = reye_indices mapping['mouth'] = np.hstack((outer_mouth_indices, inner_mouth_indices)) return new_pcloud, mapping
def face_bu3dfe_83_to_face_bu3dfe_83(pcloud): r""" Apply the BU-3DFE (Binghamton University 3D Facial Expression) Database 83-point facial semantic labels. The semantic labels applied are as follows: - right_eye - left_eye - right_eyebrow - left_eyebrow - right_nose - left_nose - nostrils - outer_mouth - inner_mouth - jaw References ---------- .. [1] http://www.cs.binghamton.edu/~lijun/Research/3DFE/3DFE_Analysis.html """ from menpo.shape import PointUndirectedGraph n_expected_points = 83 validate_input(pcloud, n_expected_points) reye_indices = np.arange(0, 8) leye_indices = np.arange(8, 16) rbrow_indices = np.arange(16, 26) lbrow_indices = np.arange(26, 36) rnose_indices = np.arange(36, 39) lnose_indices = np.arange(39, 42) nostril_indices = np.arange(42, 48) outermouth_indices = np.arange(48, 60) innermouth_indices = np.arange(60, 68) jaw_indices = np.arange(68, 83) reye_connectivity = connectivity_from_array(reye_indices, close_loop=True) leye_connectivity = connectivity_from_array(leye_indices, close_loop=True) rbrow_connectivity = connectivity_from_array(rbrow_indices, close_loop=True) lbrow_connectivity = connectivity_from_array(lbrow_indices, close_loop=True) rnose_connectivity = connectivity_from_array(rnose_indices) nostril_connectivity = connectivity_from_array(nostril_indices) lnose_connectivity = connectivity_from_array(lnose_indices) outermouth_connectivity = connectivity_from_array(outermouth_indices, close_loop=True) innermouth_connectivity = connectivity_from_array(innermouth_indices, close_loop=True) jaw_connectivity = connectivity_from_array(jaw_indices) all_connectivity = np.vstack([ reye_connectivity, leye_connectivity, rbrow_connectivity, lbrow_connectivity, rnose_connectivity, nostril_connectivity, lnose_connectivity, outermouth_connectivity, innermouth_connectivity, jaw_connectivity ]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['right_eye'] = reye_indices mapping['left_eye'] = leye_indices mapping['right_eyebrow'] = rbrow_indices mapping['left_eyebrow'] = lbrow_indices mapping['right_nose'] = rnose_indices mapping['left_nose'] = lnose_indices mapping['nostrils'] = nostril_indices mapping['outer_mouth'] = outermouth_indices mapping['inner_mouth'] = innermouth_indices mapping['jaw'] = jaw_indices return new_pcloud, mapping
def face_lfpw_29_to_face_lfpw_29(pcloud): r""" Apply the 29-point semantic labels from the original LFPW dataset. The semantic labels applied are as follows: - chin - left_eye - right_eye - left_eyebrow - right_eyebrow - mouth - nose References ---------- .. [1] http://homes.cs.washington.edu/~neeraj/databases/lfpw/ """ from menpo.shape import PointUndirectedGraph n_expected_points = 29 validate_input(pcloud, n_expected_points) chin_indices = np.array([28]) outer_leye_indices = np.array([8, 12, 10, 13]) pupil_leye_indices = np.array([16]) outer_reye_indices = np.array([11, 14, 9, 15]) pupil_reye_indices = np.array([17]) lbrow_indices = np.array([0, 4, 2, 5]) rbrow_indices = np.array([3, 6, 1, 7]) outer_mouth_indices = np.array([22, 24, 23, 27]) inner_mouth_indices = np.array([22, 25, 23, 26]) nose_indices = np.array([18, 20, 19, 21]) chin_connectivity = connectivity_from_array(chin_indices, close_loop=True) leye_connectivity = connectivity_from_array(outer_leye_indices, close_loop=True) reye_connectivity = connectivity_from_array(outer_reye_indices, close_loop=True) lbrow_connectivity = connectivity_from_array(lbrow_indices, close_loop=True) rbrow_connectivity = connectivity_from_array(rbrow_indices, close_loop=True) mouth_connectivity = np.vstack([ connectivity_from_array(outer_mouth_indices, close_loop=True), connectivity_from_array(inner_mouth_indices, close_loop=True)]) nose_connectivity = connectivity_from_array(nose_indices, close_loop=True) all_connectivity = np.vstack([ chin_connectivity, leye_connectivity, reye_connectivity, lbrow_connectivity, rbrow_connectivity, mouth_connectivity, nose_connectivity]) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points, all_connectivity) mapping = OrderedDict() mapping['chin'] = chin_indices mapping['left_eye'] = np.hstack((outer_leye_indices, pupil_leye_indices)) mapping['right_eye'] = np.hstack((outer_reye_indices, pupil_reye_indices)) mapping['left_eyebrow'] = lbrow_indices mapping['right_eyebrow'] = rbrow_indices mapping['mouth'] = np.hstack((outer_mouth_indices, inner_mouth_indices)) mapping['nose'] = nose_indices return new_pcloud, mapping
def face_ibug_68_to_face_ibug_49(pcloud): r""" Apply the IBUG 49-point semantic labels, but removing the annotations corresponding to the jaw region and the 2 describing the inner mouth corners. The semantic labels applied are as follows: - left_eyebrow - right_eyebrow - nose - left_eye - right_eye - mouth References ---------- .. [1] http://www.multipie.org/ .. [2] http://ibug.doc.ic.ac.uk/resources/300-W/ """ from menpo.shape import PointUndirectedGraph n_expected_points = 68 validate_input(pcloud, n_expected_points) lbrow_indices = np.arange(0, 5) rbrow_indices = np.arange(5, 10) upper_nose_indices = np.arange(10, 14) lower_nose_indices = np.arange(14, 19) leye_indices = np.arange(19, 25) reye_indices = np.arange(25, 31) outer_mouth_indices = np.arange(31, 43) inner_mouth_indices = np.hstack((31, np.arange(43, 46), 37, np.arange(46, 49))) lbrow_connectivity = connectivity_from_array(lbrow_indices) rbrow_connectivity = connectivity_from_array(rbrow_indices) nose_connectivity = np.vstack([ connectivity_from_array(upper_nose_indices), connectivity_from_array(lower_nose_indices)]) leye_connectivity = connectivity_from_array(leye_indices, close_loop=True) reye_connectivity = connectivity_from_array(reye_indices, close_loop=True) mouth_connectivity = np.vstack([ connectivity_from_array(outer_mouth_indices, close_loop=True), connectivity_from_array(inner_mouth_indices, close_loop=True)]) all_connectivity = np.vstack([ lbrow_connectivity, rbrow_connectivity, nose_connectivity, leye_connectivity, reye_connectivity, mouth_connectivity]) # Ignore the two inner mouth points ind = np.hstack((np.arange(17, 60), np.arange(61, 64), np.arange(65, 68))) new_pcloud = PointUndirectedGraph.init_from_edges(pcloud.points[ind], all_connectivity) mapping = OrderedDict() mapping['left_eyebrow'] = lbrow_indices mapping['right_eyebrow'] = rbrow_indices mapping['nose'] = np.hstack([upper_nose_indices, lower_nose_indices]) mapping['left_eye'] = leye_indices mapping['right_eye'] = reye_indices mapping['mouth'] = np.hstack([outer_mouth_indices, inner_mouth_indices]) return new_pcloud, mapping
import numpy as np from numpy.testing import assert_allclose from menpo.image import Image from menpo.image.rasterize import rasterize_landmarks_2d from menpo.shape import PointCloud, PointUndirectedGraph centre = PointCloud([[4.5, 4.5]]) line = PointUndirectedGraph(np.array([[2, 4.5], [8, 4.5]]), adjacency_matrix=np.array([[0, 1], [1, 0]])) def test_rasterize_matplotlib_basic(): im = Image.init_blank([11, 11], fill=0, n_channels=1) im.landmarks["test"] = centre new_im = rasterize_landmarks_2d( im, group="test", render_lines=False, marker_style=".", marker_face_colour="r", marker_size=2, marker_edge_width=0, backend="matplotlib", ) assert new_im.n_channels == 3 assert new_im.shape == (11, 11) assert_allclose(new_im.pixels[:, 5, 5], [255, 0, 0]) def test_rasterize_pillow_basic():