예제 #1
0
 def __getitem__(self, index):
     path = self.paths[index]
     mesh = Mesh(file=path,
                 opt=self.opt,
                 hold_history=True,
                 export_folder=self.opt.export_folder)
     meta = {}
     meta['mesh'] = mesh
     if self.opt.edge_split:
         path_index = os.path.join(
             os.path.dirname(self.seg_paths[index]),
             'cache\\' + os.path.basename(self.seg_paths[index]))
         label = read_seg(path_index) - self.offset
     else:
         label = read_seg(self.seg_paths[index]) - self.offset
     label = pad(label, self.opt.ninput_edges, val=-1, dim=0)
     meta['label'] = label
     if self.opt.edge_split:
         path_index = os.path.join(
             os.path.dirname(self.sseg_paths[index]),
             'cache\\' + os.path.basename(self.sseg_paths[index]))
         soft_label = read_sseg(path_index)
     else:
         soft_label = read_sseg(self.sseg_paths[index])
     meta['soft_label'] = pad(soft_label,
                              self.opt.ninput_edges,
                              val=-1,
                              dim=0)
     # get edge features
     edge_features = mesh.extract_features()
     edge_features = pad(edge_features, self.opt.ninput_edges)
     meta['edge_features'] = (edge_features - self.mean) / self.std
     return meta
예제 #2
0
 def __getitem__(self, index):
     path = self.paths[index][0]
     label = self.paths[index][1]
     mesh = Mesh(file=path, opt=self.opt, hold_history=False, export_folder=self.opt.export_folder)
     meta = {'mesh': mesh, 'label': label}
     # get edge features
     face_features = mesh.extract_features()
     face_features = pad(face_features, self.opt.ninput_faces)
     meta['face_features'] = (face_features - self.mean) / self.std
     return meta
예제 #3
0
 def __getitem__(self, index):
     path = self.paths[index]
     mesh = Mesh(file=path, opt=self.opt, hold_history=True, export_folder=self.opt.export_folder)
     meta = {}
     meta['mesh'] = mesh
     # get edge features
     face_features = mesh.extract_features()
     meta['num_triangle'] = mesh.faces_count
     face_features = pad(face_features, self.opt.ninput_faces)
     meta['face_features'] = (face_features - self.mean) / self.std
     return meta
예제 #4
0
def color_obj():
    """coloring mesh with the given seg file"""
    path = "E:/3ds_intern/meshcnn/datasets/coseg_aliens/labels_aliens/5.obj"
    path2 = "E:/3ds_intern/meshcnn/datasets/coseg_aliens/labels_aliens/5.eseg"
    opt = TestOptions().parse()
    mesh = Mesh(file=path,
                opt=opt,
                hold_history=False,
                export_folder=
                "E:/3ds_intern/meshcnn/datasets/coseg_aliens/labels_aliens")
    seg = read_seg(path2).astype(int)
    mesh.export_segments(seg)
예제 #5
0
 def __getitem__(self, index):
     path = self.paths[index]
     mesh = Mesh(file=path,
                 opt=self.opt,
                 hold_history=True,
                 export_folder=self.opt.export_folder)
     # get edge features
     edge_features = mesh.extract_features()
     edge_features = pad(edge_features, self.opt.ninput_edges)
     meta = {'mesh': mesh, 'label': edge_features}
     meta['edge_features'] = (edge_features - self.mean) / self.std
     return meta
예제 #6
0
 def __getitem__(self, index):
     path = self.paths[index]
     mesh = Mesh(file=path, opt=self.opt, hold_history=True, export_folder=self.opt.export_folder)
     meta = {}
     meta['mesh'] = mesh
     label = read_seg(self.seg_paths[index]) - self.offset
     label = pad(label, self.opt.ninput_edges, val=-1, dim=0)
     meta['label'] = label
     soft_label = read_sseg(self.sseg_paths[index])
     meta['soft_label'] = pad(soft_label, self.opt.ninput_edges, val=-1, dim=0)
     # get edge features
     edge_features = mesh.extract_features()
     edge_features = pad(edge_features, self.opt.ninput_edges)
     meta['edge_features'] = (edge_features - self.mean) / self.std
     return meta
예제 #7
0
 def __getitem__(self, index):
     path = self.paths[index][0]
     #print(path)
     mesh = Mesh(file=path,
                 opt=self.opt,
                 hold_history=True,
                 export_folder=self.opt.export_folder)
     meta = {}
     mesh.vs = (mesh.vs - np.mean(mesh.vs, 0)) / np.std(mesh.vs, 0)
     meta['mesh'] = mesh
     meta['export_folder'] = mesh.export_folder
     meta['filename'] = mesh.filename
     # get edge features
     edge_features = mesh.extract_features()
     edge_features = pad(edge_features, self.opt.ninput_edges)
     vs, pad_iter = pad_vertices(mesh.vs, 1402)
     meta['edge_features'] = (edge_features - self.mean) / self.std
     meta['label'] = vs.astype(np.float)
     meta['init_faces'] = mesh.init_faces
     meta['pad_iter'] = pad_iter
     return meta
예제 #8
0
    def __getitem__(self, index):
        path = self.paths[index]
        # print("opt: {}, export_folder: {}, phase: {}".format(self.opt, self.opt.export_folder,  self.opt.phase))
        mesh = Mesh(file=path,
                    opt=self.opt,
                    hold_history=True,
                    export_folder=self.opt.export_folder,
                    phase=self.opt.phase)
        meta = {}
        meta["filename"] = mesh.filename
        meta['mesh'] = mesh
        if self.opt.phase != "test":
            label = read_seg(self.seg_paths[index]) - self.offset
            # print("label: ", label.shape, type(label), label)
            # if len(label) > self.opt.ninput_edges:
            #     label = label[mesh.e_masks]
            if len(label) <= self.opt.ninput_edges:
                label = pad(label, self.opt.ninput_edges, val=-1, dim=0)
            meta['label'] = label
            soft_label = read_sseg(self.sseg_paths[index])
            # if len(soft_label) > self.opt.ninput_edges:
            #     soft_label = soft_label[mesh.e_masks]
            if len(soft_label) <= self.opt.ninput_edges:
                soft_label = pad(soft_label,
                                 self.opt.ninput_edges,
                                 val=-1,
                                 dim=0)
            meta['soft_label'] = soft_label

            # get edge features
        edge_features = mesh.extract_features()
        if edge_features.shape[1] <= self.opt.ninput_edges:
            edge_features = pad(edge_features, self.opt.ninput_edges)
            meta['edge_features'] = (edge_features - self.mean) / self.std
        else:
            meta["edge_features"] = np.array([])

        # print("edge_features: ", type(meta["edge_features"]), meta["edge_features"].shape)

        return meta
예제 #9
0
import utils
import numpy as np
from models.losses import chamfer_distance
from options import Options
import time
import os

options = Options()
opts = options.args

torch.manual_seed(opts.torch_seed)
device = torch.device('cuda:{}'.format(opts.gpu) if torch.cuda.is_available() else torch.device('cpu'))
print('device: {}'.format(device))

# initial mesh
mesh = Mesh(opts.initial_mesh, device=device, hold_history=True)

# input point cloud
input_xyz, input_normals = utils.read_pts(opts.input_pc)
# normalize point cloud based on initial mesh
input_xyz /= mesh.scale
input_xyz += mesh.translations[None, :]
input_xyz = torch.Tensor(input_xyz).type(options.dtype()).to(device)[None, :, :]
input_normals = torch.Tensor(input_normals).type(options.dtype()).to(device)[None, :, :]

part_mesh = PartMesh(mesh, num_parts=options.get_num_parts(len(mesh.faces)), bfs_depth=opts.overlap)
print(f'number of parts {part_mesh.n_submeshes}')
net, optimizer, rand_verts, scheduler = init_net(mesh, part_mesh, device, opts)

for i in range(opts.iterations):
    num_samples = options.get_num_samples(i % opts.upsamp)
예제 #10
0
    polydata = reader.GetOutput()

    #Network parameter
    down_convs = [5, 32, 64, 128, 256]
    up_convs = [256, 128, 64, 32, 8]
    pool_res = [2250, 1800, 1350, 600]
    resblocks = 3
    net = MeshEncoderDecoder(pool_res, down_convs, up_convs, resblocks)

    #Try to get pretrained mesh
    state_dict = torch.load('./data/latest_net.pth')
    net.load_state_dict(state_dict)
    net.eval()

    #Import sample mesh
    mesh = Mesh(polydata)
    mesh_feature = mesh.extract_features()

    # mesh_gemm = mesh.extract_gemm_edges()
    # print(mesh_gemm.shape)

    sample_input = torch.tensor(mesh_feature).unsqueeze(0).float()
    print(sample_input.size())
    y = net.forward(sample_input, [mesh])
    y_value, y_index = y.max(-2)

    #Get Predicted Class
    predict = y_index[0]
    print(predict.size())

    #Visualize
예제 #11
0
    def __init__(self,
                 mesh_original_filename,
                 mesh_filename,
                 num_classes,
                 edge_soft_labels_file,
                 print_warnings=False):
        self.__print_warnings = print_warnings
        # Allow to call recursive function the needed number of times.
        sys.setrecursionlimit(5000)
        self.__num_classes = num_classes
        # Read the mesh data.
        # Read mesh.
        opt = OptClass()
        mesh_pymesh = pymesh.load_mesh(mesh_filename)
        for color in ['green', 'red', 'blue']:
            if (not mesh_pymesh.has_attribute(f'face_{color}')):
                mesh_pymesh.add_attribute(f'face_{color}')
                mesh_pymesh.set_attribute(
                    f'face_{color}',
                    mesh_pymesh.get_attribute(f'vertex_{color}'))
                mesh_pymesh.remove_attribute(f'vertex_{color}')
        face_labels = np.empty(mesh_pymesh.num_faces, dtype=np.long)
        face_red = mesh_pymesh.get_attribute('face_red')
        face_green = mesh_pymesh.get_attribute('face_green')
        face_blue = mesh_pymesh.get_attribute('face_blue')
        for face_idx, (blue, green,
                       red) in enumerate(zip(face_blue, face_green, face_red)):

            assigned_label = False
            for label_idx in range(len(seg_colors)):
                if (np.all([blue, green, red] == seg_colors[label_idx])):
                    face_labels[face_idx] = label_idx
                    assigned_label = True

            assert (assigned_label), [blue, green, red]
        mesh = Mesh(file=mesh_original_filename, opt=opt, hold_history=False)
        # Map vertices in MeshCNN to pymesh vertices.
        meshcnn_vertex_idx_to_pymesh_vertex_idx = np.empty(
            [mesh_pymesh.num_vertices])
        pymesh_vertex_to_assign = [r for r in range(mesh_pymesh.num_vertices)]
        for meshcnn_vertex_idx, meshcnn_vertex in enumerate(mesh.vs):
            found_match = None
            for pymesh_vertex_idx in pymesh_vertex_to_assign:
                pymesh_vertex = mesh_pymesh.vertices[pymesh_vertex_idx]
                if (np.isclose(meshcnn_vertex[0], pymesh_vertex[0])
                        and np.isclose(meshcnn_vertex[1], pymesh_vertex[1])
                        and np.isclose(meshcnn_vertex[2], pymesh_vertex[2])):
                    found_match = pymesh_vertex_idx
                    pymesh_vertex_to_assign.remove(pymesh_vertex_idx)
                    meshcnn_vertex_idx_to_pymesh_vertex_idx[
                        meshcnn_vertex_idx] = pymesh_vertex_idx
                    break
            assert (found_match is not None)

        face_vertex_indices = mesh_pymesh.get_attribute(
            'face_vertex_indices').astype(np.long).reshape(-1, 3)
        vertex_to_faces = {
            vertex: []
            for vertex in range(mesh_pymesh.num_vertices)
        }
        for face_idx, vertices_in_face in enumerate(face_vertex_indices):
            for pymesh_vertex_idx in vertices_in_face:
                meshcnn_vertex_idx = meshcnn_vertex_idx_to_pymesh_vertex_idx[
                    pymesh_vertex_idx]
                vertex_to_faces[meshcnn_vertex_idx].append(face_idx)

        # Read vertices.
        self.__vertices = mesh.vs
        self.__num_vertices = self.__vertices.shape[0]
        assert (self.__num_vertices == mesh_pymesh.num_vertices
                ), f"{self.__num_vertices}, {mesh_pymesh.num_vertices}"
        # Edges.
        if (hasattr(mesh, 'original_edges')):
            self.__edges = np.array(mesh.original_edges).squeeze()
        else:
            self.__edges = mesh.edges
        self.__num_edges = self.__edges.shape[0]

        self.__halfedge_to_halfedge_idx = {}
        for halfedge_idx, halfedge in enumerate(self.__edges):
            self.__halfedge_to_halfedge_idx[(halfedge[0],
                                             halfedge[1])] = halfedge_idx

        assert (num_classes in [3, 4, 8])
        edge_soft_labels = np.zeros([self.__num_edges, num_classes])

        # For each (half)-edge, see the face to which the edge belongs and form
        # edge soft-labels from the hard labels of these faces.
        for halfedge_idx, halfedge in enumerate(self.__edges):
            vertex_1, vertex_2 = halfedge
            faces_halfedge = list(
                set(vertex_to_faces[vertex_1])
                & set(vertex_to_faces[vertex_2]))
            assert (len(faces_halfedge) in [1, 2])
            for face_idx in faces_halfedge:
                # Get face label.
                face_lab = face_labels[face_idx]
                # Update edge soft label.
                edge_soft_labels[halfedge_idx, face_lab] += 0.5

        # Create the output folder if non-existent.
        output_folder = os.path.dirname(edge_soft_labels_file)
        if (not os.path.exists(output_folder)):
            os.makedirs(output_folder)

        # Save soft label to file.
        np.savetxt(edge_soft_labels_file, edge_soft_labels, fmt="%.6f")
예제 #12
0
def run_test(dataset_name, meshcnn_root, soft_labels_folder, verbose):
    opt = Opt(dataset_name)

    # Initialize counter.
    accuracy_counter = PdMeshNetAccuracyCounter()
    accuracy_counter.reset_counter()

    folder_original_meshes = os.path.join(meshcnn_root,
                                          f'datasets/{dataset_name}/test/')

    mesh_filenames = glob.glob(os.path.join(folder_original_meshes, '*.obj'))
    for mesh_filename in mesh_filenames:
        # Load original mesh.
        mesh = Mesh(file=mesh_filename, opt=opt, hold_history=False)
        mesh_name = mesh_filename.rsplit('.')[0].rpartition('/')[-1]
        mesh_name = f'{mesh_name}_aug_0_clusterized'
        if (verbose):
            print(f"Original mesh filename = '{mesh_filename}'.")
        # Load predicted soft labels.
        pred_soft_labels_file = os.path.join(
            soft_labels_folder, f'{dataset_name}/sseg/{mesh_name}.seseg')
        predicted_soft_labels = np.loadtxt(open(pred_soft_labels_file, 'r'),
                                           dtype='float64')
        num_edges = len(predicted_soft_labels)
        # Pad with zero the last class of coseg `chairs` (MeshCNN provides an
        # empty column for the 4th class, although the classes are 3).
        predicted_soft_labels_new = np.zeros([num_edges, opt.nclasses])
        predicted_soft_labels_new[:, :predicted_soft_labels.
                                  shape[1]] = predicted_soft_labels
        predicted_soft_labels = predicted_soft_labels_new

        assert (mesh.edges_count == num_edges)
        assert (predicted_soft_labels.ndim == 2 and
                predicted_soft_labels.shape[1] == opt.nclasses)
        num_predictions = predicted_soft_labels.shape[0]
        # Create two versions (cf. Supplementary Material `.pdf`), in each of
        # which one of the two predicted soft labels of each edge is considered
        # as 'hard label'.
        predicted_versions = np.empty([num_predictions, 2], dtype=np.long)
        for prediction_idx, prediction in enumerate(predicted_soft_labels):
            nonzero_pred = [b.item() for b in np.argwhere(prediction > 0)]
            assert (len(nonzero_pred) in [1, 2])
            if (len(nonzero_pred) == 1):
                nonzero_pred = 2 * nonzero_pred
            predicted_versions[prediction_idx] = nonzero_pred

        short_mesh_name = mesh_name.split('_aug')[0]
        # Load ground-truth softlabels.
        gt_soft_labels_file = os.path.join(
            meshcnn_root,
            f'datasets/{dataset_name}/sseg/{short_mesh_name}.seseg')
        gt_soft_labels = read_sseg(gt_soft_labels_file)
        # Load ground-truth hard labels.
        gt_hard_labels_file = os.path.join(
            meshcnn_root, f'datasets/{dataset_name}/seg/{short_mesh_name}.eseg')
        gt_hard_labels = read_seg(gt_hard_labels_file) - 1
        edge_labels = np.empty([num_edges], dtype=np.float)

        # Compute accuracy based on soft edge labels.
        correct = 0.5 * seg_accuracy(
            torch.from_numpy(predicted_versions[:, 0].reshape(1, -1)),
            torch.from_numpy(gt_soft_labels.reshape(
                1, -1, opt.nclasses)), [mesh]) + 0.5 * seg_accuracy(
                    torch.from_numpy(predicted_versions[:, 1].reshape(1, -1)),
                    torch.from_numpy(gt_soft_labels.reshape(
                        1, -1, opt.nclasses)), [mesh])
        # Compute accuracy based on hard edge labels.
        correct_hard = 0.5 * ((
            np.nonzero(predicted_versions[:, 0] == gt_hard_labels)[0].shape[0] +
            np.nonzero(predicted_versions[:, 1] == gt_hard_labels)[0].shape[0])
                             ) / num_edges
        if (verbose):
            print(
                "\tThe percentage of the mesh that was correct labelled "
                f"according to ground-truth soft labels is {correct * 100:.4}%."
            )
            print("\tThe percentage of the mesh that was correct labelled "
                  "according to ground-truth hard labels is "
                  f"{correct_hard * 100:.4}%.")
        accuracy_counter.update_counter(ncorrect=correct,
                                        ncorrect_hard=correct_hard,
                                        nexamples=1)
    accuracy_counter.print_acc(accuracy_counter.acc, accuracy_counter.acc_hard)