Example #1
0
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)
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
    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
Example #6
0
def test_affine_identity_3d():
    assert_allclose(AffineTransform.identity(3).h_matrix, np.eye(4))