コード例 #1
0
def test_preconditioners():
    atol = 1e-6
    index = 1
    scale = 0.2

    name = f"GT{index:02d}"
    # print(name)

    image_dir = "data"

    image = load_image(f"{image_dir}/input_training_lowres/{name}.png", "rgb",
                       scale, "bilinear")
    trimap = load_image(
        f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png",
        "gray",
        scale,
        "nearest",
    )

    A, b = make_linear_system(cf_laplacian(image), trimap)

    preconditioners = [
        ("no", lambda A: None),
        ("jacobi", lambda A: jacobi(A)),
        ("icholt", lambda A: ichol(A, max_nnz=500000)),
        ("vcycle", lambda A: vcycle(A, trimap.shape)),
    ]

    expected_iterations = {
        "no": 532,
        "jacobi": 250,
        "icholt": 3,
        "vcycle": 88,
    }

    for preconditioner_name, preconditioner in preconditioners:
        callback = CounterCallback()

        M = preconditioner(A)

        x = cg(A, b, M=M, atol=atol, rtol=0, maxiter=10000, callback=callback)

        r = b - A.dot(x)

        norm_r = np.linalg.norm(r)

        assert norm_r <= atol

        n_expected = expected_iterations[preconditioner_name]

        if callback.n > n_expected:
            print(
                "WARNING: Unexpected number of iterations. Expected %d, but got %d"
                % (n_expected, callback.n))

        assert callback.n <= n_expected
コード例 #2
0
def test_foreground():
    try:
        from pymatting.foreground.estimate_foreground_ml_cupy import (
            estimate_foreground_ml_cupy, )
        from pymatting.foreground.estimate_foreground_ml_pyopencl import (
            estimate_foreground_ml_pyopencl, )
        methods = [
            estimate_foreground_ml,
            estimate_foreground_cf,
            estimate_foreground_ml_cupy,
            estimate_foreground_ml_pyopencl,
        ]
    except:
        methods = [
            estimate_foreground_ml,
            estimate_foreground_cf,
        ]
        warnings.warn(
            'Tests for GPU implementation skipped, because of missing packages.'
        )

    max_mse = 0.022
    scale = 0.1
    image = load_image("data/lemur/lemur.png", "RGB", scale, "box")
    trimap = load_image("data/lemur/lemur_trimap.png", "GRAY", scale,
                        "nearest")
    alpha = load_image("data/lemur/lemur_alpha.png", "GRAY", scale, "box")
    expected_foreground = load_image("data/lemur/lemur_foreground.png", "RGB",
                                     scale, "box")
    expected_background = load_image("data/lemur/lemur_background.png", "RGB",
                                     scale, "box")

    for estimate_foreground in methods:
        foreground, background = estimate_foreground(image,
                                                     alpha,
                                                     return_background=True)

        is_fg, is_bg, is_known, is_unknown = trimap_split(trimap,
                                                          flatten=False)

        difference = np.abs(foreground - expected_foreground)
        weighted_difference = (alpha[:, :, np.newaxis] *
                               difference)[is_unknown]

        mse = np.mean(weighted_difference)

        if mse > max_mse:
            print(
                "WARNING: %s - mean squared error threshold to expected foreground exceeded: %f"
                % (estimate_foreground.__name__, mse))

        assert mse <= max_mse
コード例 #3
0
ファイル: test_lkm.py プロジェクト: zumbrother/pymatting
def test_lkm():
    index = 1
    scale = 0.2
    epsilon = 1e-7
    radius = 2
    image_dir = "data"

    name = f"GT{index:02d}"

    image = load_image(f"{image_dir}/input_training_lowres/{name}.png", "rgb",
                       scale, "bilinear")
    trimap = load_image(
        f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png",
        "gray",
        scale,
        "nearest",
    )

    L_lkm, diag_L_lkm = lkm_laplacian(image, epsilon=epsilon, radius=radius)

    L_cf = cf_laplacian(image, epsilon=epsilon, radius=radius)

    A_cf, b, c = make_linear_system(L_cf, trimap, return_c=True)

    def A_lkm(x):
        return L_lkm(x) + c * x

    inv_diag_A_lkm = 1.0 / (diag_L_lkm + c)

    def jacobi_lkm(r):
        return inv_diag_A_lkm * r

    jacobi_cf = jacobi(A_cf)

    lkm_callback = ProgressCallback()
    cf_callback = ProgressCallback()

    x_lkm = cg(A_lkm, b, M=jacobi_lkm)
    x_cf = cg(A_cf, b, M=jacobi_cf)

    difference = np.linalg.norm(x_lkm - x_cf)

    assert difference < 2e-4
    assert abs(lkm_callback.n - cf_callback.n) <= 2
コード例 #4
0
def main():
    scale = max(SCALES)

    laplacian_names = [laplacian.__name__ for laplacian in LAPLACIANS]
    laplacian_names.append("lkm_laplacian")

    results = defaultdict(dict)

    for index in INDICES:
        name = f"GT{index:02d}.png"

        image_path = os.path.join(IMAGE_DIR, "input_training_lowres", name)
        trimap_path = os.path.join(IMAGE_DIR, "trimap_training_lowres/Trimap1",
                                   name)
        true_alpha_path = os.path.join(IMAGE_DIR, "gt_training_lowres", name)

        image = load_image(image_path, "rgb", scale, "bilinear")
        trimap = load_image(trimap_path, "gray", scale, "nearest")
        true_alpha = load_image(true_alpha_path, "gray", scale, "bilinear")

        is_fg, is_bg, is_known, is_unknown = trimap_split(trimap,
                                                          flatten=False)

        for laplacian_name in laplacian_names:
            print(f"Processing image {name} with {laplacian_name}")

            alpha = compute_alpha(image, trimap, laplacian_name, is_fg, is_bg,
                                  is_known)

            difference_unknown = np.abs(alpha - true_alpha)[is_unknown]

            error = np.linalg.norm(difference_unknown)

            results[laplacian_name][str(index)] = error

    os.makedirs("results/", exist_ok=True)
    with open("results/laplacians.json", "w") as f:
        print(results)
        json.dump(results, f, indent=4)
コード例 #5
0
ファイル: extend_fg.py プロジェクト: ywu40/mmediting
    def extend(self, fg_name):
        fg_name = fg_name.strip()
        alpha_path = join_first_contain(self.alpha_dirs, fg_name,
                                        self.data_root)
        fg_path = join_first_contain(self.fg_dirs, fg_name, self.data_root)
        alpha_path = osp.join(self.data_root, alpha_path)
        fg_path = osp.join(self.data_root, fg_path)
        extended_path = re.sub('/fg/', '/fg_extended/', fg_path)
        extended_path = extended_path.replace('jpg', 'png')
        if not osp.exists(alpha_path):
            raise FileNotFoundError(f'{alpha_path} does not exist!')
        if not osp.exists(fg_path):
            raise FileNotFoundError(f'{fg_path} does not exist!')

        image = load_image(fg_path, 'RGB')
        alpha = load_image(alpha_path, 'GRAY')
        F = estimate_foreground_ml(image, alpha, return_background=False)
        fg = Image.fromarray(np.uint8(F * 255))
        fg.save(extended_path)
        fix_png_file(osp.basename(extended_path), osp.dirname(extended_path))
        data_info = dict()
        data_info['alpha_path'] = alpha_path
        data_info['fg_path'] = extended_path
        return data_info
コード例 #6
0
def test_laplacians():
    indices = np.arange(27) + 1
    scale = 0.1
    image_dir = "data"

    # allow 1% regression
    allowed_error = 0.01

    expected_errors = {
        "cf_laplacian": [
            1.0839111942763648,
            3.841759348043566,
            3.358489754678929,
            5.079739853533443,
            1.8166309691629416,
            1.4385024442876313,
            1.501023996041348,
            4.18173542822268,
            3.4705502834921487,
            1.9351918367749816,
            2.488966062209934,
            1.3989649710604704,
            3.8741776417276306,
            0.9728827692868615,
            2.5399897862272747,
            10.642191399781298,
            1.6438877577185722,
            2.1543490658816635,
            1.1489311470229537,
            0.954323791336118,
            4.63568149096655,
            1.3580148342589717,
            1.1415671048773133,
            2.6984843343086196,
            4.691593185812834,
            6.003127907648125,
            4.390608172576709,
        ],
        "knn_laplacian": [
            2.089130250752722,
            3.767524785077177,
            3.7231290999572506,
            4.248310409891682,
            2.577488769545899,
            3.966983051036645,
            2.672147903806734,
            5.083407281314084,
            4.325617257887361,
            2.491360039941334,
            3.4146860032738173,
            2.1208129283441575,
            5.147092338936775,
            2.1976345580461056,
            3.0719533535155263,
            13.440447444054444,
            3.1829279859509327,
            3.711063622279358,
            2.4566255493763935,
            1.9078593671486113,
            4.956619727222683,
            3.1646762552974868,
            2.783888863957631,
            4.714904428201373,
            4.496672172372184,
            10.402315008230564,
            5.270881922679586,
        ],
        "lbdm_laplacian": [
            1.0839897312877216,
            3.841573408975021,
            3.365742999572245,
            5.077997360572911,
            1.8211938024322178,
            1.4392778020952708,
            1.5006381799933766,
            4.242864047447403,
            3.4904348404779753,
            1.9357254296106827,
            2.48917998418364,
            1.4043779651168937,
            3.8737045683526024,
            0.973164964965189,
            2.5443819959543457,
            10.651958437589906,
            1.6551494481797882,
            2.155449159543011,
            1.1490544867887889,
            0.9538815333644246,
            4.635535802794727,
            1.3595341099477465,
            1.143076373539195,
            2.707384007058893,
            4.698042368150364,
            6.0029066668301,
            4.390146320671879,
        ],
        "rw_laplacian": [
            4.865828574946059,
            6.1494492984553615,
            5.309294879045085,
            9.319890125482436,
            5.133000114540576,
            5.6589208995955405,
            6.225056464430212,
            9.487026325071337,
            7.871287695275896,
            5.059639993759375,
            5.810823041482708,
            4.846480646386845,
            10.15011136629045,
            4.9853995176605395,
            4.285341458168511,
            19.431455009600853,
            5.8216134507328015,
            5.952428504902877,
            4.0253392720779555,
            5.8843985862801045,
            8.728913826808643,
            5.5895832018589084,
            4.840184561383416,
            6.210095889788392,
            7.375539945860434,
            14.111658110736256,
            10.200776413201114,
        ],
        "uniform_laplacian": [
            4.0444203072543266,
            5.2284413228378135,
            9.019003158309758,
            9.778390304677947,
            3.6483079178591966,
            5.0698226038235195,
            4.712467105116259,
            8.21743217218649,
            8.122577721412982,
            4.696993284565137,
            4.268656408720733,
            3.477238604177124,
            10.00684602150998,
            3.481498583276864,
            3.9349298092727087,
            11.370794857942638,
            4.369772744405769,
            5.607500940968039,
            2.8416197864350137,
            4.550807753215429,
            8.621295976221598,
            4.878478538957252,
            4.979139178621439,
            4.5556096152615835,
            7.20245540436063,
            11.036244338204016,
            7.370920965316346,
        ],
    }

    debug = False

    actual_errors = {}

    for laplacian in LAPLACIANS:
        laplacian_name = laplacian.__name__
        print("testing", laplacian_name)

        errors = []

        for index, expected_error in zip(indices, expected_errors[laplacian_name]):
            name = f"GT{index:02d}"
            if debug:
                print(name)

            image = load_image(
                f"{image_dir}/input_training_lowres/{name}.png",
                "rgb",
                scale,
                "bilinear",
            )
            trimap = load_image(
                f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png",
                "gray",
                scale,
                "nearest",
            )
            true_alpha = load_image(
                f"{image_dir}/gt_training_lowres/{name}.png", "gray", scale, "bilinear"
            )

            A, b = make_linear_system(laplacian(image), trimap)

            x = scipy.sparse.linalg.spsolve(A, b)

            alpha = np.clip(x, 0, 1).reshape(trimap.shape)

            is_unknown = trimap_split(trimap, flatten=False)[3]

            difference_unknown = np.abs(alpha - true_alpha)[is_unknown]

            error = np.linalg.norm(difference_unknown)

            additional_error = (error - expected_error) / expected_error

            if additional_error > allowed_error:
                print("Regression:")
                print(laplacian_name)
                print(f"Performance decreased by {100.0 * additional_error:.3f} %")

            assert additional_error < allowed_error

            errors.append(error)

        actual_errors[laplacian_name] = errors

    print("Errors:")
    print(actual_errors)
コード例 #7
0
def run_solver_single_image(solver_name, scale, index):
    # Load images
    name = f"GT{index:02d}.png"

    image_path = os.path.join(IMAGE_DIR, "input_training_lowres", name)
    trimap_path = os.path.join(IMAGE_DIR, "trimap_training_lowres/Trimap1",
                               name)

    image = load_image(image_path, "rgb", scale, "bilinear")
    trimap = load_image(trimap_path, "gray", scale, "nearest")

    # Create linear system
    L = cf_laplacian(image)

    A, b = make_linear_system(L, trimap)

    is_fg, is_bg, is_known, is_unknown = trimap_split(trimap)

    atol = ATOL * np.sum(is_known)
    rtol = atol / np.linalg.norm(b)

    # Compute various matrix representations
    Acsr = A.tocsr()
    Acsc = A.tocsc()
    Acoo = A.tocoo()

    AL = scipy.sparse.tril(Acoo)

    # Start memory usage measurement thread
    memory_usage = [get_memory_usage()]
    thread = threading.Thread(target=log_memory_usage, args=(memory_usage, ))
    thread.is_running = True
    # All threads should die if the solver thread crashes so we can at least
    # carry on with the other solvers.
    thread.daemon = True
    thread.start()

    # Measure solver build time
    # Note that it is not easily possible to separate build time from solve time
    # for every solver, which is why only the sum of build_time and solve_time
    # should be compared for fairness.
    start_time = time.perf_counter()
    run_solver = build_solver(solver_name, A, Acsr, Acsc, Acoo, AL, b, atol,
                              rtol)
    build_time = time.perf_counter() - start_time

    # Measure actual solve time
    start_time = time.perf_counter()
    x = run_solver()
    solve_time = time.perf_counter() - start_time

    # Stop memory usage measuring thread
    thread.is_running = False
    thread.join()

    # Compute relative error
    r = b - A.dot(x)
    norm_r = np.linalg.norm(r)

    # Store results
    h, w = trimap.shape

    result = dict(
        solver_name=str(solver_name),
        image_name=str(name),
        scale=float(scale),
        index=int(index),
        norm_r=float(norm_r),
        build_time=float(build_time),
        solve_time=float(solve_time),
        atol=float(atol),
        rtol=float(rtol),
        width=int(w),
        height=int(h),
        n_fg=int(np.sum(is_fg)),
        n_bg=int(np.sum(is_bg)),
        n_known=int(np.sum(is_known)),
        n_unknown=int(np.sum(is_unknown)),
        memory_usage=memory_usage,
    )

    print(result)

    # Ensure that everything worked as expected
    assert norm_r <= atol

    # Inspect alpha for debugging
    if 0:
        alpha = np.clip(x, 0, 1).reshape(h, w)
        show_images([alpha])

    return result
コード例 #8
0
def test_laplacians():
    indices = np.arange(27) + 1
    scale = 0.1
    atol = 1e-5
    image_dir = "data"

    # allow 1% regression
    allowed_error = 0.01

    expected_errors = {
        "cf_laplacian": [
            4.355988465052598,
            7.754267319636701,
            4.747200315117146,
            7.644794385858358,
            4.384527830585845,
            4.531604199822819,
            4.1031381858764835,
            6.0839679119939385,
            4.524651010229449,
            4.358659056252233,
            5.890604883965759,
            3.5985421897613152,
            10.065349782695913,
            2.585264548989054,
            3.7208956259331214,
            16.362808646457598,
            3.8009339105572795,
            6.408594319626463,
            6.017566616442684,
            4.044413987769631,
            11.785953665340037,
            5.430424431633303,
            3.21780354668552,
            5.1231383764470655,
            9.431651112452275,
            13.036791155586041,
            8.988754957709757,
        ],
        "knn_laplacian": [
            3.529027369985819,
            6.779684407351125,
            5.315215932104659,
            7.98386599862108,
            4.201669915857062,
            5.292745196567874,
            4.154624688607045,
            6.386926684070437,
            5.405970320706553,
            4.908653603147019,
            6.359468813893265,
            3.2796344351763556,
            14.078147343580305,
            2.8225579528031197,
            4.833168662156053,
            13.893654956704204,
            4.55905119644519,
            6.511696323731112,
            4.901962902239601,
            4.058804576038566,
            11.250593534800391,
            5.708992860151824,
            3.9937473660706355,
            7.521799056342947,
            12.451095645355371,
            19.559055742483523,
            10.23295095188048,
        ],
        "lbdm_laplacian": [
            4.355917047411817,
            7.755294676926569,
            4.754459256408494,
            7.6527379119497985,
            4.388543223502785,
            4.532265356616695,
            4.101334275889063,
            6.157890368267364,
            4.542514790384632,
            4.354168371741936,
            5.8910132753382936,
            3.597996913221781,
            10.046433903595707,
            2.5842975995911734,
            3.7271507175548657,
            16.377298831555507,
            3.8079423147251483,
            6.411020196265968,
            6.018502476088196,
            4.044885752161074,
            11.78269622620083,
            5.430059151842563,
            3.2183422118639493,
            5.132075679579669,
            9.434882862603411,
            13.025182853722477,
            8.987652819180946,
        ],
        "rw_laplacian": [
            5.41122022101416,
            8.433097819805354,
            5.831135210315725,
            13.5612231500563,
            6.709520989020883,
            7.070404131242503,
            8.386298390789808,
            12.322855420059101,
            8.021969631117862,
            6.081774217141341,
            7.7249956991680255,
            5.764913649046752,
            16.450934622522023,
            5.160830048929572,
            5.1776067921810425,
            19.8520195558823,
            6.6178806558435515,
            8.427877366337041,
            6.402179991723246,
            8.23741566966435,
            13.829571729270182,
            7.287711407153692,
            6.013004768961857,
            8.373112239007229,
            14.367435257885573,
            21.48881471389073,
            15.311157506616729,
        ],
        "uniform_laplacian": [
            9.060169551556976,
            10.412435398963028,
            13.59968223667663,
            13.846523627602492,
            7.920606255132267,
            9.742329228146986,
            9.842485562589646,
            12.678815442427544,
            11.046849004040244,
            9.072405246677807,
            10.491323657975121,
            6.997344821901131,
            16.996103185024563,
            6.70609069103123,
            6.738930012060983,
            13.416425113943234,
            7.636413320373581,
            11.921912128705248,
            8.430136202987251,
            9.091272603814666,
            16.26958162705805,
            10.192918063068861,
            8.775645747372451,
            8.203250649100266,
            12.316984833694821,
            20.0647516222413,
            12.544650300995547,
        ],
    }

    debug = False

    for laplacian in LAPLACIANS:
        laplacian_name = laplacian.__name__
        print("testing", laplacian_name)

        errors = []

        for index, expected_error in zip(indices,
                                         expected_errors[laplacian_name]):
            name = f"GT{index:02d}"
            if debug:
                print(name)

            image = load_image(
                f"{image_dir}/input_training_lowres/{name}.png",
                "rgb",
                scale,
                "bilinear",
            )
            trimap = load_image(
                f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png",
                "gray",
                scale,
                "bilinear",
            )
            true_alpha = load_image(
                f"{image_dir}/gt_training_lowres/{name}.png", "gray", scale,
                "nearest")

            A, b = make_linear_system(laplacian(image), trimap)

            x = scipy.sparse.linalg.spsolve(A, b)

            r = b - A.dot(x)

            norm_r = np.linalg.norm(r)

            alpha = np.clip(x, 0, 1).reshape(trimap.shape)

            is_unknown = trimap_split(trimap, flatten=False)[3]

            difference_unknown = np.abs(alpha - true_alpha)[is_unknown]

            error = np.linalg.norm(difference_unknown)

            additional_error = (error - expected_error) / expected_error

            if additional_error > allowed_error:
                print("Regression:")
                print(laplacian_name)
                print(
                    f"Performance decreased by {100.0 * additional_error:.3f} %"
                )

            assert additional_error < allowed_error

            errors.append(error)
コード例 #9
0
def main():
    solvers = []

    if 0:
        from pymatting import cg, ichol

        def solve_cg_icholt(A, b, atol):
            M = ichol(A, discard_threshold=1e-3, shifts=[0.002])
            return cg(A, b, M=M, atol=atol, rtol=0)

        solvers.append(
            ("cg_icholt", lambda: solve_cg_icholt(Acsc, b, atol=atol)))

    if 1:
        import pyamg
        from pymatting import cg

        def solve_pyamg(A, b, atol):
            M = pyamg.smoothed_aggregation_solver(A).aspreconditioner()
            return cg(A, b, M=M, atol=atol, rtol=0)

        solvers.append(("pyamg", lambda: solve_pyamg(Acsr, b, atol=atol)))

    if 0:
        from solve_mumps import solve_mumps_coo, init_mpi, finalize_mpi

        init_mpi()

        def solve_mumps(A, b):
            return solve_mumps_coo(A.data, A.row, A.col, b, is_symmetric=True)

        solvers.append(("mumps", lambda: solve_mumps(AL, b)))

    if 1:
        from solve_petsc import solve_petsc_coo, init_petsc, finalize_petsc

        init_petsc()

        def solve_petsc(A, b, atol):
            return solve_petsc_coo(A.data,
                                   A.row,
                                   A.col,
                                   b,
                                   atol=atol,
                                   gamg_threshold=0.1)

        solvers.append(("petsc", lambda: solve_petsc(Acoo, b, atol=atol)))

    if 1:
        from solve_amgcl import solve_amgcl_csr

        def solve_amgcl(A, b, atol):
            return solve_amgcl_csr(A.data,
                                   A.indices,
                                   A.indptr,
                                   b,
                                   atol=atol,
                                   rtol=0)

        solvers.append(("amgcl", lambda: solve_amgcl(Acsr, b, atol=atol)))

    if 0:
        solvers.append(
            ("umfpack",
             lambda: scipy.sparse.linalg.spsolve(Acsc, b, use_umfpack=True)))

    if 0:

        def solve_superLU(A, b):
            # Usually the same as:
            # scipy.sparse.linalg.spsolve(A, b, use_umfpack=False)
            return scipy.sparse.linalg.splu(A).solve(b)

        solvers.append(("superlu", lambda: solve_superLU(Acsc, b)))

    if 1:
        from solve_eigen import solve_eigen_cholesky_coo

        def solve_eigen_cholesky(A, b):
            return solve_eigen_cholesky_coo(A.data, A.row, A.col, b)

        solvers.append(
            ("eigen_cholesky", lambda: solve_eigen_cholesky(Acoo, b)))

    if 0:
        from solve_eigen import solve_eigen_icholt_coo

        def solve_eigen_icholt(A, b, rtol):
            # just large enough to not fail for given images (might fail with larger/different images)
            initial_shift = 2e-4
            return solve_eigen_icholt_coo(A.data,
                                          A.row,
                                          A.col,
                                          b,
                                          rtol=rtol,
                                          initial_shift=initial_shift)

        solvers.append(
            ("eigen_icholt", lambda: solve_eigen_icholt(Acoo, b, rtol=rtol)))

    indices = np.arange(27)
    scales = np.sqrt(np.linspace(0.1, 1.0, 11))

    # indices = np.int32([1, 2])
    # scales = [0.1]

    atol0 = 1e-7

    image_dir = "data"

    for solver_name, solver in solvers:
        results = []

        for scale in scales:
            for index in indices + 1:

                name = f"GT{index:02d}"
                image = load_image(
                    f"{image_dir}/input_training_lowres/{name}.png",
                    "rgb",
                    scale,
                    "bilinear",
                )
                trimap = load_image(
                    f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png",
                    "gray",
                    scale,
                    "bilinear",
                )

                L = cf_laplacian(image)

                A, b = make_linear_system(L, trimap)

                is_fg, is_bg, is_known, is_unknown = trimap_split(trimap)

                atol = atol0 * np.sum(is_known)
                rtol = atol / np.linalg.norm(b)

                Acsr = A.tocsr()
                Acsc = A.tocsc()
                Acoo = A.tocoo()
                AL = scipy.sparse.tril(Acoo)

                def log_memory_usage(memory_usage):
                    while running:
                        memory_usage.append(get_memory_usage())
                        time.sleep(0.01)

                memory_usage = [get_memory_usage()]
                running = True
                thread = threading.Thread(target=log_memory_usage,
                                          args=(memory_usage, ))
                thread.start()

                start_time = time.perf_counter()

                x = solver()

                elapsed_time = time.perf_counter() - start_time

                running = False
                thread.join()

                r = b - A.dot(x)
                norm_r = np.linalg.norm(r)

                h, w = trimap.shape

                result = dict(
                    solver_name=str(solver_name),
                    scale=float(scale),
                    index=int(index),
                    norm_r=float(norm_r),
                    t=float(elapsed_time),
                    atol=float(atol),
                    rtol=float(rtol),
                    width=int(w),
                    height=int(h),
                    n_fg=int(np.sum(is_fg)),
                    n_bg=int(np.sum(is_bg)),
                    n_known=int(np.sum(is_known)),
                    n_unknown=int(np.sum(is_unknown)),
                    memory_usage=memory_usage,
                )

                print(result)

                assert norm_r <= atol

                if 0:
                    alpha = np.clip(x, 0, 1).reshape(h, w)
                    show_images([alpha])

                results.append(result)

        path = f"benchmarks/results/solver/{solver_name}/results.json"

        dir_name = os.path.split(path)[0]
        if len(dir_name) > 0:
            os.makedirs(dir_name, exist_ok=True)

        with open(path, "w") as f:
            json.dump(results, f, indent=4)
コード例 #10
0
def main():
    indices = 1 + np.arange(27)
    scale = 1.0
    image_dir = "../data"
    info = {}
    
    laplacian_name = "lkm_laplacian"
    print(laplacian_name)
    
    errors = {}
    
    for index in indices:
        name = f"GT{index:02d}"
        print(name)
        
        image = load_image(f"{image_dir}/input_training_lowres/{name}.png", "rgb", scale, "bilinear")
        trimap = load_image(f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png", "gray", scale, "bilinear")
        true_alpha = load_image(f"{image_dir}/gt_training_lowres/{name}.png", "gray", scale, "nearest")
        
        L_matvec, diag_L = lkm_laplacian(image)
        
        is_fg, is_bg, is_known, is_unknown = trimap_split(trimap)
        
        atol = 1e-7 * np.sum(is_known)
        
        lambda_value = 100.0
        
        c = lambda_value * is_known
        b = lambda_value * is_fg
        
        inv_diag_A = 1.0 / (diag_L + c)
        
        def A_matvec(x):
            return L_matvec(x) + c * x
        
        def jacobi(x):
            return inv_diag_A * x
        
        x = cg(A_matvec, b, M=jacobi, atol=atol)
        
        alpha = np.clip(x, 0, 1).reshape(trimap.shape)
        
        difference_unknown = np.abs(alpha - true_alpha)[is_unknown.reshape(trimap.shape)]
        
        error = np.linalg.norm(difference_unknown)
        
        errors[str(index)] = error
    
    info[laplacian_name] = errors
    
    for laplacian in LAPLACIANS:
        laplacian_name = laplacian.__name__
        print(laplacian_name)
        
        errors = {}
        
        for index in indices:
            name = f"GT{index:02d}"
            print(name)
            
            image = load_image(f"{image_dir}/input_training_lowres/{name}.png", "rgb", scale, "bilinear")
            trimap = load_image(f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png", "gray", scale, "bilinear")
            true_alpha = load_image(f"{image_dir}/gt_training_lowres/{name}.png", "gray", scale, "nearest")
            
            A, b = make_linear_system(laplacian(image), trimap)
            
            is_fg, is_bg, is_known, is_unknown = trimap_split(trimap, flatten=False)
            
            atol = 1e-7 * np.sum(is_known)
            
            preconditioner = {
                "knn_laplacian": jacobi,
                "rw_laplacian": jacobi,
                "cf_laplacian": ichol,
                "lbdm_laplacian": ichol,
                "uniform_laplacian": ichol,
            }[laplacian_name]
            
            x = cg(A, b, M=preconditioner(A), atol=atol)
            
            alpha = np.clip(x, 0, 1).reshape(trimap.shape)
            
            difference_unknown = np.abs(alpha - true_alpha)[is_unknown]
            
            error = np.linalg.norm(difference_unknown)
            
            errors[str(index)] = error
    
        info[laplacian_name] = errors
    
    with open("results/laplacians.json", "w") as f:
        print(info)
        json.dump(info, f, indent=4)
コード例 #11
0
ファイル: test_lkm.py プロジェクト: zyqqing/pymatting
def test_lkm():
    index = 1
    scale = 0.2
    atol = 1e-5
    epsilon = 1e-7
    radius = 2
    image_dir = "data"

    errors = []

    name = f"GT{index:02d}"
    # print(name)

    image = load_image(
        f"{image_dir}/input_training_lowres/{name}.png", "rgb", scale, "bilinear"
    )
    trimap = load_image(
        f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png",
        "gray",
        scale,
        "bilinear",
    )
    true_alpha = load_image(
        f"{image_dir}/gt_training_lowres/{name}.png", "gray", scale, "nearest"
    )

    L_lkm, diag_L_lkm = lkm_laplacian(image, epsilon=epsilon, radius=radius)

    L_cf = cf_laplacian(image, epsilon=epsilon, radius=radius)

    A_cf, b, c = make_linear_system(L_cf, trimap, return_c=True)

    def A_lkm(x):
        return L_lkm(x) + c * x

    inv_diag_A_lkm = 1.0 / (diag_L_lkm + c)

    def jacobi_lkm(r):
        return inv_diag_A_lkm * r

    jacobi_cf = jacobi(A_cf)

    lkm_callback = ProgressCallback()
    cf_callback = ProgressCallback()

    x_lkm = cg(A_lkm, b, M=jacobi_lkm)
    x_cf = cg(A_cf, b, M=jacobi_cf)

    if 0:
        # show result
        show_images(
            [x_lkm.reshape(trimap.shape), x_cf.reshape(trimap.shape),]
        )

    difference = np.linalg.norm(x_lkm - x_cf)

    # print("norm(x_lkm - x_cf):")
    # print(difference)
    # print("iterations:")
    # print("lkm:", lkm_callback.n)
    # print("cf:", cf_callback.n)

    assert difference < 1e-5
    assert abs(lkm_callback.n - cf_callback.n) <= 2