예제 #1
0
def test_mean_pointcloud_type():
    points = np.array([[1, 2, 3], [1, 1, 1]])
    trilist = np.array([0, 1, 2])
    pcs = [TriMesh(points, trilist), TriMesh(points + 2, trilist)]
    mean_pc = mean_pointcloud(pcs)
    assert isinstance(mean_pc, TriMesh)
    assert_allclose(mean_pc.points, points + 1)
예제 #2
0
def grid_view(daams,
              fitter,
              final_shape,
              image=None,
              angle=0,
              indexes=None,
              trilist=None):
    t = fitter.algorithms[-1]
    t = t.transform

    t.set_target(final_shape)

    sub, sampled = subsample_dense_pointclouds([
        PointCloud(daams.reference_frame.landmarks['source'].lms.
                   points[daams.n_landmarks:])
    ],
                                               daams.reference_frame.shape,
                                               mask=daams.reference_frame.mask)

    index = []
    for p in sub[0].points:
        for i, pp in enumerate(
                daams.reference_frame.landmarks['source'].lms.points):
            if np.all(p == pp):
                index.append(i)

    if indexes:
        index = indexes + index
    else:
        index = range(daams.n_landmarks) + index

    tm = TriMesh(daams.reference_frame.landmarks['source'].lms.points[index])

    if not trilist is None:
        tm_fit = TriMesh(t.target.points[index], trilist)
    else:
        tm_fit = TriMesh(t.target.points[index], tm.trilist)

    if image:
        image = build_reference_frame(final_shape)
        image.landmarks['DENSE'] = t.target
        img = image

        img.landmarks['trim'] = tm_fit
        img = img.rotate_ccw_about_centre(angle - 360)
        img = img.crop_to_landmarks_proportion(1, group='trim')
        img.view_widget()
    else:
        tm_fit.view()
        return tm_fit, t.target
예제 #3
0
def test_chain_pwa_before_tps():
    a_tm = TriMesh(np.random.random([10, 2]))
    b = PointCloud(np.random.random([10, 2]))
    pwa = PiecewiseAffine(a_tm, b)
    tps = ThinPlateSplines(b, a_tm)
    chain = pwa.compose_before(tps)
    assert (isinstance(chain, TransformChain))
예제 #4
0
def duplicate_vertices(mesh):
    # generate a new mesh with unique vertices per triangle
    # (i.e. duplicate verts so that each triangle is unique)    old_to_new = mesh.trilist.ravel()
    old_to_new = mesh.trilist.ravel()
    new_trilist = np.arange(old_to_new.shape[0]).reshape([-1, 3])
    new_points = mesh.points[old_to_new]
    return TriMesh(new_points, trilist=new_trilist), old_to_new
예제 #5
0
def _construct_shape_type(points, trilist, tcoords, texture,
                          colour_per_vertex):
    # Four different outcomes - either we have a textured mesh, a coloured
    # mesh or just a plain mesh or we fall back to a plain pointcloud.
    if trilist is None:
        obj = PointCloud(points, copy=False)
    elif tcoords is not None and texture is not None:
        obj = TexturedTriMesh(points,
                              tcoords,
                              texture,
                              trilist=trilist,
                              copy=False)
    elif colour_per_vertex is not None:
        obj = ColouredTriMesh(points,
                              trilist=trilist,
                              colours=colour_per_vertex,
                              copy=False)
    else:
        # TriMesh fall through
        obj = TriMesh(points, trilist=trilist, copy=False)

    if tcoords is not None and texture is None:
        warnings.warn('tcoords were found, but no texture was recovered, '
                      'reverting to an untextured mesh.')
    if texture is not None and tcoords is None:
        warnings.warn('texture was found, but no tcoords were recovered, '
                      'reverting to an untextured mesh.')

    return obj
예제 #6
0
def getTriMeshfromPly(path):
    data = []
    with open(path) as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=' ')
        for row in csv_reader:
            data.append(row)

    flag = False
    points = []
    trilist = []
    count = 0
    for row in range(len(data)):
        if (data[row][0] == 'element') and (data[row][1] == 'vertex'):
            numOfVertices = int(data[row][2])
        if flag and count < numOfVertices:
            data[row][0] = "{0:.6f}".format(float(data[row][0]))
            data[row][1] = "{0:.6f}".format(float(data[row][1]))
            data[row][2] = "{0:.6f}".format(float(data[row][2]))
            points.append([
                float(data[row][0]),
                float(data[row][1]),
                float(data[row][2])
            ])
            count = count + 1
        elif flag and count >= numOfVertices:
            if data[row][0] == '3':
                trilist.append(
                    [int(data[row][1]),
                     int(data[row][2]),
                     int(data[row][3])])
        if (data[row][0] == 'end_header'):
            flag = True
    points_np = np.array(points)
    trilist_np = np.array(trilist)
    return TriMesh(points_np, trilist_np)
def face_ibug_68_to_face_ibug_68_trimesh(pcloud):
    r"""
    Apply the IBUG 68-point semantic labels, with trimesh connectivity.

    The semantic labels applied are as follows:

      - tri

    References
    ----------
    .. [1] http://www.multipie.org/
    .. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
    """
    from menpo.shape import TriMesh

    n_expected_points = 68
    validate_input(pcloud, n_expected_points)

    tri_list = np.array([[47, 29, 28], [44, 43, 23], [38, 20, 21],
                         [47, 28, 42], [49, 61, 60], [40, 41, 37],
                         [37, 19, 20], [28, 40, 39], [38, 21, 39],
                         [36,  1,  0], [48, 59,  4], [49, 60, 48],
                         [67, 59, 60], [13, 53, 14], [61, 51, 62],
                         [57,  8,  7], [52, 51, 33], [61, 67, 60],
                         [52, 63, 51], [66, 56, 57], [35, 30, 29],
                         [53, 52, 35], [37, 36, 17], [18, 37, 17],
                         [37, 38, 40], [38, 37, 20], [19, 37, 18],
                         [38, 39, 40], [28, 29, 40], [41, 36, 37],
                         [27, 39, 21], [41, 31,  1], [30, 32, 31],
                         [33, 51, 50], [33, 30, 34], [31, 40, 29],
                         [36,  0, 17], [31,  2,  1], [31, 41, 40],
                         [ 1, 36, 41], [31, 49,  2], [ 2, 49,  3],
                         [60, 59, 48], [ 3, 49, 48], [31, 32, 50],
                         [48,  4,  3], [59,  5,  4], [58, 67, 66],
                         [ 5, 59, 58], [58, 59, 67], [ 7,  6, 58],
                         [66, 57, 58], [13, 54, 53], [ 7, 58, 57],
                         [ 6,  5, 58], [50, 61, 49], [62, 67, 61],
                         [31, 50, 49], [32, 33, 50], [30, 33, 32],
                         [34, 52, 33], [35, 52, 34], [53, 63, 52],
                         [62, 63, 65], [62, 51, 63], [66, 65, 56],
                         [63, 53, 64], [62, 66, 67], [62, 65, 66],
                         [57, 56,  9], [65, 63, 64], [ 8, 57,  9],
                         [ 9, 56, 10], [10, 56, 11], [11, 56, 55],
                         [11, 55, 12], [56, 65, 55], [55, 64, 54],
                         [55, 65, 64], [55, 54, 12], [64, 53, 54],
                         [12, 54, 13], [45, 46, 44], [35, 34, 30],
                         [14, 53, 35], [15, 46, 45], [27, 28, 39],
                         [27, 42, 28], [35, 29, 47], [30, 31, 29],
                         [15, 35, 46], [15, 14, 35], [43, 22, 23],
                         [27, 21, 22], [24, 44, 23], [44, 47, 43],
                         [43, 47, 42], [46, 35, 47], [26, 45, 44],
                         [46, 47, 44], [25, 44, 24], [25, 26, 44],
                         [16, 15, 45], [16, 45, 26], [22, 42, 43],
                         [50, 51, 61], [27, 22, 42]])
    new_pcloud = TriMesh(pcloud.points, tri_list)

    mapping = OrderedDict()
    mapping['tri'] = np.arange(new_pcloud.n_points)

    return new_pcloud, mapping
def eye_ibug_close_17_to_eye_ibug_close_17_trimesh(pcloud):
    r"""
    Apply the IBUG 17-point close eye semantic labels, with trimesh
    connectivity.

    The semantic labels applied are as follows:

      - tri
    """
    from menpo.shape import TriMesh

    n_expected_points = 17
    validate_input(pcloud, n_expected_points)

    tri_list = np.array([[10, 11, 13], [ 3, 13,  2], [ 4, 14,  3],
                         [15,  5, 16], [12, 11,  0], [13, 14, 10],
                         [13, 12,  2], [14, 13,  3], [ 0,  1, 12],
                         [ 2, 12,  1], [13, 11, 12], [ 9, 10, 14],
                         [15,  9, 14], [ 7,  8, 15], [ 5,  6, 16],
                         [15, 14,  4], [ 7, 15, 16], [ 8,  9, 15],
                         [15,  4,  5], [16,  6,  7]])

    new_pcloud = TriMesh(pcloud.points, tri_list, copy=False)

    mapping = OrderedDict()
    mapping['tri'] = np.arange(new_pcloud.n_points)

    return new_pcloud, mapping
예제 #9
0
def chain_tps_after_pwa_test():
    a_tm = TriMesh(np.random.random([10, 2]))
    b = PointCloud(np.random.random([10, 2]))
    pwa = PiecewiseAffine(a_tm, b)
    tps = ThinPlateSplines(b, a_tm)
    chain = tps.compose_after(pwa)
    assert(isinstance(chain, TransformChain))
예제 #10
0
def test_trimesh_creation_copy_warning():
    points = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]])
    trilist = np.array([[0, 1, 3], [1, 2, 3]], order='F')
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        TriMesh(points, trilist=trilist, copy=False)
        assert len(w) == 1
예제 #11
0
    def constrain_to_pointcloud(self, pointcloud, trilist=None):
        r"""
        Restricts this mask to be equal to the convex hull around a point cloud

        Parameters
        ----------
        pointcloud : :map:`PointCloud`
            The pointcloud of points that should be constrained to

        trilist: (t, 3) ndarray, Optional
            Triangle list to be used on the points in selecting
            the mask region. If None defaults to performing Delaunay
            triangulation on the points.

            Default: None
        """
        from menpo.transform.piecewiseaffine import PiecewiseAffine
        from menpo.transform.piecewiseaffine import TriangleContainmentError

        if self.n_dims != 2:
            raise ValueError("can only constrain mask on 2D images.")

        if trilist is not None:
            from menpo.shape import TriMesh
            pointcloud = TriMesh(pointcloud.points, trilist)

        pwa = PiecewiseAffine(pointcloud, pointcloud)
        try:
            pwa.apply(self.indices)
        except TriangleContainmentError as e:
            self.from_vector_inplace(~e.points_outside_source_domain)
예제 #12
0
 def __init__(self, source, target):
     from menpo.shape import TriMesh  # to avoid circular import
     if not isinstance(source, TriMesh):
         source = TriMesh(source.points)
     Alignment.__init__(self, source, target)
     if self.n_dims != 2:
         raise ValueError("source and target must be 2 "
                          "dimensional")
예제 #13
0
def test_trimesh_creation():
    points = np.array([[0, 0, 0],
                       [1, 0, 0],
                       [1, 1, 0],
                       [0, 1, 0]])
    trilist = np.array([[0, 1, 3],
                        [1, 2, 3]])
    TriMesh(points, trilist)
예제 #14
0
def calculate_errors_4DMaja_real(path_fits, path_gt, model):
    # Parameters:
    # --------------
    #  path_fits: 'string' of the directory that contains your reconstructed meshes.
    #             Meshes' filenames should be the same with the
    #             corresponding ground truth meshes filenames + the suffix of
    #             the mesh type (e.g <frame_number>.obj, <frame_number>.ply)
    #  path_gt  : 'string' of the full path of the ground truth mesh.
    #  model    : 'string' of the model template you are using. Should be one of the
    #             following: 'LSFM', 'Basel', 'Surrey'
    # Returns:
    # --------------
    #  errors   : python list that contains the error per vertex between the ground
    #             truth mesh and a mean mesh calculated from your reconstructed meshes

    path_fits = Path(path_fits)
    path_gt = Path(path_gt)

    # load meshes' filenames
    filenames = [p.name for p in path_fits.glob('*')]
    filenames.sort()

    # load gt_mesh (it is olny one, maja's neautral face)
    gt_mesh = m3io.import_mesh(path_gt, texture_resolver=None)
    gt_mesh.landmarks['ibug49'] = PointCloud(gt_mesh.points[lms_indexes][19:])

    errors = [0]

    # accumulate fits
    acc_points = np.zeros((gt_mesh.n_points, 3))
    for i, filename in enumerate(print_progress(filenames)):

        fit_3d = m3io.import_mesh(path_fits / filename, texture_resolver=None)
        if model == 'Surrey':
            lms = face_ibug_49_to_face_ibug_49(
                PointCloud(fit_3d.points[eos.load_eos_low_res_lm_index()]))
            fit_3d = eos.upsample_eos_low_res_to_fw_no_texture(fit_3d)
            fit_3d.landmarks['ibug49'] = lms
        elif model == 'LSFM' or model == 'Basel':
            fit_3d.landmarks['ibug49'] = PointCloud(
                fit_3d.points[lms_indexes][19:])
        else:
            print('Error: Not supported model template')
            return

        acc_points += fit_3d.points

    # create mean_fit_3d
    mean_fit_3d = TriMesh(acc_points / len(filenames), gt_mesh.trilist)
    mean_fit_3d.landmarks['ibug49'] = PointCloud(
        mean_fit_3d.points[lms_indexes][19:])

    # calculate per vertex errors between the neutral gt_mesh and the mean_fit_3d
    gt_mesh, eval_mask = landmark_and_mask_gt_mesh(gt_mesh, distance=1)
    errors[0], _, _ = mask_align_and_calculate_dense_error(
        mean_fit_3d, gt_mesh, eval_mask)

    return errors
예제 #15
0
def test_trimesh_from_tri_mask():
    points = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]])
    trilist = np.array([[0, 1, 3], [1, 2, 3]])
    mask = np.zeros(2, dtype=np.bool)
    mask[0] = True
    trimesh = TriMesh(points, trilist=trilist).from_tri_mask(mask)
    assert (trimesh.n_tris == 1)
    assert (trimesh.n_points == 3)
    assert_allclose(trimesh.points, points[trilist[0]])
예제 #16
0
def test_trimesh_n_tris():
    points = np.array([[0, 0, 0],
                       [1, 0, 0],
                       [1, 1, 0],
                       [0, 1, 0]])
    trilist = np.array([[0, 1, 3],
                        [1, 2, 3]])
    trimesh = TriMesh(points, trilist)
    assert(trimesh.n_tris == 2)
예제 #17
0
def test_trimesh_face_normals():
    points = np.array([[0.0, 0.0, -1.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0],
                       [0.0, 1.0, 0.0]])
    trilist = np.array([[0, 1, 3], [1, 2, 3]])
    expected_normals = np.array(
        [[-np.sqrt(3) / 3, -np.sqrt(3) / 3,
          np.sqrt(3) / 3], [-0, -0, 1]])
    trimesh = TriMesh(points, trilist)
    face_normals = trimesh.tri_normals()
    assert_allclose(face_normals, expected_normals)
예제 #18
0
def test_trimesh_creation_copy_false():
    points = np.array([[0, 0, 0],
                       [1, 0, 0],
                       [1, 1, 0],
                       [0, 1, 0]])
    trilist = np.array([[0, 1, 3],
                        [1, 2, 3]])
    tm = TriMesh(points, trilist, copy=False)
    assert (is_same_array(tm.points, points))
    assert (is_same_array(tm.trilist, trilist))
예제 #19
0
def load_tassos_lsfm_combined_model(path):
    m = loadmat(str(path))
    mean = TriMesh(m['mean'].reshape([-1, 3]), trilist=m['trilist'])
    return {
        'shape_model': PCAModel.init_from_components(
            m['components'].T,  m['eigenvalues'].ravel(),
            mean, 8888, True),
        'n_id_comps': int(m['n_trunc_ids'][0][0]),
        'n_exp_comps': int(m['n_trunc_expressions'][0][0])
    }
예제 #20
0
def generative_construct(DB, fitter, trilist, label=None,
    fit_group='mean', train_group='final',
    feature=igo,
    diagonal=200,
    scales=(0.5, 1.0),
    n_processes=24,
    model_class=HolisticAAM,
    increament_model=None,
    original_shape_model=None,
    shape_forgetting_factor=1.0,
    appearance_forgetting_factor=1.0,
    max_iters=10,

):
    # fix appearance optimize shape
    error = []

#       Multi Processs Computation
    frs = mp_fit(DB, fitter, group=fit_group, n_processes=n_processes, max_iters=max_iters)

    for fr, img in zip(frs, DB):
        img.landmarks[train_group] = TriMesh(fr.final_shape.points, trilist=trilist)
        error.append(fr.final_error(alignment_error))
        if label:
            img.landmarks[label] = TriMesh(fr.final_shape.points, trilist=trilist)

    del fitter
    if increament_model:
        pdm = copy.deepcopy(increament_model)
        pdm.increment(DB, verbose=True, group=train_group,
            shape_forgetting_factor=shape_forgetting_factor,
            appearance_forgetting_factor=appearance_forgetting_factor)
    else:
        pdm = model_class(DB, holistic_features=feature, diagonal=diagonal, scales=scales, verbose=True, group=train_group)

    if original_shape_model:
        pdm.shape_models = original_shape_model

    if increament_model:
        del increament_model

    return pdm, np.mean(error)
예제 #21
0
def _construct_shape_type(points, trilist, tcoords, texture,
                          colour_per_vertex):
    r"""
    Construct the correct Shape subclass given the inputs. TexturedTriMesh
    can only be created when tcoords and texture are available. ColouredTriMesh
    can only be created when colour_per_vertex is non None and TriMesh
    can only be created when trilist is non None. Worst case fall back is
    PointCloud.

    Parameters
    ----------
    points : ``(N, D)`` `ndarray`
        The N-D points.
    trilist : ``(N, 3)`` `ndarray`` or ``None``
        Triangle list or None.
    tcoords : ``(N, 2)`` `ndarray` or ``None``
        Texture coordinates.
    texture : :map:`Image` or ``None``
        Texture.
    colour_per_vertex : ``(N, 1)`` or ``(N, 3)`` `ndarray` or ``None``
        The colour per vertex.

    Returns
    -------
    shape : :map:`PointCloud` or subclass
        The correct shape for the given inputs.
    """
    # Four different outcomes - either we have a textured mesh, a coloured
    # mesh or just a plain mesh or we fall back to a plain pointcloud.
    if trilist is None:
        obj = PointCloud(points, copy=False)
    elif tcoords is not None and texture is not None:
        obj = TexturedTriMesh(points,
                              tcoords,
                              texture,
                              trilist=trilist,
                              copy=False)
    elif colour_per_vertex is not None:
        obj = ColouredTriMesh(points,
                              trilist=trilist,
                              colours=colour_per_vertex,
                              copy=False)
    else:
        # TriMesh fall through
        obj = TriMesh(points, trilist=trilist, copy=False)

    if tcoords is not None and texture is None:
        warnings.warn('tcoords were found, but no texture was recovered, '
                      'reverting to an untextured mesh.')
    if texture is not None and tcoords is None:
        warnings.warn('texture was found, but no tcoords were recovered, '
                      'reverting to an untextured mesh.')

    return obj
예제 #22
0
def test_trimesh_boundary_tri_index():
    points = np.array([[0.0, 0.0, 0.0], [0.5, 0.5, 0.0], [0.0, 0.5, 0.0],
                       [-0.5, 0.5, 0.0], [-0.5, -0.5, 0.0], [0.5, -0.5, 0.0],
                       [0.0, -1.0, 0.0]])
    trilist = np.array([[0, 2, 3], [2, 0, 1], [4, 0, 3], [0, 5, 1], [4, 5, 0],
                        [5, 4, 6]])
    trimesh = TriMesh(points, trilist)
    boundary_tri_index = trimesh.boundary_tri_index()
    # The "middle" triangle is [4, 5, 0] which is surrounded on all sides
    # [5, 4, 6] has two edges that have no neighbours
    assert_allclose(boundary_tri_index, [True, True, True, True, False, True])
예제 #23
0
def from_UV_2_3D(uv, uv_layout='oval', topology='full', plot=False):
    res = uv.shape[0]
    info_dict = import_uv_info(uv, res, uv_layout=uv_layout, topology=topology)

    tmask = info_dict['tmask']
    tc_ps = info_dict['tcoords_pixel_scaled']
    tmask_im = info_dict['tmask_image']
    trilist = info_dict['trilist']

    #uv = interpolaton_of_uv_xyz(uv,tmask).as_unmasked()
    x = uv.pixels[0][(tc_ps.points.astype(int).T[0, :],
                      tc_ps.points.astype(int).T[1, :])]
    y = uv.pixels[1][(tc_ps.points.astype(int).T[0, :],
                      tc_ps.points.astype(int).T[1, :])]
    z = uv.pixels[2][(tc_ps.points.astype(int).T[0, :],
                      tc_ps.points.astype(int).T[1, :])]
    points = np.hstack((x.T[:, None], y.T[:, None], z.T[:, None]))
    if plot is True:
        TriMesh(points, trilist).view()
    return TriMesh(points, trilist)
예제 #24
0
def face_ibug_68_to_face_ibug_51_trimesh(pcloud):
    r"""
    Apply the IBUG 51-point semantic labels, with trimesh connectivity..

    The semantic labels applied are as follows:

      - tri

    References
    ----------
    .. [1] http://www.multipie.org/
    .. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
    """
    from menpo.shape import TriMesh

    # Apply face_ibug_68_to_face_ibug_51
    new_pcloud = face_ibug_68_to_face_ibug_51(pcloud)

    # This is in terms of the 51 points
    tri_list = np.array([[30, 12, 11], [27, 26, 6], [21, 3, 4], [30, 11, 25],
                         [32, 44, 43], [23, 24, 20], [20, 2, 3], [11, 23, 22],
                         [21, 4, 22], [32, 43, 31], [50, 42, 43], [44, 34, 45],
                         [35, 34, 16], [44, 50, 43], [35, 46,
                                                      34], [49, 39, 40],
                         [18, 13, 12], [36, 35, 18], [20, 19, 0], [1, 20, 0],
                         [20, 21, 23], [21, 20, 3], [2, 20, 1], [21, 22, 23],
                         [11, 12, 23], [24, 19, 20], [10, 22, 4], [13, 15, 14],
                         [16, 34, 33], [16, 13, 17], [14, 23,
                                                      12], [14, 24, 23],
                         [43, 42, 31], [14, 15, 33], [41, 50,
                                                      49], [41, 42, 50],
                         [49, 40, 41], [33, 44, 32], [45, 50,
                                                      44], [14, 33, 32],
                         [15, 16, 33], [13, 16, 15], [17, 35,
                                                      16], [18, 35, 17],
                         [36, 46, 35], [45, 46, 48], [45, 34,
                                                      46], [49, 48, 39],
                         [46, 36, 47], [45, 49, 50], [45, 48,
                                                      49], [48, 46, 47],
                         [39, 48, 38], [38, 47, 37], [38, 48,
                                                      47], [47, 36, 37],
                         [28, 29, 27], [18, 17, 13], [10, 11, 22],
                         [10, 25, 11], [18, 12, 30], [13, 14, 12], [26, 5, 6],
                         [10, 4, 5], [7, 27, 6], [27, 30, 26], [26, 30, 25],
                         [29, 18, 30], [9, 28, 27], [29, 30, 27], [8, 27, 7],
                         [8, 9, 27], [5, 25, 26], [33, 34, 44], [10, 5, 25]])

    new_pcloud = TriMesh(new_pcloud.points, trilist=tri_list, copy=False)

    mapping = OrderedDict()
    mapping['tri'] = np.arange(new_pcloud.n_points)

    return new_pcloud, mapping
예제 #25
0
def _get_mean_model(model):
    """
    Get mean BFM mesh.

    Parameters:
        model (BFM dict model): BFM model

    Returns:
        mean_mesh (menpo.shape.mesh.base.TriMesh): mean mesh model
    """
    return TriMesh(points=np.reshape(model['shapeMU'], (-1, 3)),
                   trilist=model['tri'])
예제 #26
0
    def pseudoinverse(self):
        r"""
        The pseudoinverse of the transform - that is, the transform that
        results from swapping `source` and `target`, or more formally, negating
        the transforms parameters. If the transform has a true inverse this
        is returned instead.

        :type: ``type(self)``
        """
        from menpo.shape import PointCloud, TriMesh  # to avoid circular import
        new_source = TriMesh(self.target.points, self.source.trilist)
        new_target = PointCloud(self.source.points)
        return type(self)(new_source, new_target)
def test_trimesh_copy():
    points = np.ones([10, 3])
    trilist = np.ones([10, 3])
    landmarks = PointCloud(np.ones([3, 3]), copy=False)

    tmesh = TriMesh(points, trilist=trilist, copy=False)
    tmesh.landmarks['test'] = landmarks
    tmesh_copy = tmesh.copy()

    assert (not is_same_array(tmesh_copy.points, tmesh.points))
    assert (not is_same_array(tmesh_copy.trilist, tmesh.trilist))
    assert (not is_same_array(tmesh_copy.landmarks['test'].lms.points,
                              tmesh.landmarks['test'].lms.points))
예제 #28
0
def test_trimesh_vertex_normals():
    points = np.array([[0.0, 0.0, -1.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0],
                       [0.0, 1.0, 0.0]])
    trilist = np.array([[0, 1, 3], [1, 2, 3]])
    # 0 and 2 are the corner of the triangles and so the maintain the
    # face normals. The other two are the re-normalised vertices:
    # normalise(n0 + n2)
    expected_normals = np.array(
        [[-np.sqrt(3) / 3, -np.sqrt(3) / 3,
          np.sqrt(3) / 3], [-0.32505758, -0.32505758, 0.88807383], [0, 0, 1],
         [-0.32505758, -0.32505758, 0.88807383]])
    trimesh = TriMesh(points, trilist)
    vertex_normals = trimesh.vertex_normals()
    assert_allclose(vertex_normals, expected_normals)
예제 #29
0
파일: labels.py 프로젝트: yymath/menpo
def ibug_close_eye_trimesh(landmark_group):
    """
    Apply the ibug's "standard" close eye semantic labels to the
    landmarks in the given landmark group.

    The group label will be 'ibug_close_eye_trimesh'.

    The semantic labels applied are as follows:

      - tri

    Parameters
    ----------
    landmark_group : :map:`LandmarkGroup`
        The landmark group to apply semantic labels to.

    Returns
    -------
    group_label : `str`
        The group label: 'ibug_close_eye_trimesh'
    landmark_group : :map:`LandmarkGroup`
        New landmark group.

    Raises
    ------
    :class:`menpo.landmark.exceptions.LabellingError`
        If the given landmark group contains less than 38 points
    """
    from menpo.shape import TriMesh

    group_label = 'ibug_close_eye_trimesh'
    n_expected_points = 17
    n_points = landmark_group.lms.n_points

    _validate_input(landmark_group, n_expected_points, group_label)

    tri_list = np.array([[10, 11, 13], [ 3, 13,  2], [ 4, 14,  3],
                         [15,  5, 16], [12, 11,  0], [13, 14, 10],
                         [13, 12,  2], [14, 13,  3], [ 0,  1, 12],
                         [ 2, 12,  1], [13, 11, 12], [ 9, 10, 14],
                         [15,  9, 14], [ 7,  8, 15], [ 5,  6, 16],
                         [15, 14,  4], [ 7, 15, 16], [ 8,  9, 15],
                         [15,  4,  5], [16,  6,  7]])

    new_landmark_group = LandmarkGroup(
        TriMesh(landmark_group.lms.points, tri_list, copy=False),
        OrderedDict([('tri', np.ones(n_points, dtype=np.bool))]))

    return group_label, new_landmark_group
예제 #30
0
def FastNICP(sources, target):
    aligned = []
    corrs = []
    for source in sources:
        pts, _ = icp(source.points, target.points)
        mesh = TriMesh(pts)
        try:
            a_s, corr = nicp(mesh, target, us=2001, ls=1, step=100)
        except:
            print('Failed Fast NICP')
            nicp_result = SNICP([PointCloud(pts)], target)
            corr = nicp_result.point_correspondence[0]
            a_s = nicp_result.aligned_shapes[0]
        aligned.append(a_s)
        corrs.append(corr)
    return aligned, corrs