Ejemplo n.º 1
0
    def _runImp(self):
        normal_data = loadNormal(self._data_file)

        if normal_data is None:
            return

        N0_32F, A_8U = normal_data

        #N0_32F = cv2.resize(N0_32F, (64, 64))
        #A_8U = cv2.resize(A_8U, N0_32F.shape[:2])

        A_32F = to32F(A_8U)

        L = normalizeVector(np.array([-0.2, 0.3, 0.7]))

        # C0_32F = ToonShader().diffuseShading(L, N0_32F)
        C0_32F = LambertShader().diffuseShading(L, N0_32F)

        sfs_method = Wu08SFS(L, C0_32F, A_8U)
        sfs_method.run()
        N_32F = sfs_method.normal()

        saveNormal(self.resultFile(self._data_file_name, result_name="Wu08"), N_32F, A_8U)

        C_error = sfs_method.shadingError()
        I_32F = sfs_method.brightness()
        I_32F = gray2rgb(I_32F)
        C_32F = sfs_method.shading()

        N0_32F = trim(N0_32F, A_8U)
        C0_32F = trim(C0_32F, A_8U)
        C_32F = trim(C_32F, A_8U)
        N_32F = trim(N_32F, A_8U)
        C_error = trim(C_error, A_8U)
        I_32F = trim(I_32F, A_8U)
        A_32F = trim(A_32F, A_8U)
        A_8U = trim(A_8U, A_8U)

        h, w = N_32F.shape[:2]
        N_error = angleErros(N_32F.reshape(-1, 3), N0_32F.reshape(-1, 3)).reshape(h, w)
        N_error[A_8U < np.max(A_8U)] = 0.0

        fig, axes = plt.subplots(figsize=(11, 5))
        font_size = 15
        fig.subplots_adjust(left=0.05, right=0.95, top=0.9, hspace=0.12, wspace=0.05)
        fig.suptitle(self.name(), fontsize=font_size)

        num_rows = 2
        num_cols = 3
        plot_grid = SubplotGrid(num_rows, num_cols)

        plot_grid.showImage(normalToColor(N0_32F, A_8U), r'Ground Truth Normal: $N_g$')
        plot_grid.showImage(normalToColor(N_32F, A_8U), r'Estimated Normal: $N$')
        plot_grid.showColorMap(N_error, r'Angle Error: $N_g, N$', v_min=0, v_max=30.0)

        plot_grid.showImage(setAlpha(C0_32F, A_32F), r'Shading: $C$')
        plot_grid.showImage(setAlpha(C_32F, A_32F), r'Estimated Shading: $C$')
        plot_grid.showColorMap(C_error, r'Shading Error: $C_g, C$', v_min=0, v_max=0.1)

        showMaximize()
Ejemplo n.º 2
0
    def _runImp(self):
        normal_data = loadNormal(self._data_file)

        if normal_data is None:
            return

        N0_32F, A_8U = normal_data

        # N0_32F = cv2.resize(N0_32F, (64, 64))
        # A_8U = cv2.resize(A_8U, N0_32F.shape[:2])

        A_32F = to32F(A_8U)

        L = normalizeVector(np.array([-0.2, 0.3, 0.7]))

        # C0_32F = ToonShader().diffuseShading(L, N0_32F)
        C0_32F = LambertShader().diffuseShading(L, N0_32F)

        sfs_method = Wu08SFS(L, C0_32F, A_8U)
        sfs_method.run()
        N_32F = sfs_method.normal()

        saveNormal(self.resultFile(self._data_file_name, result_name="Wu08"), N_32F, A_8U)

        C_error = sfs_method.shadingError()
        I_32F = sfs_method.brightness()
        I_32F = gray2rgb(I_32F)
        C_32F = sfs_method.shading()

        N0_32F = trim(N0_32F, A_8U)
        C0_32F = trim(C0_32F, A_8U)
        C_32F = trim(C_32F, A_8U)
        N_32F = trim(N_32F, A_8U)
        C_error = trim(C_error, A_8U)
        I_32F = trim(I_32F, A_8U)
        A_32F = trim(A_32F, A_8U)
        A_8U = trim(A_8U, A_8U)

        h, w = N_32F.shape[:2]
        N_error = angleErros(N_32F.reshape(-1, 3), N0_32F.reshape(-1, 3)).reshape(h, w)
        N_error[A_8U < np.max(A_8U)] = 0.0

        fig, axes = plt.subplots(figsize=(11, 5))
        font_size = 15
        fig.subplots_adjust(left=0.05, right=0.95, top=0.9, hspace=0.12, wspace=0.05)
        fig.suptitle(self.name(), fontsize=font_size)

        num_rows = 2
        num_cols = 3
        plot_grid = SubplotGrid(num_rows, num_cols)

        plot_grid.showImage(normalToColor(N0_32F, A_8U), r"Ground Truth Normal: $N_g$")
        plot_grid.showImage(normalToColor(N_32F, A_8U), r"Estimated Normal: $N$")
        plot_grid.showColorMap(N_error, r"Angle Error: $N_g, N$", v_min=0, v_max=30.0)

        plot_grid.showImage(setAlpha(C0_32F, A_32F), r"Shading: $C$")
        plot_grid.showImage(setAlpha(C_32F, A_32F), r"Estimated Shading: $C$")
        plot_grid.showColorMap(C_error, r"Shading Error: $C_g, C$", v_min=0, v_max=0.1)

        showMaximize()
Ejemplo n.º 3
0
    def _runImp(self):
        # file_path = self._data_file
        file_path = self.resultFile(self._data_file_name, result_name="Wu08")
        normal_data = loadNormal(file_path)

        if normal_data is None:
            return

        N0_32F, A_8U = normal_data

        D_32F = depthFromNormal(N0_32F, A_8U)

        fig, axes = plt.subplots(figsize=(11, 5))

        font_size = 15

        fig.subplots_adjust(left=0.05,
                            right=0.95,
                            top=0.9,
                            hspace=0.05,
                            wspace=0.05)
        fig.suptitle("Depth From Normal", fontsize=font_size)

        plt.subplot(1, 4, 1)
        plt.title(r'Initial Normal: $N_0$')
        plt.imshow(normalToColor(N0_32F, A_8U))
        plt.axis('off')

        plt.subplot(1, 4, 2)
        plt.title(r'Estimated Depth: $D$')
        plt.gray()
        plt.imshow(D_32F)
        plt.axis('off')

        N_32F = depthToNormal(D_32F)
        plt.subplot(1, 4, 3)
        plt.title(r'Recovered Normal: $N$')
        plt.imshow(normalToColor(N_32F, A_8U))
        plt.axis('off')

        h, w = N_32F.shape[:2]
        N_diff = angleErros(N_32F.reshape(-1, 3),
                            N0_32F.reshape(-1, 3)).reshape(h, w)
        N_diff[A_8U < np.max(A_8U)] = 0.0
        plt.subplot(1, 4, 4)
        plt.title(r'Angle Error: $N, N_0$')
        plt.imshow(N_diff, cmap=plt.cm.jet, vmin=0, vmax=30.0)
        plt.axis('off')

        plt.colorbar()

        #out_file_path = self.resultFile(self._data_file_name)
        out_file_path = self.resultFile(self._data_file_name,
                                        result_name="Wu08Depth")
        plt.savefig(out_file_path)
Ejemplo n.º 4
0
    def _runImp(self):
        # file_path = self._data_file
        file_path = self.resultFile(self._data_file_name, result_name="Wu08")
        normal_data = loadNormal(file_path)

        if normal_data is None:
            return

        N0_32F, A_8U = normal_data

        D_32F = depthFromNormal(N0_32F, A_8U)

        fig, axes = plt.subplots(figsize=(11, 5))

        font_size = 15

        fig.subplots_adjust(left=0.05, right=0.95, top=0.9, hspace=0.05, wspace=0.05)
        fig.suptitle("Depth From Normal", fontsize=font_size)

        plt.subplot(1, 4, 1)
        plt.title(r'Initial Normal: $N_0$')
        plt.imshow(normalToColor(N0_32F, A_8U))
        plt.axis('off')

        plt.subplot(1, 4, 2)
        plt.title(r'Estimated Depth: $D$')
        plt.gray()
        plt.imshow(D_32F)
        plt.axis('off')

        N_32F = depthToNormal(D_32F)
        plt.subplot(1, 4, 3)
        plt.title(r'Recovered Normal: $N$')
        plt.imshow(normalToColor(N_32F, A_8U))
        plt.axis('off')

        h, w = N_32F.shape[:2]
        N_diff = angleErros(N_32F.reshape(-1, 3), N0_32F.reshape(-1, 3)).reshape(h, w)
        N_diff[A_8U < np.max(A_8U)] = 0.0
        plt.subplot(1, 4, 4)
        plt.title(r'Angle Error: $N, N_0$')
        plt.imshow(N_diff, cmap=plt.cm.jet, vmin=0, vmax=30.0)
        plt.axis('off')

        plt.colorbar()

        #out_file_path = self.resultFile(self._data_file_name)
        out_file_path = self.resultFile(self._data_file_name, result_name="Wu08Depth")
        plt.savefig(out_file_path)
def computeErrors(L, C0_32F, C_32F, Ng_32F, N_32F, A_8U):
    h, w = A_8U.shape
    N_error = angleErros(N_32F.reshape(-1, 3), Ng_32F.reshape(-1, 3)).reshape(h, w)
    N_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
    N_error = trim(N_error, A_8U)

    C_error = normVectors(C0_32F.reshape(-1, 3) - C_32F.reshape(-1, 3)).reshape(h, w)
    C_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
    C_error = trim(C_error, A_8U)

    I_32F = np.clip(LdotN(L, N_32F), 0.0, 1.0)
    Ig_32F = np.clip(LdotN(L, Ng_32F), 0.0, 1.0)
    I_error = np.abs(I_32F - Ig_32F)
    I_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
    I_error = trim(I_error, A_8U)
    return C_error, N_error, I_error
def computeLambertShadingError():
    shape_names = shapeNames()

    L = normalizeVector(np.array([-0.2, 0.3, 0.6]))

    C_errors = np.zeros(len(shape_names))
    N_errors = np.zeros(len(shape_names))

    for si, shape_name in enumerate(shape_names):
        Ng_data = shapeFile(shape_name)

        Ng_data = loadNormal(Ng_data)
        Ng_32F, A_8U = Ng_data

        N0_file = shapeResultFile(result_name="InitialNormal",
                                  data_name=shape_name)
        N0_data = loadNormal(N0_file)
        N0_32F, A_8U = N0_data

        C0_32F = LambertShader().diffuseShading(L, Ng_32F)

        sfs_method = ToonSFS(L, C0_32F, A_8U)
        sfs_method.setInitialNormal(N0_32F)
        sfs_method.setNumIterations(iterations=60)
        sfs_method.run()
        N_32F = sfs_method.normal()
        C_32F = sfs_method.shading()
        C_error = sfs_method.shadingError()
        C_error[A_8U < 0.5 * np.max(A_8U)] = 0.0

        C_errors[si] = np.average(C_error[A_8U > 0.5 * np.max(A_8U)])

        h, w = A_8U.shape[:2]
        N_error = angleErros(N_32F.reshape(-1, 3),
                             Ng_32F.reshape(-1, 3)).reshape(h, w)
        N_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        N_errors[si] = np.average(N_error[A_8U > 0.5 * np.max(A_8U)])

    file_path = shapeResultFile("ShapeEstimation",
                                "ShadingError",
                                file_ext=".npy")
    np.save(file_path, C_errors)

    file_path = shapeResultFile("ShapeEstimation",
                                "NormalError",
                                file_ext=".npy")
    np.save(file_path, N_errors)
def computeErrors(L, C0_32F, C_32F, Ng_32F, N_32F, A_8U):
    h, w = A_8U.shape
    N_error = angleErros(N_32F.reshape(-1, 3),
                         Ng_32F.reshape(-1, 3)).reshape(h, w)
    N_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
    N_error = trim(N_error, A_8U)

    C_error = normVectors(C0_32F.reshape(-1, 3) -
                          C_32F.reshape(-1, 3)).reshape(h, w)
    C_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
    C_error = trim(C_error, A_8U)

    I_32F = np.clip(LdotN(L, N_32F), 0.0, 1.0)
    Ig_32F = np.clip(LdotN(L, Ng_32F), 0.0, 1.0)
    I_error = np.abs(I_32F - Ig_32F)
    I_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
    I_error = trim(I_error, A_8U)
    return C_error, N_error, I_error
def computeLambertShadingError():
    shape_names = shapeNames()

    L = normalizeVector(np.array([-0.2, 0.3, 0.6]))

    C_errors = np.zeros(len(shape_names))
    N_errors = np.zeros(len(shape_names))

    for si, shape_name in enumerate(shape_names):
        Ng_data = shapeFile(shape_name)

        Ng_data = loadNormal(Ng_data)
        Ng_32F, A_8U = Ng_data

        N0_file = shapeResultFile(result_name="InitialNormal", data_name=shape_name)
        N0_data = loadNormal(N0_file)
        N0_32F, A_8U = N0_data

        C0_32F = LambertShader().diffuseShading(L, Ng_32F)

        sfs_method = ToonSFS(L, C0_32F, A_8U)
        sfs_method.setInitialNormal(N0_32F)
        sfs_method.setNumIterations(iterations=60)
        sfs_method.run()
        N_32F = sfs_method.normal()
        C_32F = sfs_method.shading()
        C_error = sfs_method.shadingError()
        C_error[A_8U < 0.5 * np.max(A_8U)] = 0.0

        C_errors[si] = np.average(C_error[A_8U > 0.5 * np.max(A_8U)])

        h, w = A_8U.shape[:2]
        N_error = angleErros(N_32F.reshape(-1, 3), Ng_32F.reshape(-1, 3)).reshape(h, w)
        N_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        N_errors[si] = np.average(N_error[A_8U > 0.5 * np.max(A_8U)])

    file_path = shapeResultFile("ShapeEstimation", "ShadingError", file_ext=".npy")
    np.save(file_path, C_errors)

    file_path = shapeResultFile("ShapeEstimation", "NormalError", file_ext=".npy")
    np.save(file_path, N_errors)
def materialShapeVariationFigure():
    target_colormaps = [23, 3, 12]
    #target_colormaps = [3, 17]
    colormap_files = [colorMapFile(cmap_id) for cmap_id in target_colormaps]

    target_shapes = ["Blob1", "ThreeBox"]
    shape_names = target_shapes
    #shape_names = shapeNames()[4:5]

    num_shapes = len(shape_names)
    num_colormaps = len(colormap_files)
    num_rows = num_colormaps
    num_cols = 6

    w = 20
    h = w * num_rows / num_cols

    fig, axes = plt.subplots(figsize=(w, h))
    font_size = 15
    fig.subplots_adjust(left=0.02,
                        right=0.98,
                        top=0.96,
                        bottom=0.02,
                        hspace=0.15,
                        wspace=0.1)
    fig.suptitle("", fontsize=font_size)

    plot_grid = SubplotGrid(num_rows, num_cols)

    L = normalizeVector(np.array([-0.4, 0.5, 0.6]))

    shape_name = "Blob1"

    Ng_data = shapeFile(shape_name)
    Ng_data = loadNormal(Ng_data)
    Ng_32F, A_8U = Ng_data

    N0_file = shapeResultFile(result_name="InitialNormal",
                              data_name=shape_name)
    N0_data = loadNormal(N0_file)
    N0_32F, A_8U = N0_data

    for mi, colormap_file in enumerate(colormap_files):
        M_32F = loadColorMap(colormap_file)
        C0_32F = ColorMapShader(M_32F).diffuseShading(L, Ng_32F)

        sfs_method = ToonSFS(L, C0_32F, A_8U)
        sfs_method.setInitialNormal(N0_32F)
        sfs_method.setNumIterations(iterations=40)
        sfs_method.setWeights(w_lap=5.0)
        sfs_method.run()

        N_32F = sfs_method.normal()
        C_32F = sfs_method.shading()
        #C_32F = cv2.bilateralFilter(C_32F, 0, 0.1, 3)
        C_error = sfs_method.shadingError()

        C_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        C_error = trim(C_error, A_8U)

        h, w = A_8U.shape
        N_error = angleErros(N_32F.reshape(-1, 3),
                             Ng_32F.reshape(-1, 3)).reshape(h, w)
        N_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        N_error = trim(N_error, A_8U)

        title = ""

        if mi == 0:
            title = "Ground-truth"
        plot_grid.showImage(setAlpha(C0_32F, to32F(A_8U)), title)

        title = ""
        if mi == 0:
            title = "Our result"
        plot_grid.showImage(setAlpha(C_32F, to32F(A_8U)), title)

        title = ""
        if mi == 0:
            title = "Error (shading)"
        plot_grid.showColorMap(C_error,
                               title,
                               v_min=0,
                               v_max=0.1,
                               with_colorbar=True)

        title = ""
        if mi == 0:
            title = "Ground-truth"
        plot_grid.showImage(normalToColor(Ng_32F, A_8U), title)

        title = ""
        if mi == 0:
            title = "Our result"
        plot_grid.showImage(normalToColor(N_32F, A_8U), title)

        title = ""
        if mi == 0:
            title = "Error (shape)"

        plot_grid.showColorMap(N_error,
                               title,
                               v_min=0,
                               v_max=50.0,
                               with_colorbar=True)

    #showMaximize()
    file_path = shapeResultFile("ShapeEstimation",
                                "MaterialShapeEvaluation",
                                file_ext=".pdf")
    fig.savefig(file_path, transparent=False)
def LambertShadingFigure():
    target_shapes = [
        "Sphere", "Cone", "Blob1", "Man", "Cone", "OctaFlower", "Pulley",
        "Grog", "Lucy", "Raptor"
    ]
    target_shapes = ["Blob1", "Pulley", "Lucy"]
    shape_names = target_shapes

    num_rows = len(shape_names)
    num_cols = 6

    w = 20
    h = w * num_rows / num_cols

    fig, axes = plt.subplots(figsize=(w, h))
    font_size = 15
    fig.subplots_adjust(left=0.02,
                        right=0.98,
                        top=0.96,
                        bottom=0.02,
                        hspace=0.15,
                        wspace=0.1)
    fig.suptitle("", fontsize=font_size)

    plot_grid = SubplotGrid(num_rows, num_cols)

    L = normalizeVector(np.array([-0.2, 0.3, 0.6]))

    for si, shape_name in enumerate(shape_names):
        Ng_data = shapeFile(shape_name)

        Ng_data = loadNormal(Ng_data)
        Ng_32F, A_8U = Ng_data

        N0_file = shapeResultFile(result_name="InitialNormal",
                                  data_name=shape_name)
        N0_data = loadNormal(N0_file)
        N0_32F, A_8U = N0_data

        C0_32F = LambertShader().diffuseShading(L, Ng_32F)

        sfs_method = ToonSFS(L, C0_32F, A_8U)
        sfs_method.setInitialNormal(N0_32F)
        sfs_method.setNumIterations(iterations=70)
        sfs_method.setWeights(w_lap=1.0)
        sfs_method.run()
        N_32F = sfs_method.normal()
        C_32F = sfs_method.shading()
        C_error = sfs_method.shadingError()
        C_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        C_error = trim(C_error, A_8U)

        h, w = A_8U.shape
        N_error = angleErros(N_32F.reshape(-1, 3),
                             Ng_32F.reshape(-1, 3)).reshape(h, w)
        N_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        N_error = trim(N_error, A_8U)

        title = ""
        if si == 0:
            title = "Ground-truth"
        plot_grid.showImage(setAlpha(C0_32F, to32F(A_8U)), title)

        title = ""
        if si == 0:
            title = "Our result"
        plot_grid.showImage(setAlpha(C_32F, to32F(A_8U)), title)

        title = ""
        if si == 0:
            title = "Error (shading)"
        plot_grid.showColorMap(C_error,
                               title,
                               v_min=0,
                               v_max=0.1,
                               with_colorbar=True)

        title = ""
        if si == 0:
            title = "Ground-truth"
        plot_grid.showImage(normalToColor(Ng_32F, A_8U), title)

        title = ""
        if si == 0:
            title = "Our result"
        plot_grid.showImage(normalToColor(N_32F, A_8U), title)

        title = ""
        if si == 0:
            title = "Error (shape)"

        plot_grid.showColorMap(N_error,
                               title,
                               v_min=0,
                               v_max=30.0,
                               with_colorbar=True)

    file_path = shapeResultFile("ShapeEstimation",
                                "LambertEstimationError",
                                file_ext=".pdf")
    fig.savefig(file_path, transparent=True)
def materialShapeVariationFigure():
    target_colormaps = [23, 3, 12]
    #target_colormaps = [3, 17]
    colormap_files = [colorMapFile(cmap_id) for cmap_id in target_colormaps]

    target_shapes = ["Blob1", "ThreeBox"]
    shape_names = target_shapes
    #shape_names = shapeNames()[4:5]

    num_shapes = len(shape_names)
    num_colormaps = len(colormap_files)
    num_rows = num_colormaps
    num_cols = 6

    w = 20
    h = w * num_rows / num_cols

    fig, axes = plt.subplots(figsize=(w, h))
    font_size = 15
    fig.subplots_adjust(left=0.02, right=0.98, top=0.96, bottom=0.02, hspace=0.15, wspace=0.1)
    fig.suptitle("", fontsize=font_size)

    plot_grid = SubplotGrid(num_rows, num_cols)

    L = normalizeVector(np.array([-0.4, 0.5, 0.6]))

    shape_name = "Blob1"

    Ng_data = shapeFile(shape_name)
    Ng_data = loadNormal(Ng_data)
    Ng_32F, A_8U = Ng_data

    N0_file = shapeResultFile(result_name="InitialNormal", data_name=shape_name)
    N0_data = loadNormal(N0_file)
    N0_32F, A_8U = N0_data

    for mi, colormap_file in enumerate(colormap_files):
        M_32F = loadColorMap(colormap_file)
        C0_32F = ColorMapShader(M_32F).diffuseShading(L, Ng_32F)

        sfs_method = ToonSFS(L, C0_32F, A_8U)
        sfs_method.setInitialNormal(N0_32F)
        sfs_method.setNumIterations(iterations=40)
        sfs_method.setWeights(w_lap=5.0)
        sfs_method.run()

        N_32F = sfs_method.normal()
        C_32F = sfs_method.shading()
            #C_32F = cv2.bilateralFilter(C_32F, 0, 0.1, 3)
        C_error = sfs_method.shadingError()

        C_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        C_error = trim(C_error, A_8U)

        h, w = A_8U.shape
        N_error = angleErros(N_32F.reshape(-1, 3), Ng_32F.reshape(-1, 3)).reshape(h, w)
        N_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        N_error = trim(N_error, A_8U)

        title = ""

        if mi == 0:
            title =  "Ground-truth"
        plot_grid.showImage(setAlpha(C0_32F, to32F(A_8U)), title)

        title = ""
        if mi == 0:
            title =  "Our result"
        plot_grid.showImage(setAlpha(C_32F, to32F(A_8U)), title)

        title = ""
        if mi == 0:
            title = "Error (shading)"
        plot_grid.showColorMap(C_error, title, v_min=0, v_max=0.1, with_colorbar=True)

        title = ""
        if mi == 0:
            title =  "Ground-truth"
        plot_grid.showImage(normalToColor(Ng_32F, A_8U), title)

        title = ""
        if mi == 0:
            title = "Our result"
        plot_grid.showImage(normalToColor(N_32F, A_8U), title)

        title = ""
        if mi == 0:
            title = "Error (shape)"

        plot_grid.showColorMap(N_error, title, v_min=0, v_max=50.0, with_colorbar=True)

    #showMaximize()
    file_path = shapeResultFile("ShapeEstimation", "MaterialShapeEvaluation", file_ext=".pdf")
    fig.savefig(file_path, transparent=False)
def LambertShadingFigure():
    target_shapes = ["Sphere", "Cone", "Blob1", "Man", "Cone", "OctaFlower", "Pulley", "Grog", "Lucy", "Raptor"]
    target_shapes = ["Blob1", "Pulley", "Lucy"]
    shape_names = target_shapes

    num_rows = len(shape_names)
    num_cols = 6

    w = 20
    h = w * num_rows / num_cols

    fig, axes = plt.subplots(figsize=(w, h))
    font_size = 15
    fig.subplots_adjust(left=0.02, right=0.98, top=0.96, bottom=0.02, hspace=0.15, wspace=0.1)
    fig.suptitle("", fontsize=font_size)

    plot_grid = SubplotGrid(num_rows, num_cols)

    L = normalizeVector(np.array([-0.2, 0.3, 0.6]))

    for si, shape_name in enumerate(shape_names):
        Ng_data = shapeFile(shape_name)

        Ng_data = loadNormal(Ng_data)
        Ng_32F, A_8U = Ng_data

        N0_file = shapeResultFile(result_name="InitialNormal", data_name=shape_name)
        N0_data = loadNormal(N0_file)
        N0_32F, A_8U = N0_data

        C0_32F = LambertShader().diffuseShading(L, Ng_32F)

        sfs_method = ToonSFS(L, C0_32F, A_8U)
        sfs_method.setInitialNormal(N0_32F)
        sfs_method.setNumIterations(iterations=70)
        sfs_method.setWeights(w_lap=1.0)
        sfs_method.run()
        N_32F = sfs_method.normal()
        C_32F = sfs_method.shading()
        C_error = sfs_method.shadingError()
        C_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        C_error = trim(C_error, A_8U)

        h, w = A_8U.shape
        N_error = angleErros(N_32F.reshape(-1, 3), Ng_32F.reshape(-1, 3)).reshape(h, w)
        N_error[A_8U < 0.5 * np.max(A_8U)] = 0.0
        N_error = trim(N_error, A_8U)

        title = ""
        if si == 0:
            title =  "Ground-truth"
        plot_grid.showImage(setAlpha(C0_32F, to32F(A_8U)), title)

        title = ""
        if si == 0:
            title =  "Our result"
        plot_grid.showImage(setAlpha(C_32F, to32F(A_8U)), title)

        title = ""
        if si == 0:
            title = "Error (shading)"
        plot_grid.showColorMap(C_error, title, v_min=0, v_max=0.1, with_colorbar=True)

        title = ""
        if si == 0:
            title =  "Ground-truth"
        plot_grid.showImage(normalToColor(Ng_32F, A_8U), title)

        title = ""
        if si == 0:
            title = "Our result"
        plot_grid.showImage(normalToColor(N_32F, A_8U), title)

        title = ""
        if si == 0:
            title = "Error (shape)"

        plot_grid.showColorMap(N_error, title, v_min=0, v_max=30.0, with_colorbar=True)

    file_path = shapeResultFile("ShapeEstimation", "LambertEstimationError", file_ext=".pdf")
    fig.savefig(file_path, transparent=True)