def main():
    path_to_neutral = Path(
        '/Users/lls/Documents/face/data/headpose/Angle/neutral0/')
    path_to_smile = Path(
        '/Users/lls/Documents/face/data/headpose/Angle/down30')
    path_to_source = Path('/Users/lls/Documents/face/data/trump/trump')

    # PDM shape
    neutral = PDMModel(path_to_neutral, 20)[0].model.mean()
    smile = PDMModel(path_to_smile, 20)[0].model.mean()
    source_shape, source_img = PDMModel(path_to_source, 20)
    p_smile = project(smile, source_shape)
    p_neutral = project(neutral, source_shape)
    delta = (p_smile - p_neutral) * 1.5
    ptsPath = '/Users/lls/Documents/face/data/trump/trump/trump_13.pts'
    trumpShape = mio.import_landmark_file(ptsPath).lms
    p_i = project(trumpShape, source_shape)
    new_p_i = p_i + delta
    reconstructed_img_i = source_shape.model.instance(new_p_i)
    trans_reconstructed_img_i = AlignmentAffine(reconstructed_img_i,
                                                trumpShape)
    reconstructed_img_i_pc = trans_reconstructed_img_i.apply(
        reconstructed_img_i)
    plt.subplot(241)
    reconstructed_img_i_pc.view()
    plt.gca().set_title('reconstructed_img_i_pc')
    plt.subplot(242)
    trumpShape.view()
    plt.gca().set_title('trumpShape')
    plt.show()
    '''
Esempio n. 2
0
def Projection(trumpShapeModel, headMeanShape):
    '''ALIGN HEADSHAPE TO TRUMP'''
    transform = AlignmentAffine(headMeanShape, trumpShapeModel.model.mean())
    normalized_shape = transform.apply(headMeanShape)
    '''HEAD P'''
    headWeights = trumpShapeModel.model.project(normalized_shape)
    return headWeights
Esempio n. 3
0
def reconstructByPca(path_to_images):
    shape_model = pca(path_to_images)

    # Import shape
    shape = mio.import_builtin_asset.einstein_pts().lms

    # Find the affine transform that normalizes the shape
    # with respect to the mean shape
    transform = AlignmentAffine(shape, shape_model.model.mean())

    # Normalize shape and project it
    normalized_shape = transform.apply(shape)
    weights = shape_model.model.project(normalized_shape)
    print("Weights: {}".format(weights))

    # Reconstruct the normalized shape
    reconstructed_normalized_shape = shape_model.model.instance(weights)

    # Apply the pseudoinverse of the affine tansform
    reconstructed_shape = transform.pseudoinverse().apply(
        reconstructed_normalized_shape)

    # Visualize
    plt.subplot(121)
    shape.view(render_axes=False, axes_x_limits=0.05, axes_y_limits=0.05)
    plt.gca().set_title('Original shape')
    plt.subplot(122)
    reconstructed_shape.view(render_axes=False,
                             axes_x_limits=0.05,
                             axes_y_limits=0.05)
    plt.gca().set_title('Reconstructed shape')
Esempio n. 4
0
def Reconstruction(trumpShapeModel, deltaWeights, trumpShape):
    transform = AlignmentAffine(trumpShape, trumpShapeModel.model.mean())
    trumpWeights = trumpShapeModel.model.project(trumpShape)
    trumpWeights = trumpWeights + deltaWeights
    reconstructed_normalized_shape = trumpShapeModel.model.instance(
        trumpWeights)
    reconstructed_shape = transform.pseudoinverse().apply(
        reconstructed_normalized_shape)
    return reconstructed_shape
Esempio n. 5
0
def ProjectionAndReconstruction(trumpShapeModel, headMeanShape):
    '''ALIGN HEADSHAPE TO TRUMP'''
    transform = AlignmentAffine(headMeanShape, trumpShapeModel.model.mean())
    normalized_shape = transform.apply(headMeanShape)
    '''HEAD P'''
    headWeights = trumpShapeModel.model.project(normalized_shape)
    '''RECONSTRUCTION'''
    reconstructed_normalized_shape = trumpShapeModel.model.instance(
        headWeights)
    reconstructed_shape = transform.pseudoinverse().apply(
        reconstructed_normalized_shape)
    return reconstructed_shape, headWeights
Esempio n. 6
0
def Reconstruction(trumpShapeModel, deltaWeights, trumpShape):
    trumpWeights, transform = Projection(trumpShapeModel, trumpShape)
    trumpWeights = trumpWeights + deltaWeights
    # print trumpWeights
    reconstructed_normalized_shape = trumpShapeModel.model.instance(
        trumpWeights)
    # reconstructed_shape = transform.pseudoinverse().apply(
    # reconstructed_normalized_shape)
    trans_reconstructed_shape = AlignmentAffine(reconstructed_normalized_shape,
                                                trumpShape)
    reconstructed_img_shape = trans_reconstructed_shape.apply(
        reconstructed_normalized_shape)
    return reconstructed_img_shape
Esempio n. 7
0
def test_align_2d_affine_compose_target():
    source = PointCloud(np.array([[0, 1], [1, 1], [-1, -5], [3, -5]]))
    target = UniformScale(2.0, n_dims=2).apply(source)
    original_estimate = AlignmentAffine(source, target)
    new_estimate = original_estimate.copy()
    new_estimate.compose_after_from_vector_inplace(
        np.array([0, 0, 0, 0, 1, 1.]))
    estimate_target = new_estimate.target

    correct_target = original_estimate.compose_after(Translation(
        [1, 1.])).apply(source)

    assert_allclose(estimate_target.points, correct_target.points)
Esempio n. 8
0
def test_align_2d_affine_set_target():
    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 = Affine(h_matrix)
    source = PointCloud(np.array([[0, 1], [1, 1], [-1, -5], [3, -5]]))
    target = affine.apply(source)
    # estimate the transform from source and source
    estimate = AlignmentAffine(source, source)
    # and set the target
    estimate.set_target(target)
    # check the estimates is correct
    assert_allclose(affine.h_matrix, estimate.h_matrix)
Esempio n. 9
0
def test_align_2d_affine_set_h_matrix():
    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 = Affine(h_matrix)
    source = PointCloud(np.array([[0, 1], [1, 1], [-1, -5], [3, -5]]))
    target = affine.apply(source)
    # estimate the transform from source and source
    estimate = AlignmentAffine(source, source)
    # and set the h_matrix
    estimate.set_h_matrix(affine.h_matrix)
    # check the estimates is correct
    assert_allclose(target.points, estimate.target.points)
Esempio n. 10
0
    def fit_from_bb(self,
                    image,
                    bounding_box,
                    max_iters=20,
                    gt_shape=None,
                    crop_image=None,
                    **kwargs):
        # generate the list of images to be fitted
        images, bounding_boxes, gt_shapes = self._prepare_image(
            image, bounding_box, gt_shape=gt_shape, crop_image=crop_image)

        # work out the affine transform between the initial shape of the
        # highest pyramidal level and the initial shape of the original image
        affine_correction = AlignmentAffine(bounding_boxes[-1], bounding_box)

        # run multilevel fitting
        algorithm_results = self._fit(images,
                                      bounding_boxes[0],
                                      max_iters=max_iters,
                                      gt_shapes=gt_shapes,
                                      **kwargs)

        # build multilevel fitting result
        fitter_result = self._fitter_result(image,
                                            algorithm_results,
                                            affine_correction,
                                            gt_shape=gt_shape)

        return fitter_result
Esempio n. 11
0
def test_align_2d_affine_compose_target():
    source = PointCloud(np.array([[0, 1],
                                  [1, 1],
                                  [-1, -5],
                                  [3, -5]]))
    target = UniformScale(2.0, n_dims=2).apply(source)
    original_estimate = AlignmentAffine(source, target)
    new_estimate = original_estimate.copy()
    new_estimate.compose_after_from_vector_inplace(
        np.array([0, 0, 0, 0, 1, 1.]))
    estimate_target = new_estimate.target

    correct_target = original_estimate.compose_after(
        Translation([1, 1.])).apply(source)

    assert_allclose(estimate_target.points, correct_target.points)
Esempio n. 12
0
    def fit(self, image, initial_shape, max_iters=50, gt_shape=None,
            **kwargs):
        r"""
        Fits the multilevel fitter to an image.

        Parameters
        -----------
        image: :map:`Image` or subclass
            The image to be fitted.

        initial_shape: :map:`PointCloud`
            The initial shape estimate from which the fitting procedure
            will start.

        max_iters: `int` or `list` of `int`, optional
            The maximum number of iterations.
            If `int`, specifies the overall maximum number of iterations.
            If `list` of `int`, specifies the maximum number of iterations per
            level.

        gt_shape: :map:`PointCloud`
            The ground truth shape associated to the image.

        **kwargs:
            Additional keyword arguments that can be passed to specific
            implementations of ``_fit`` method.

        Returns
        -------
        multi_fitting_result: :map:`MultilevelFittingResult`
            The multilevel fitting result containing the result of
            fitting procedure.
        """
        # generate the list of images to be fitted
        images, initial_shapes, gt_shapes = self._prepare_image(
            image, initial_shape, gt_shape=gt_shape)

        # detach added landmarks from image
        del image.landmarks['initial_shape']
        if gt_shape:
            del image.landmarks['gt_shape']

        # work out the affine transform between the initial shape of the
        # highest pyramidal level and the initial shape of the original image
        affine_correction = AlignmentAffine(initial_shapes[-1], initial_shape)

        # run multilevel fitting
        fitting_results = self._fit(images, initial_shapes[0],
                                    max_iters=max_iters,
                                    gt_shapes=gt_shapes, **kwargs)

        # build multilevel fitting result
        multi_fitting_result = self._create_fitting_result(
            image, fitting_results, affine_correction, gt_shape=gt_shape)

        return multi_fitting_result
    def _prepare_image(self, image, initial_shape):
        r"""
        Function the performs pre-processing on the image to be fitted. This
        involves the following steps:

            1. Rescale image so that the provided initial_shape has the
               specified diagonal.
            2. Compute features
            3. Estimate the affine transform introduced by the rescale to
               diagonal and features extraction

        Parameters
        ----------
        image : `menpo.image.Image` or subclass
            The image to be fitted.
        initial_shape : `menpo.shape.PointCloud`
            The initial shape estimate from which the fitting procedure
            will start.

        Returns
        -------
        image : `menpo.image.Image`
            The feature-based image.
        initial_shape : `menpo.shape.PointCloud`
            The rescaled initial shape.
        affine_transform : `menpo.transform.Affine`
            The affine transform that is the inverse of the transformations
            introduced by the rescale wrt diagonal as well as the feature
            extraction.
        """
        # Attach landmarks to the image, in order to make transforms easier
        image.landmarks['__initial_shape'] = initial_shape

        if self.diagonal is not None:
            # Rescale image so that initial_shape matches the provided diagonal
            tmp_image = image.rescale_landmarks_to_diagonal_range(
                self.diagonal, group='__initial_shape')
        else:
            tmp_image = image
        # Extract features
        feature_image = self.holistic_features(tmp_image)

        # Get final transformed landmarks
        new_initial_shape = feature_image.landmarks['__initial_shape']

        # Now we have introduced an affine transform that consists of the image
        # rescaled based on the diagonal, as well as potential rescale
        # (down-sampling) caused by features. We need to store this transform
        # (estimated by AlignmentAffine) in order to be able to revert it at
        # the final fitting result.
        affine_transform = AlignmentAffine(new_initial_shape, initial_shape)

        # Detach added landmarks from image
        del image.landmarks['__initial_shape']

        return feature_image, new_initial_shape, affine_transform
Esempio n. 14
0
    def fit(self, image, initial_shape, max_iters=50, gt_shape=None,
            error_type='me_norm', verbose=False, view=False, **kwargs):
        r"""
        Fits a single image.

        Parameters
        -----------
        image: :class:`menpo.image.masked.MaskedImage`
            The image to be fitted.
        initial_shape: :class:`menpo.shape.PointCloud`
            The initial shape estimate from which the fitting procedure
            will start.
        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
        gt_shape: PointCloud
            The groundtruth shape of the image.

            Default: None
        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'
        verbose: boolean, optional
            If True, it prints information related to the fitting results (such
            as: final error, convergence, ...).

            Default: False
        view: boolean, optional
            If True, the final fitting result will be visualized.

            Default: False

        **kwargs:

        Returns
        -------
        fitting_list: :map:`FittingResultList`
            A fitting result object.
        """
        # copy image
        image = image.copy()

        # generate image pyramid
        images = self._prepare_image(image, initial_shape, gt_shape=gt_shape)

        # get ground truth shape per level
        if gt_shape:
            gt_shapes = [i.landmarks['gt_shape'].lms for i in images]
        else:
            gt_shapes = None

        # get initial shape per level
        initial_shapes = [i.landmarks['initial_shape'].lms for i in images]

        affine_correction = AlignmentAffine(initial_shapes[-1], initial_shape)

        # execute multilevel fitting
        fitting_results = self._fit(images, initial_shapes[0],
                                    max_iters=max_iters,
                                    gt_shapes=gt_shapes, **kwargs)

        # store result
        multilevel_fitting_result = self._create_fitting_result(
            image, fitting_results, affine_correction, gt_shape=gt_shape,
            error_type=error_type)

        if verbose:
            print(multilevel_fitting_result)
        if view:
            multilevel_fitting_result.view_final_fitting(new_figure=True)

        return multilevel_fitting_result
Esempio n. 15
0
    def _prepare_image(self, image, initial_shape, gt_shape=None):
        r"""
        Function the performs pre-processing on the image to be fitted. This
        involves the following steps:

            1. Rescale image wrt the scale factor between the reference_shape
               and the initial_shape.
            2. For each scale:
                  3. Compute features
                  4. Estimate the affine transform introduced by the rescale to
                     reference shape and features extraction
                  5. Rescale image
                  6. Save affine transform, scale transform and final image

        Parameters
        ----------
        image : `menpo.image.Image` or subclass
            The image to be fitted.
        initial_shape : `menpo.shape.PointCloud`
            The initial shape estimate from which the fitting procedure
            will start.
        gt_shape : `menpo.shape.PointCloud`, optional
            The ground truth shape associated to the image.

        Returns
        -------
        images : `list` of `menpo.image.Image`
            The list of images per scale.
        initial_shapes : `list` of `menpo.shape.PointCloud`
            The list of initial shapes per scale.
        gt_shapes : `list` of `menpo.shape.PointCloud`
            The list of ground truth shapes per scale.
        affine_transforms : `list` of `menpo.transform.Affine`
            The list of affine transforms per scale that are the inverses of the
            transformations introduced by the rescale wrt the reference shape as
            well as the feature extraction.
        scale_transforms : `list` of `menpo.shape.Scale`
            The list of inverse scaling transforms per scale.
        """
        # Attach landmarks to the image, in order to make transforms easier
        image.landmarks['__initial_shape'] = initial_shape
        if gt_shape:
            image.landmarks['__gt_shape'] = gt_shape

        # Rescale image wrt the scale factor between reference_shape and
        # initial_shape
        #tmp_image = image.rescale_to_pointcloud(self.reference_shape,
        #                                      group='__initial_shape')

        tmp_image = image.rescale_to_pointcloud(gt_shape, group='__gt_shape')
        #tmp_image = image

        # For each scale:
        #     1. Compute features
        #     2. Estimate the affine transform introduced by the rescale to
        #        reference shape and features extraction
        #     2. Rescale image
        #     3. Save affine transform, scale transform and final image
        images = []
        affine_transforms = []
        scale_transforms = []
        for i in range(self.n_scales):
            # Extract features
            if (i == 0 or self.holistic_features[i] !=
                    self.holistic_features[i - 1]):
                # Compute features only if this is the first pass through
                # the loop or the features at this scale are different from
                # the features at the previous scale
                feature_image = self.holistic_features[i](tmp_image)

                # Until now, we have introduced an affine transform that
                # consists of the image rescale to the reference shape,
                # as well as potential rescale (down-sampling) caused by
                # features. We need to store this transform (estimated by
                # AlignmentAffine) in order to be able to revert it at the
                # final fitting result.
                affine_transforms.append(
                    AlignmentAffine(
                        feature_image.landmarks['__initial_shape'].lms,
                        initial_shape))
            else:
                # If features are not extracted, then the affine transform
                # should be identical with the one of the first (lowest) level.
                affine_transforms.append(affine_transforms[0])

            # Rescale images according to scales
            if self.scales[i] != 1:
                # Scale feature images only if scale is different than 1
                scaled_image, scale_transform = feature_image.rescale(
                    self.scales[i], return_transform=True)
            else:
                # Otherwise the image remains the same and the transform is the
                # identity matrix.
                scaled_image = feature_image
                scale_transform = Scale(1., initial_shape.n_dims)

            # rewrite response map data
            # scaled_image.rspmap_data = scipy.ndimage.zoom(image.rspmap_data, zoom=[1, 1, float(scaled_image.height) / image.rspmap_data.shape[-2],
            #                                                               float(scaled_image.width) / image.rspmap_data.shape[-1]], order=1)  # mode = 'nearest'

            scaled_image.rspmap_data = image.rspmap_data
            # Add scale transform to list
            scale_transforms.append(scale_transform)

            scaled_image.path = image.path
            # Add scaled image to list
            images.append(scaled_image)

        # Get initial shapes per level
        initial_shapes = [i.landmarks['__initial_shape'].lms for i in images]

        # Get ground truth shapes per level
        if gt_shape:
            gt_shapes = [i.landmarks['__gt_shape'].lms for i in images]
        else:
            gt_shapes = None

        # Detach added landmarks from image
        del image.landmarks['__initial_shape']
        if gt_shape:
            del image.landmarks['__gt_shape']

        return (images, initial_shapes, gt_shapes, affine_transforms,
                scale_transforms)
Esempio n. 16
0
    def fit(self,
            image,
            initial_shape,
            max_iters=50,
            gt_shape=None,
            crop_image=None,
            **kwargs):
        r"""
        Fits the multilevel algorithm to an image.

        Parameters
        -----------
        image: :map:`Image` or subclass
            The image to be fitted.

        initial_shape: :map:`PointCloud`
            The initial shape estimate from which the fitting procedure
            will start.

        max_iters: `int` or `list` of `int`, optional
            The maximum number of iterations.
            If `int`, specifies the overall maximum number of iterations.
            If `list` of `int`, specifies the maximum number of iterations per
            level.

        gt_shape: :map:`PointCloud`
            The ground truth shape associated to the image.

        crop_image: `None` or float`, optional
            If `float`, it specifies the proportion of the border wrt the
            initial shape to which the image will be internally cropped around
            the initial shape range.
            If `None`, no cropping is performed.

            This will limit the fitting algorithm search region but is
            likely to speed up its running time, specially when the
            modeled object occupies a small portion of the image.

        **kwargs:
            Additional keyword arguments that can be passed to specific
            implementations of ``_fit`` method.

        Returns
        -------
        multi_fitting_result: :map:`MultilevelFittingResult`
            The multilevel fitting result containing the result of
            fitting procedure.
        """

        # generate the list of images to be fitted
        images, initial_shapes, gt_shapes = self._prepare_image(
            image, initial_shape, gt_shape=gt_shape, crop_image=crop_image)

        # detach added landmarks from image
        del image.landmarks['initial_shape']
        if gt_shape:
            del image.landmarks['gt_shape']

        # work out the affine transform between the initial shape of the
        # highest pyramidal level and the initial shape of the original image
        affine_correction = AlignmentAffine(initial_shapes[-1], initial_shape)

        # run multilevel fitting
        algorithm_results = self._fit(images,
                                      initial_shapes[0],
                                      max_iters=max_iters,
                                      gt_shapes=gt_shapes,
                                      **kwargs)

        # build multilevel fitting result
        fitter_result = self._fitter_result(image,
                                            algorithm_results,
                                            affine_correction,
                                            gt_shape=gt_shape)

        return fitter_result
Esempio n. 17
0
    def fit(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:`pybug.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:`pybug.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 = AlignmentAffine(initial_shapes[-1], initial_shape)

        fittings = self._fit(images,
                             initial_shapes[0],
                             max_iters=max_iters,
                             gt_shapes=gt_shapes,
                             **kwargs)

        multiple_fitting = self._create_fitting(image,
                                                fittings,
                                                affine_correction,
                                                gt_shape=gt_shape,
                                                error_type=error_type)

        if verbose:
            multiple_fitting.print_fitting_info()
        if view:
            multiple_fitting.view_final_fitting(new_figure=True)

        return multiple_fitting
Esempio n. 18
0
def affine_test(path_to_images):
    # create pca model based on training set
    shape_model = pca(path_to_images)
    # create test image
    # testImage = mio.import_builtin_asset.takeo_ppm()
    testImage = mio.import_image(
        '/home/sean/workplace/221/py-R-FCN-test/data/DB/face/300-w_face/otherDB/aflw-full/testset/0_image00002_1.jpg'
    )

    # Find the affine transform that normalizes the shape
    # with respect to the mean shape
    # shape = testImage.landmarks['PTS']
    # transform = AlignmentAffine(shape, shape_model.model.mean())

    # image change size to adapt the scale of kp to that of target_kp
    tmp_image = testImage.rescale_to_pointcloud(shape_model.model.mean(),
                                                group='PTS')

    transform = AlignmentAffine(testImage.landmarks['PTS'],
                                tmp_image.landmarks['PTS'])
    new_shape = transform.apply(
        testImage.landmarks['PTS'])  # equal to kp of tmp

    # warp image
    # new_image = testImage.warp_to_shape(tmp_image.shape, transform.pseudoinverse(),
    #               warp_landmarks=True, order=1,
    #               mode='nearest',
    #               return_transform=False)
    #
    # plt.subplot(131)
    # testImage.view_landmarks(marker_face_colour='white', marker_edge_colour='black',
    #                          marker_size=4, render_axes=True)
    # plt.gca().set_title('Original image')
    # plt.subplot(132)
    # new_image.view_landmarks(marker_face_colour='white', marker_edge_colour='black',
    #                          marker_size=4, render_axes=True)
    # plt.gca().set_title('Rescale image')
    # plt.subplot(133)
    # tmp_image.view_landmarks(marker_face_colour='white', marker_edge_colour='black',
    #                          marker_size=4, render_axes=True)
    # plt.gca().set_title('Template image')

    # create a noise shape
    # noisy_shape = noisy_shape_from_shape(testImage.landmarks['PTS'], testImage.landmarks['PTS'],
    #                                         noise_percentage=0.2,
    #                                         allow_alignment_rotation=True)
    # transform = AlignmentAffine(testImage.landmarks['PTS'], noisy_shape)

    # similarity = AlignmentSimilarity(testImage.landmarks['PTS'],
    #                                               testImage.landmarks['PTS'],
    #                                               rotation=True)
    s = compositions.scale_about_centre(testImage.landmarks['PTS'], 1)
    r = compositions.rotate_ccw_about_centre(testImage, 90)
    t = compositions.Translation([0, 0], testImage.n_dims)
    # transform = similarity.compose_after(t.compose_after(s.compose_after(r)))
    transform = t.compose_after(s.compose_after(r))
    # new_shape = transform.apply(testImage.landmarks['PTS'])

    # warp image
    new_image = testImage.warp_to_shape(testImage.shape,
                                        transform.pseudoinverse(),
                                        warp_landmarks=True,
                                        order=1,
                                        mode='nearest',
                                        return_transform=False)
    plt.subplot(121)
    testImage.view_landmarks(marker_face_colour='white',
                             marker_edge_colour='black',
                             marker_size=4,
                             render_axes=True)
    plt.gca().set_title('Original image')
    plt.subplot(122)
    new_image.view_landmarks(marker_face_colour='white',
                             marker_edge_colour='black',
                             marker_size=4,
                             render_axes=True)
    plt.gca().set_title('Rescale image')
    plt.close('all')
def project(target, source_model):
    # align the source and target face
    transform = AlignmentAffine(target, source_model.model.mean())
    normalized_target = transform.apply(target)
    weights = source_model.model.project(normalized_target)
    return weights
Esempio n. 20
0
def affine_enhance(path_to_images,
                   save_dir=None,
                   scales=[1],
                   rotations=[0],
                   translations=[[0, 0]],
                   mean_shape=1):
    if save_dir is not None:
        mk_dir(save_dir, 0)
    # load training images
    train_images = []
    for path_to_image in path_to_images:
        for img in print_progress(
                mio.import_images(path_to_image, verbose=True)):
            train_images.append(img)
    print 'sum of training data: %d' % len(train_images)
    # create pca model based on training set
    # shape_model = pca(path_train_images)
    shape_model = pca_image(train_images)
    excepted_num = len(scales) * len(rotations) * len(translations) * len(
        train_images)
    completed_num = 0
    for train_img in train_images:
        if mean_shape:
            transform = AlignmentAffine(train_img.landmarks['PTS'],
                                        shape_model.model.mean())
            [r1, s, r2, t] = transform.decompose()
            # transform = r2.compose_after(s.compose_after(r1))
            transform = r2.compose_after(r1)
            rotation_shape = transform.apply(train_img.landmarks['PTS'])
            offset = train_img.landmarks['PTS'].centre(
            ) - rotation_shape.centre()
            t = compositions.Translation(offset, train_img.n_dims)
            transform = t.compose_after(r2.compose_after(r1))
            normal_image = train_img.warp_to_shape(train_img.shape,
                                                   transform.pseudoinverse(),
                                                   warp_landmarks=True,
                                                   order=1,
                                                   mode='nearest',
                                                   return_transform=False)
        else:
            normal_image = train_img
        for scale in scales:
            for rotation in rotations:
                for translation in translations:
                    s = compositions.scale_about_centre(
                        normal_image.landmarks['PTS'], scale)
                    r = compositions.rotate_ccw_about_centre(
                        normal_image, rotation)
                    t = compositions.Translation(translation,
                                                 normal_image.n_dims)
                    transform = t.compose_after(s.compose_after(r))

                    # warp image
                    new_image = normal_image.warp_to_shape(
                        normal_image.shape,
                        transform.pseudoinverse(),
                        warp_landmarks=True,
                        order=1,
                        mode='nearest',
                        return_transform=False)
                    # plt.subplot(121)
                    # normal_image.view_landmarks(marker_face_colour='white', marker_edge_colour='black',
                    #                          marker_size=4, render_axes=True)
                    # plt.gca().set_title('Original image')
                    # plt.subplot(122)
                    # new_image.view_landmarks(marker_face_colour='white', marker_edge_colour='black',
                    #                          marker_size=4, render_axes=True)
                    # plt.gca().set_title('Rescale image')
                    # plt.close('all')

                    # save enhanced image with lable
                    img_suffix = new_image.path.suffix
                    lb_suffix = '.pts'
                    dataType = filter(lambda x: x in str(new_image.path),
                                      support_types)[0]
                    new_image_name = '%s_' % dataType + new_image.path.name.split(
                        '.')[0] + '_s%s_r%s_x%s_y%s' % (
                            str(scale), str(rotation), str(
                                translation[0]), str(translation[1]))
                    img_path = os.path.join(save_dir,
                                            new_image_name + img_suffix)
                    lb_path = os.path.join(save_dir,
                                           new_image_name + lb_suffix)
                    mio.export_image(new_image, img_path, overwrite=True)
                    mio.export_landmark_file(new_image.landmarks['PTS'],
                                             lb_path,
                                             overwrite=True)

                    # plt.subplot(121)
                    # new_image.view_landmarks(marker_face_colour='white', marker_edge_colour='black',
                    #                             marker_size=4, render_axes=True)
                    # plt.gca().set_title('new image')
                    # save_image = mio.import_image(img_path)
                    # plt.subplot(122)
                    # save_image.view_landmarks(marker_face_colour='white', marker_edge_colour='black',
                    #                          marker_size=4, render_axes=True)
                    # plt.gca().set_title('saved image')
                    # plt.close('all')
                    completed_num = completed_num + 1
                    print 'completed: %d/%d' % (completed_num, excepted_num)