Esempio n. 1
0
    def load_model(self, path_data):
        self.filename, self.file_extension = os.path.splitext(path_data)

        if os.path.exists(self.filename + ".png"):
            self.bgImage = self.filename + ".png"

        if self.file_extension == ".mat":
            file = h5py.File(path_data, 'r')
            try:
                self.set_points(np.transpose(np.array(file["avgModel"])))
                self.set_landmarks(np.transpose(np.array(file["landmarks3D"])))
            except Exception as ex:
                print("File is not compatible:" + ex)

        if self.file_extension == ".wrl":
            self.set_points(file3D.load_wrml(path_data))
            self.set_landmarks(file3D.load_bnd(self.filename + ".bnd"))
            if self.bgImage is not None and os.path.exists(self.bgImage):
                self.bgImage = self.filename[:-3] + "F2D.png"

        if self.file_extension == ".off":
            self.set_points(file3D.load_off(path_data))

        row = "Model loaded: " + str(self.points.shape[0]) + " points"

        if self.landmarks is not None:
            row += " and " + str(self.landmarks.shape[0]) + " landmarks."

        self.init_registration_points()
        Logger.addRow(row)
    def save_h5py(self, filename):
        def encode_ss_utf_8(ss):
            return np.void(ss.encode('utf-8'))

        # self = self.source_model.compute_displacement_map(self.target_model, 3)
        file = None
        try:
            file = h5py.File(filename, "w")
            file.create_dataset("points", data=self.points)
            file.create_dataset("missed_points", data=self.missed_points)
            file.attrs["points_color"] = encode_ss_utf_8(self.points_color)
            file.attrs["missed_points_color"] = encode_ss_utf_8(
                self.missed_points_color)
            if self.landmarks is not None:
                file.create_dataset("landmarks", data=self.landmarks)
                file.create_dataset("missed_landmarks",
                                    data=self.missed_landmarks)
                file.attrs["landmarks_color"] = encode_ss_utf_8(
                    self.landmarks_color)
                file.attrs["missed_landmarks_color"] = encode_ss_utf_8(
                    self.missed_landmarks_color)
        except Exception as ex:
            Logger.addRow("ERROR: Displacement map was not saved. =>" +
                          str(ex))
        finally:
            if file is not None:
                file.close()
                Logger.addRow(f'File {filename} saved correctly.')
 def write_on_file(self):
     with open('registration_parameters.conf', 'w+') as conf_file:
         conf = ConfigParser()
         conf['PARAMETERS'] = {}
         for key, value in self.params.items():
             conf['PARAMETERS'][str(key)] = str(value)
         conf.write(conf_file)
         Logger.addRow("Configuration file updated")
Esempio n. 4
0
 def __init__(self, source, target_list, percentage, final_callback):
     Thread.__init__(self)
     self.source_model = source
     self.target_list = target_list
     self.perc = percentage
     self.finalCallback = final_callback
     self.should_stop = False
     Logger.addRow("Starting Batch Thread..")
    def compute_map(cls, source_model, target_model, max_dist=2):
        """:param source_model
            :type source_model Model

            :param target_model
            :type target_model Model

            :param max_dist
            :type max_dist number
         """

        source_points = source_model.points
        target_points = target_model.points

        hit_landmarks = None
        missed_landmarks = None
        landmarks_color = None
        missed_landmarks_color = None

        # Points KDTree
        tree = cKDTree(source_points)
        _, indices = tree.query(target_points,
                                distance_upper_bound=max_dist,
                                n_jobs=multiprocessing.cpu_count())
        # Indices contains source's neighbors indices to target's points used for query
        indices = set(indices)
        indices.discard(source_points.shape[0])
        indices = list(indices)
        hit_points = source_points[indices]
        missed_points = np.delete(source_points, indices,
                                  axis=0)  # Points without a feasible neighbor
        missed_color = "y"
        points_color = "b"
        # LandmarksKDTree
        if source_model.landmarks is not None and target_model.landmarks is not None:
            tree = cKDTree(source_model.landmarks)
            _, indices = tree.query(target_model.landmarks,
                                    distance_upper_bound=max_dist,
                                    n_jobs=multiprocessing.cpu_count())
            indices = set(indices)
            indices.discard(source_model.landmarks.shape[0])
            indices = list(indices)
            hit_landmarks = source_model.landmarks[indices]
            missed_landmarks = np.delete(source_model.landmarks,
                                         indices,
                                         axis=0)
            landmarks_color = "r"
            missed_landmarks_color = "p"

        Logger.addRow("Displacement map created.")
        return cls(points=hit_points,
                   landmarks=hit_landmarks,
                   points_color=points_color,
                   landmarks_color=landmarks_color,
                   missed_points=missed_points,
                   missed_landmarks=missed_landmarks,
                   missed_points_color=missed_color,
                   missed_landmarks_color=missed_landmarks_color)
Esempio n. 6
0
    def run(self):
        source = self.source_model.get_registration_points()

        try:
            for targ in self.target_list:
                Logger.addRow(
                    "Batch %d of %d:" %
                    (self.target_list.index(targ) + 1, len(self.target_list)))
                path_wrl = targ[0:len(targ) - 3] + "bnd"
                t = Model(targ, path_wrl)
                target = Model.decimate(t.points, self.perc)
                Logger.addRow("Points decimated.")
                if t.landmarks is not None:
                    target = np.concatenate((target, t.landmarks), axis=0)
                reg = rigid_registration(**{'X': source, 'Y': target})
                meth = "CPD Rigid"

                Logger.addRow("Starting registration with " + meth +
                              ", using " + str(self.perc) + "% of points.")
                model = Model()

                reg_time = time.time()

                # Se si vuole visualizzare i progressi usare questa versione
                # data, reg_param = reg.register(partial(self.drawCallback, ax=None))
                data, reg_param = reg.register(partial(self.log, ax=None))

                model.set_points(
                    reg.transform_point_cloud(self.source_model.model_data))

                model.registration_params = reg_param
                if t.landmarks is not None:
                    model.set_landmarks(
                        data[target.shape[0] -
                             t.landmarks.shape[0]:data.shape[0]])
                model.filename = t.filename
                # model.centerData()
                model.compute_displacement_map(target, 3)
                now = datetime.datetime.now()
                save_filename = "RIGID_REG_{0}_{1}_{2}_{3}_{4}.mat"
                save_path = os.path.join(
                    "results",
                    save_filename.format(now.day, now.month, now.year,
                                         now.hour, now.minute))
                model.save_model(save_path)
                model.shoot_displacement_map(save_path)
                Logger.addRow("Took " + str(round(time.time() - reg_time, 3)) +
                              "s.")

        except Exception as ex:
            Logger.addRow(str(ex))
            print(ex)
        finally:
            self.finalCallback()
Esempio n. 7
0
    def save_model(self, filename):
        model = {"model_data": self.points}

        if self.landmarks is not None:
            model["landmarks3D"] = self.landmarks
        if self.displacement_map is not None:
            model["displacement_map"] = self.displacement_map
        if self.registration_params is not None:
            for i in range(len(self.registration_params)):
                model[str("reg_param" + str(i))] = self.registration_params[i]

        file3D.save_file(filename, model)
        Logger.addRow(str("File saved: " + filename))
    def load_model(cls, filename):
        try:
            file = h5py.File(filename, 'r')
            points = file.get("points").value
            missed_points = file.get("missed_points").value
            points_color = (
                file.attrs["points_color"]).tostring().decode('utf-8')
            missed_points_color = (
                file.attrs["missed_points_color"]).tostring().decode('utf-8')

            # If landmarks are not present a KeyError is raised
            landmarks = file.get("landmarks").value
            missed_landmarks = file.get("missed_landmarks").value
            landmarks_color = (
                file.attrs["landmarks_color"]).tostring().decode('utf-8')
            missed_landmarks_color = (file.attrs["missed_landmarks_color"]
                                      ).tostring().decode('utf-8')

        except AttributeError:
            Logger.addRow("INFO: Displacement model has no landmarks.")
            landmarks = None
            landmarks_color = None
            missed_landmarks = None
            missed_landmarks_color = None
        except FileNotFoundError:
            Logger.addRow(f"ERROR: {filename} not found, check path.")

        except Exception as ex:
            Logger.addRow(f"ERROR: Problem during opening of {filename} =>" +
                          str(ex))

        finally:
            displacement_model = cls(
                points=points,
                landmarks=landmarks,
                missed_points=missed_points,
                missed_landmarks=missed_landmarks,
                points_color=points_color,
                landmarks_color=landmarks_color,
                missed_points_color=missed_points_color,
                missed_landmarks_color=missed_landmarks_color)

        Logger.addRow(f'File {filename} load correctly.')
        return displacement_model
    def run(self):
        source = self.source_model.get_registration_points()
        target = Model.decimate(self.target_model.points, self.percentage)
        Logger.addRow("Points decimated.")
        if self.target_model.landmarks is not None:
            target = np.concatenate((target, self.target_model.landmarks),
                                    axis=0)
        Logger.addRow("Landmarks added.")

        ps = RegistrationParameters().get_params()

        if self.method == 1:  # CPD - RIGID
            self.registration_method = rigid_registration(
                **{
                    'X': target,
                    'Y': source,
                    'sigma2': ps['sigma2'],
                    'max_iterations': ps['max_iterations'],
                    'tolerance': ps['tolerance'],
                    'w': ps['w']
                })
            method = "CPD Rigid"
        if self.method == 2:  # CPD - AFFINE
            self.registration_method = affine_registration(
                **{
                    'X': target,
                    'Y': source,
                    'sigma2': ps['sigma2'],
                    'max_iterations': ps['max_iterations'],
                    'tolerance': ps['tolerance'],
                    'w': ps['w']
                })
            method = "CPD Affine"
        if self.method == 3:  # CPD - DEFORMABLE
            self.registration_method = deformable_registration(
                **{
                    'X': target,
                    'Y': source,
                    'sigma2': ps['sigma2'],
                    'max_iterations': ps['max_iterations'],
                    'tolerance': ps['tolerance'],
                    'w': ps['w']
                })
            method = "CPD Deformable"

        Logger.addRow("Starting registration with " + method + ", using " +
                      str(self.percentage) + "% of points.")
        model = Model()
        reg_time = time.time()

        try:
            self.registration_method.register(
                partial(self.interruptable_wrapper, ax=None))
            model = self.aligned_model(model)
        except InterruptedException as ex:
            Logger.addRow(str(ex))
            model = self.aligned_model(model)
        except Exception as ex:
            Logger.addRow("Err: " + str(ex))
            model = self.target_model  # Fail: back with the original target model
        finally:
            Logger.addRow("Took " + str(round(time.time() - reg_time, 3)) +
                          "s.")
            self.callback(model)
 def log(self, iteration, error):
     row = "Iteration #" + str(iteration) + " error: " + str(error)
     Logger.addRow(row)
Esempio n. 11
0
def load_off(file, faces_required=False):
    """
    Reads vertices and faces from an off file.

    :param file: path to file to read
    :type file: str
    :param faces_required: True if the function should return faces also
    :type: bool
    :return: vertices and faces as lists of tuples
    :rtype: [(float)], [(int)]
    """

    assert os.path.exists(file)

    with open(file, 'r') as fp:
        lines = fp.readlines()
        lines = [line.strip() for line in lines]

        assert (lines[0] == 'OFF'), "Invalid preambole"

        parts = lines[1].split(' ')
        assert (
            len(parts) == 3
        ), "Need exactly 3 parameters on 2nd line (n_vertices, n_faces, n_edges)."

        num_vertices = int(parts[0])
        assert num_vertices > 0

        num_faces = int(parts[1])
        if faces_required:
            assert num_faces > 0

        vertices = []
        for i in range(num_vertices):
            vertex = lines[2 + i].split(' ')
            vertex = [float(point) for point in vertex]
            assert (len(vertex) == 3), str("Invalid vertex row on line " +
                                           str(i))

            vertices.append(vertex)

        if num_vertices > len(vertices):
            row = "WARNING: some vertices were not loaded correctly: {0} declared vs {1} loaded."
            Logger.addRow(row.format(num_vertices, len(vertices)))

        vertices = np.asarray(vertices)

        if faces_required:
            faces = []
            for i in range(num_faces):
                face = lines[2 + num_vertices + i].split(' ')
                face = [int(index) for index in face]

                assert face[0] == len(face) - 1
                for index in face:
                    assert 0 <= index < num_vertices

                assert len(face) > 1

                faces.append(face)
            return vertices, faces

        return vertices
Esempio n. 12
0
 def __init__(self):
     super().__init__()
     self.setWindowIcon(QIcon('resources/icon.png'))
     Logger()
     self.statusLabel = QLabel("")
     self.initUI()
Esempio n. 13
0
 def log(self, iteration, error, X, Y, ax):
     sss = "Iteration #" + str(iteration) + " error: " + str(error)
     Logger.addRow(sss)
     if self.should_stop:
         raise Exception("Registration has been stopped")