def noisy_alignment_similarity_transform(source, target, noise_type='uniform', noise_percentage=0.1, allow_alignment_rotation=False): r""" Constructs and perturbs the optimal similarity transform between the source and target shapes by adding noise to its parameters. Parameters ---------- source : `menpo.shape.PointCloud` The source pointcloud instance used in the alignment target : `menpo.shape.PointCloud` The target pointcloud instance used in the alignment noise_type : ``{'uniform', 'gaussian'}``, optional The type of noise to be added. noise_percentage : `float` in ``(0, 1)`` or `list` of `len` `3`, optional The standard percentage of noise to be added. If `float`, then the same amount of noise is applied to the scale, rotation and translation parameters of the optimal similarity transform. If `list` of `float` it must have length 3, where the first, second and third elements denote the amount of noise to be applied to the scale, rotation and translation parameters, respectively. allow_alignment_rotation : `bool`, optional If ``False``, then the rotation is not considered when computing the optimal similarity transform between source and target. Returns ------- noisy_alignment_similarity_transform : `menpo.transform.Similarity` The noisy Similarity Transform between source and target. """ if isinstance(noise_percentage, float): noise_percentage = [noise_percentage] * 3 elif len(noise_percentage) == 1: noise_percentage *= 3 similarity = AlignmentSimilarity(source, target, rotation=allow_alignment_rotation) if noise_type is 'gaussian': s = noise_percentage[0] * (0.5 / 3) * np.asscalar(np.random.randn(1)) r = noise_percentage[1] * (180 / 3) * np.asscalar(np.random.randn(1)) t = noise_percentage[2] * (target.range() / 3) * np.random.randn(2) s = scale_about_centre(target, 1 + s) r = rotate_ccw_about_centre(target, r) t = Translation(t, source.n_dims) elif noise_type is 'uniform': s = noise_percentage[0] * 0.5 * (2 * np.asscalar(np.random.randn(1)) - 1) r = noise_percentage[1] * 180 * (2 * np.asscalar(np.random.rand(1)) - 1) t = noise_percentage[2] * target.range() * (2 * np.random.rand(2) - 1) s = scale_about_centre(target, 1. + s) r = rotate_ccw_about_centre(target, r) t = Translation(t, source.n_dims) else: raise ValueError('Unexpected noise type. ' 'Supported values are {gaussian, uniform}') return similarity.compose_after(t.compose_after(s.compose_after(r)))
def pointgraph_from_circle(fitting, axis_aligned_bb=True): r""" Convert a Pico detection to a menpo.shape.PointDirectedGraph. This enforces a particular point ordering. The Pico detections are circles with a given diameter. Here we convert them to the tightest possible bounding box around the circle. No orientation is currently provided. Parameters ---------- fitting : `cypico.PicoDetection` The Pico detection to convert. Result of calling a pico detection. A namedtuple with a diameter and a centre. Returns ------- bounding_box : `menpo.shape.PointDirectedGraph` A menpo PointDirectedGraph giving the bounding box. """ diameter = fitting.diameter radius = diameter / 2.0 y, x = fitting.center y -= radius x -= radius bb = bounding_box((y, x), (y + diameter, x + diameter)) if not axis_aligned_bb: t = rotate_ccw_about_centre(bb, fitting.orientation, degrees=False) bb = t.apply(bb) return bb