def test_basic_3d_affine(): linear_component = np.array([[1, 6, -4], [-3, -2, 5], [5, -1, 3]]) translation_component = np.array([7, -8, 9]) h_matrix = np.eye(4, 4) h_matrix[:-1, :-1] = linear_component h_matrix[:-1, -1] = translation_component affine = AffineTransform(h_matrix) x = np.array([[0, 1, 2], [1, 1, 1], [-1, 2, -5], [1, -5, -1]]) # transform x explicitly solution = np.dot(x, linear_component.T) + translation_component # transform x using the affine transform result = affine.apply(x) # check that both answers are equivalent assert_allclose(solution, result) # create several copies of x x_copies = np.array([x, x, x, x, x, x, x, x]) # transform all of copies at once using the affine transform results = affine.apply(x_copies) # check that all copies have been transformed correctly for r in results: assert_allclose(solution, r)
def test_align_2d_affine(): linear_component = np.array([[1, -6], [-3, 2]]) translation_component = np.array([7, -8]) h_matrix = np.eye(3, 3) h_matrix[:-1, :-1] = linear_component h_matrix[:-1, -1] = translation_component affine = AffineTransform(h_matrix) source = PointCloud(np.array([[0, 1], [1, 1], [-1, -5], [3, -5]])) target = affine.apply(source) # estimate the transform from source and target estimate = AffineTransform.align(source, target) # check the estimates is correct assert_allclose(affine.h_matrix, estimate.h_matrix)
def test_affine_jacobian_2d_with_positions(): params = np.array([0, 0.1, 0.2, 0, 30, 70]) t = AffineTransform.identity(2).from_vector(params) explicit_pixel_locations = np.array( [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2]]) dW_dp = t.jacobian(explicit_pixel_locations) assert_equal(dW_dp, jac_solution2d)
def test_affine_jacobian_3d_with_positions(): params = np.ones(12) t = AffineTransform.identity(3).from_vector(params) explicit_pixel_locations = np.array( [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [0, 2, 0], [0, 2, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1], [1, 2, 0], [1, 2, 1]]) dW_dp = t.jacobian(explicit_pixel_locations) assert_equal(dW_dp, jac_solution3d)
def fit_image(self, image, group=None, label='all', initialization='from_gt_shape', noise_std=0.0, rotation=False, max_iters=50, verbose=True, view=False, error_type='me_norm', **kwargs): r""" Fits a single image. Parameters ----------- image: :class:`menpo.image.masked.MaskedImage` The image to be fitted. group: string, Optional The key of the landmark set that should be used. If None, and if there is only one set of landmarks, this set will be used. Default: None label: string, Optional The label of of the landmark manager that you wish to use. If no label is passed, the convex hull of all landmarks is used. Default: 'all' initialization: 'from_gt_shape' or 'detection', optional The type of initialization to be used for fitting the image. Default: 'from_gt_shape' noise_std: float The std of the gaussian noise used to produce the initial shape. Default: 0.0 rotation: boolean Specifies whether in-plane rotation is to be used to produce the initial shape. Default: False max_iters: int or list, optional The maximum number of iterations. If int, then this will be the overall maximum number of iterations for all the pyramidal levels. If list, then a maximum number of iterations is specified for each pyramidal level. Default: 50 verbose: boolean Whether or not to print information related to the fitting results (such as: final error, convergence, ...). Default: True view: boolean Whether or not the fitting results are to be displayed. Default: False error_type: 'me_norm', 'me' or 'rmse', optional. Specifies the way in which the error between the fitted and ground truth shapes is to be computed. Default: 'me_norm' Returns ------- FittingList: :class:`menpo.aam.fitting.FittingList` A fitting list object containing the fitting objects associated to each run. """ image = deepcopy(image) if isinstance(image.landmarks[group][label], LandmarkGroup): gt_shape = image.landmarks[group][label].lms else: if group or label is not 'all': raise ValueError('The specified group {} and/or ' 'label {} do not exist'.format(group, label)) elif initialization is not 'detection': raise ValueError('Initialization method {} cannot ' 'be used because the image is not ' 'landmarked'.format(initialization)) gt_shape = None if initialization is 'from_gt_shape': initial_shape = self._noisy_align_from_gt_shape( gt_shape, noise_std=noise_std, rotation=rotation) elif type is 'detection': initial_shape = self._detect_shape( noise_std=noise_std, rotation=rotation) else: raise ValueError('Unknown initialization string selected. ' 'Valid options are: "from_gt_shape", ' '"detection"') images = self._prepare_image(image, initial_shape, gt_shape=gt_shape) if gt_shape: gt_shapes = [i.landmarks['gt_shape'].lms for i in images] else: gt_shapes = None initial_shapes = [i.landmarks['initial_shape'].lms for i in images] affine_correction = AffineTransform.align(initial_shapes[-1], initial_shape) basic_fittings = self._fit(images, initial_shapes[0], max_iters=max_iters, gt_shapes=gt_shapes, **kwargs) fitting = self._fitting(image, basic_fittings, affine_correction, gt_shape=gt_shape, error_type=error_type) if verbose: fitting.print_fitting_info() if view: fitting.view_final_fitting(new_figure=True) return fitting
def test_affine_identity_3d(): assert_allclose(AffineTransform.identity(3).h_matrix, np.eye(4))