Beispiel #1
0
    def __init__(
        self,
        X,
        T,
        V=None,
        cache=True,
    ):
        from sdot.core.common import is_2d
        assert is_2d(
            X
        ), "This class can only be used for measures supported on 2D domains"

        self.vertices = X
        self.triangles = T
        if V is not None:
            if isinstance(V, np.ndarray):
                # TODO
                raise NotImplementedError
            else:
                assert callable(V)
                self.values_func = V
        else:
            self.values_func = lambda x: 1.0

        self.cache = cache
        if self.cache:
            self.res = {}

        super().__init__(self.vertices, self.triangles, self.values_func)
Beispiel #2
0
def plot_empty_cells(mu, Y, ind, title=""):
    fig = plt.figure()

    if is_2d(Y):
        plot_2d_cloud(Y[ind], fig=fig)
        plot_2d_tri(mu.vertices, mu.triangles, fig=fig, c="r")
    else:
        plot_cloud(Y[ind])
        plot_tri(mu.vertices, mu.triangles, fig=fig, c="r")

    plt.title("{} empty cells{}".format(len(ind), title))
Beispiel #3
0
    def centroids(self, Y, psi=None):
        from sdot.core.common import is_2d
        assert is_2d(
            Y
        ), "This class can only be used for measures supported on 2D domains"

        if psi is None:
            psi = np.zeros(len(Y))

        C = super().centroids(Y, psi)

        if self.cache:
            self.res["C"] = C

        return C
Beispiel #4
0
    def kantorovich(self, Y, nu, psi=None):
        from sdot.core.common import is_2d
        assert is_2d(
            Y
        ), "This class can only be used for measures supported on 2D domains"

        if psi is None:
            psi = np.zeros(len(Y))

        A, DA = super().kantorovich(Y, nu, psi)

        if self.cache:
            self.res = {"A": A, "DA": DA}

        return A, DA
Beispiel #5
0
    def optimal_transport(self,
                          Y,
                          nu,
                          psi0=None,
                          eps=1e-8,
                          verbose=False,
                          maxit=100):
        from sdot.core.common import is_2d
        assert is_2d(
            Y
        ), "This class can only be used for measures supported on 2D domains"

        if psi0 is None:
            psi0 = np.zeros(len(Y))

        psi = super().optimal_transport(Y, nu, psi0, eps, verbose, maxit)

        return psi
Beispiel #6
0
    def plot(self, fig=None, as_img=False, colorbar=False):
        import matplotlib.pyplot as plt
        fig = fig or plt.figure()

        if as_img:
            # Only work with square densities
            root = math.sqrt(self.values.size)
            assert int(root + 0.5) ** 2 == self.values.size, "Plot as image only works with square densities"
            n = int(root)

            img = self.values.reshape(n, n)
            plt.imshow(img, interpolation="none")
        else:
            from sdot.core.common import plot_2d_tri_func, plot_2d_cloud, plot_tri, plot_cloud, is_2d

            if is_2d(self.vertices):
                plot_2d_cloud(self.vertices, cmap=self.values, colorbar=colorbar, fig=fig)
                # plot_2d_tri_func(self.vertices, self.triangles, self.values, fig=fig)
            else:
                plot_cloud(self.vertices, cmap=self.values, colorbar=colorbar, fig=fig)
Beispiel #7
0
        # Default perturbation parameters : translation, rotation and noise
        noise_intensity = 0.5 * M
        vprint("Noise intensity = {}".format(noise_intensity))
        cloud = add_noise(cloud, noise_intensity) # noise
        cloud += 1.0 * np.array([0, 0, 1]) # translation
        cloud = transform_3d_cloud(rotation_matrix_homogeneous([0, 1, 0], math.pi / 2),
                                   cloud) # rotation

        vprint("Saving initial point cloud to results/icp/initial_{}.xyz".format(target_mesh_basename))
        np.savetxt("results/icp/initial_{}.xyz".format(target_mesh_basename), cloud)
    elif source_ext in [".xyz", ".txt", ".cloud"]:
        assert os.path.isfile(source_filename), "{} does not exist".format(source_filename)
        cloud = np.loadtxt(source_filename)

        if is_2d(cloud):
            z = np.repeat(0, len(cloud))
            cloud = np.hstack((cloud, z.reshape(-1, 1)))
    elif source_ext in [".off", ".noff", ".coff"]:
        X, T = io.read_off(source_filename, ignore_prefix=True)
        cloud, _ = random_in_triangulation(X, T, N)
    else:
        raise RuntimeError("Format {} not supported".format(source_ext[1:]))

    vprint("ICP between {} and {}\n".format(off_file, source_filename))

    fig = plt.figure()
    ax = fig.gca(projection="3d")
    plot_tri(mesh.vertices, mesh.faces, fig=fig)
    plot_cloud(cloud, fig=fig)
    # plt.show()
Beispiel #8
0
    mu_flat /= mu_flat.sum()
    nu_flat /= nu_flat.sum()

    fig = plt.figure()
    if len(sys.argv) == 1:
        ax = fig.add_subplot("111", projection="3d")
        ax.plot_surface(X_mu, Y_mu, mu, color="r")
        ax.plot_surface(X_nu, Y_nu, nu, color="b")

        # import matplotlib as mpl
        # legend1 = mpl.lines.Line2D([0],[0], linestyle="none", c='b', marker='o')
        # legend2 = mpl.lines.Line2D([0],[0], linestyle="none", c='r', marker='o')
        # ax.legend([legend1, legend2], ["Source", 'Target'], numpoints = 1)
    elif len(sys.argv) in [3, 4]:
        if is_2d(P_mu):
            plot_2d_cloud(P_mu, fig=fig, cmap="r", labels=["source"])
            plot_2d_cloud(P_nu, fig=fig, cmap="b", labels=["target"])
        else:
            plot_cloud(P_mu, fig=fig, cmap="r", labels=["source"])
            plot_cloud(P_nu, fig=fig, cmap="b", labels=["target"])
    ax = plt.gca()
    ax.set_aspect("equal")
    # plt.legend()
    # plt.show()

    # plt.imshow(M)
    # plt.show()

    # Normal
    if discrete_init["normal"]:
Beispiel #9
0
psi = optimal_transport_3(mu,
                          Y,
                          nu_Y,
                          psi0=psi0,
                          eps=eps,
                          method="newton",
                          maxit=maxit)
end_ot = time.time()
print("Running time = {}s".format(end_ot - start_ot))

# Results
# We can export the Laguerre cells for (Y, psi) as a mesh '/tmp/final_laguerre.obj' that can be opened
# with Meshlab for instance
mu.export_laguerre_cells(Y, psi=psi, basename="/tmp/final_laguerre")

# Now, we plot the dual triangulation (C, T) where C are the centroids of the Laguerre cells
C, T = mu.res["C"], mu.res["T"]
T = clean_triangulation(C, T)

# conforming_centroids_* means that we project the centroids on the boundary
# of the triangulated surface
if is_2d(X):
    from sdot.core.optimal_transport_3 import conforming_centroids_2
    conforming_C = conforming_centroids_2(mu, C, Y, psi)
    plot_2d_tri(conforming_C, T)
else:
    from sdot.optimal_transport import conforming_centroids_3
    conforming_C = conforming_centroids_3(mu, C, Y, psi)
    plot_tri(conforming_C, T)
plt.show()
Beispiel #10
0
nu = lambda y: 1.0
## Non-uniform
# def linear_target(x, a, b, m, M):
#     alpha = (b - a) / (M - m)
#     beta = a - alpha * m
#     return alpha * x + beta
# axis = 0
# m, M = np.min(Y[:, axis]), np.max(Y[:, axis])
# # min_nu = 0.1 # fandisk 1k
# min_nu = 0.3 # torus 1k
# nu = lambda y: linear_target(y[axis], min_nu, 1, m, M)

nu = np.apply_along_axis(nu, 1, Y)

fig = plt.figure()
if is_2d(X):
    ax = plt.gca()
    ax.set_aspect("equal")
    plot_2d_cloud(Y, fig=fig, cmap="b", s=10, labels=["target"])
    # plot_2d_hull(X[:, 0:2], fig=fig, c="r")
    plot_2d_tri(X, T_X, fig=fig, c="r", label="source")
else:
    ax = plt.gca(projection="3d")
    plot_cloud(Y, ax=ax, fig=fig, cmap="b",labels=["target"], s=15)
    plot_tri(X, T_X, fig=fig, color="r", label="source")
# plt.legend()
plt.show() # TODO

## Local
if tests_init["local"]:
    start_local = time.time()