Пример #1
0
    def _solve_(self, L, x, b):
        if 'FIPY_VERBOSE_SOLVER' in os.environ:
            verbosity = True
        else:
            verbosity = False

        return solve(L.matrix, b, verb=verbosity, tol=self.tolerance)
Пример #2
0
 def _call_solver (self):
     """Solves the linear system (self._A)x = self._b and returns the solution vector.
     
     @return: The solution to the linear system.
     """
     import pyamg
     x = pyamg.solve ( self._A, self._b, verb=True, tol=1e-8, maxiter=800 )
     return x, 0
Пример #3
0
def poisson_blend(artwork_img, selfie_img, mask_img):
    # this function works only for 500x500 images (input adjustment needeed)
    # kudos to https://github.com/fbessho/PyPoi
    mask_img = mask_img[0:500, 0:500]
    mask_img[mask_img == 0] = False
    mask_img[mask_img != False] = True

    # create coefficient matrix
    A = scipy.sparse.identity(np.prod((500,500)), format='lil')
    for y in range(0,500):
        for x in range(0,500):
            if mask_img[y, x]:
                index = x + y * 500
                A[index, index] = 4
                if index + 1 < np.prod((500,500)):
                    A[index, index + 1] = -1
                if index - 1 >= 0:
                    A[index, index - 1] = -1
                if index + 500 < np.prod((500,500)):
                    A[index, index + 500] = -1
                if index - 500 >= 0:
                    A[index, index - 500] = -1

    A = A.tocsr() # Returns a copy of this matrix in Compressed Sparse Row format

    # create poisson matrix for b
    P = pyamg.gallery.poisson(mask_img.shape)

    # for each layer (ex. RGB)
    for channel in range(artwork_img.shape[2]):
        t = artwork_img[0:500, 0:500, channel]
        s = selfie_img[0:500, 0:500, channel]
        t = t.flatten() # Returns a copy of the array collapsed into one dimension.
        s = s.flatten()

        # create b
        b = P * s
        for y in range(0,500):
            for x in range(0,500):
                if not mask_img[y, x]:
                    index = x + y * 500
                    b[index] = t[index]

        # solve Ax = b
        x = pyamg.solve(A, b, verb=False, tol=1e-10)

        # assign x to target image
        x = np.reshape(x, (500,500))
        x[x > 255] = 255
        x[x < 0] = 0
        x = np.array(x, artwork_img.dtype)
        artwork_img[0:500, 0:500, channel] = x

    return artwork_img
Пример #4
0
    def apply_inverse(op,
                      V,
                      options=None,
                      least_squares=False,
                      check_finite=True,
                      default_solver='pyamg_solve'):
        """Solve linear equation system.

        Applies the inverse of `op` to the vectors in `rhs` using PyAMG.

        Parameters
        ----------
        op
            The linear, non-parametric |Operator| to invert.
        rhs
            |VectorArray| of right-hand sides for the equation system.
        options
            The |solver_options| to use (see :func:`solver_options`).
        least_squares
            Must be `False`.
        check_finite
            Test if solution only contains finite values.
        default_solver
            Default solver to use (pyamg_solve, pyamg_rs, pyamg_sa).

        Returns
        -------
        |VectorArray| of the solution vectors.
        """

        assert V in op.range

        if least_squares:
            raise NotImplementedError

        if isinstance(op, NumpyMatrixOperator):
            matrix = op.matrix
        else:
            from pymor.algorithms.to_matrix import to_matrix
            matrix = to_matrix(op)

        options = _parse_options(options, solver_options(), default_solver,
                                 None, least_squares)

        V = V.to_numpy()
        promoted_type = np.promote_types(matrix.dtype, V.dtype)
        R = np.empty((len(V), matrix.shape[1]), dtype=promoted_type)

        if options['type'] == 'pyamg_solve':
            if len(V) > 0:
                V_iter = iter(enumerate(V))
                R[0], ml = pyamg.solve(matrix,
                                       next(V_iter)[1],
                                       tol=options['tol'],
                                       maxiter=options['maxiter'],
                                       return_solver=True)
                for i, VV in V_iter:
                    R[i] = pyamg.solve(matrix,
                                       VV,
                                       tol=options['tol'],
                                       maxiter=options['maxiter'],
                                       existing_solver=ml)
        elif options['type'] == 'pyamg_rs':
            ml = pyamg.ruge_stuben_solver(
                matrix,
                strength=options['strength'],
                CF=options['CF'],
                presmoother=options['presmoother'],
                postsmoother=options['postsmoother'],
                max_levels=options['max_levels'],
                max_coarse=options['max_coarse'],
                coarse_solver=options['coarse_solver'])
            for i, VV in enumerate(V):
                R[i] = ml.solve(VV,
                                tol=options['tol'],
                                maxiter=options['maxiter'],
                                cycle=options['cycle'],
                                accel=options['accel'])
        elif options['type'] == 'pyamg_sa':
            ml = pyamg.smoothed_aggregation_solver(
                matrix,
                symmetry=options['symmetry'],
                strength=options['strength'],
                aggregate=options['aggregate'],
                smooth=options['smooth'],
                presmoother=options['presmoother'],
                postsmoother=options['postsmoother'],
                improve_candidates=options['improve_candidates'],
                max_levels=options['max_levels'],
                max_coarse=options['max_coarse'],
                diagonal_dominance=options['diagonal_dominance'])
            for i, VV in enumerate(V):
                R[i] = ml.solve(VV,
                                tol=options['tol'],
                                maxiter=options['maxiter'],
                                cycle=options['cycle'],
                                accel=options['accel'])
        else:
            raise ValueError('Unknown solver type')

        if check_finite:
            if not np.isfinite(np.sum(R)):
                raise InversionError('Result contains non-finite values')

        return op.source.from_numpy(R)
Пример #5
0
def PoissonBlending(src, tar, mask):
    H, W = tar.shape[:2]
    blending_mask = mask
    fill_mask = np.ones_like(mask, dtype=bool)
    loc = blending_mask.nonzero()
    loc_map = {}  # mapping from coordinate to variable
    for i_loc, (j, i) in enumerate(zip(loc[0], loc[1])):
        loc_map[(j, i)] = i_loc
    #w_l, w_r = BlendingWeights(src_mask, tar_mask, src_img.shape[0])
    N = np.count_nonzero(blending_mask)
    y_min = np.min(loc[0])
    y_max = np.max(loc[0])
    x_min = np.min(loc[1])
    x_max = np.max(loc[1])
    res = np.zeros((N, 3))
    size = np.prod((y_max - y_min + 1, x_max - x_min + 1))
    print('solving...N: {}'.format(N))
    stride = x_max - x_min + 1
    A = scipy.sparse.identity(N, format='lil')
    b = np.zeros((N, 3), dtype=np.float32)
    for (j, i) in zip(loc[0], loc[1]):
        alpha = 0.0  #w_l[j, i]
        cur_ptr = loc_map[(j, i)]
        if (blending_mask[j, i]):
            N_p = 0.0
            v_pq = np.zeros((1, 3), dtype=np.float32)
            f_p = tar[j, i, :].astype(np.float32)
            g_p = src[j, i, :].astype(np.float32)
            if (j > 0):
                if (fill_mask[j - 1, i]):  #upper neighbor exists
                    f_q = tar[j - 1, i, :].astype(np.float32)
                    g_q = src[j - 1, i, :].astype(np.float32)
                    if (blending_mask[j - 1, i]):  # in the omega
                        v_pq += np.dot([alpha, 1 - alpha],
                                       np.array([(f_p - f_q), (g_p - g_q)]))
                        A[cur_ptr, loc_map[(j - 1, i)]] = -1.0
                    else:  # on the boundary
                        # known function f*_p + v_pq
                        # here we choose gradient image of original image with its
                        # pixel value exists.
                        v_pq += tar[j - 1,
                                    i, :].astype(np.float32)  #+ (f_p-f_q)
                    N_p += 1.0
            if (j < H - 1):
                if (fill_mask[j + 1, i]):  #lower neighbor exists
                    f_q = tar[j + 1, i, :].astype(np.float32)
                    g_q = src[j + 1, i, :].astype(np.float32)
                    if (blending_mask[j + 1, i]):  # in the omega
                        v_pq += np.dot([alpha, 1 - alpha],
                                       np.array([(f_p - f_q), (g_p - g_q)]))
                        A[cur_ptr, loc_map[(j + 1, i)]] = -1.0
                    else:  # on the boundary
                        v_pq += tar[j + 1,
                                    i, :].astype(np.float32)  #+ (f_p-f_q)
                    N_p += 1.0
            if (fill_mask[j, i - 1]):  #left neighbor exists
                f_q = tar[j, i - 1, :].astype(np.float32)
                g_q = src[j, i - 1, :].astype(np.float32)
                if (blending_mask[j, i - 1]):  # in the omega
                    v_pq += np.dot([alpha, 1 - alpha],
                                   np.array([(f_p - f_q), (g_p - g_q)]))
                    A[cur_ptr, loc_map[(j, i - 1)]] = -1.0
                else:  # on the boundary
                    v_pq += tar[j, i - 1, :].astype(np.float32)  #+ (f_p-f_q)
                N_p += 1.0
            if (fill_mask[j, i + 1]):  #right neighbor exists
                f_q = tar[j, i + 1, :].astype(np.float32)
                g_q = src[j, i + 1, :].astype(np.float32)
                if (blending_mask[j, i + 1]):  # in the omega
                    v_pq += np.dot([alpha, 1 - alpha],
                                   np.array([(f_p - f_q), (g_p - g_q)]))
                    A[cur_ptr, loc_map[(j, i + 1)]] = -1.0
                else:  # on the boundary
                    v_pq += tar[j, i + 1, :].astype(np.float32)  #+ (f_p-f_q)
                N_p += 1.0
            A[cur_ptr, cur_ptr] = N_p
            b[cur_ptr, :] = v_pq.astype(np.float32)
        else:  # not in blending region
            raise Exception('Illegal image!!')
    gc.collect()
    A = A.tocsr()
    for c in range(3):
        x = pyamg.solve(A, b[:, c], verb=True, tol=1e-5)
        x = np.clip(x, 0, 255)
        res[:, c] = x.astype('uint8')
    tar = tar.copy()
    tar[blending_mask, :] = res
    return tar
Пример #6
0
from scipy import rand
from numpy import arange, array           
from pyamg import solve               
from pyamg.gallery import poisson         
from pyamg.util.linalg import norm        

# Run solve(...) with the verbose option
n = 100
A = poisson((n,n),format='csr')         
b = array(arange(A.shape[0]), dtype=float)
x = solve(A,b,verb=True)

##
# Return the solver generated by solve(...) so that it can be used again
(x,ml) = solve(A,b,verb=True,return_solver=True,tol=1e-8)               

# run for a new right-hand-side
b2 = rand(b.shape[0],)
x2 = solve(A,b2,verb=True,existing_solver=ml,tol=1e-8)

Пример #7
0
def apply_inverse(matrix, U, options=None):
    """Solve linear equation system.

    Applies the inverse of `matrix` to the row vectors in `U`.

    See :func:`sparse_options` for documentation of all possible options for
    sparse matrices.

    Parameters
    ----------
    matrix
        The |NumPy| matrix to invert.
    U
        2-dimensional |NumPy array| containing as row vectors
        the right-hand sides of the linear equation systems to
        solve.
    options
        |invert_options| to use. (See :func:`invert_options`.)

    Returns
    -------
    |NumPy array| of the solution vectors.
    """

    default_options = invert_options(matrix)

    if options is None:
        options = default_options.values()[0]
    elif isinstance(options, str):
        if options == 'least_squares':
            for k, v in default_options.iteritems():
                if k.startswith('least_squares'):
                    options = v
                    break
            assert not isinstance(options, str)
        else:
            options = default_options[options]
    else:
        assert 'type' in options and options['type'] in default_options \
            and options.viewkeys() <= default_options[options['type']].viewkeys()
        user_options = options
        options = default_options[user_options['type']]
        options.update(user_options)

    R = np.empty((len(U), matrix.shape[1]))

    if options['type'] == 'solve':
        for i, UU in enumerate(U):
            try:
                R[i] = np.linalg.solve(matrix, UU)
            except np.linalg.LinAlgError as e:
                raise InversionError('{}: {}'.format(str(type(e)), str(e)))
    elif options['type'] == 'least_squares_lstsq':
        for i, UU in enumerate(U):
            try:
                R[i], _, _, _ = np.linalg.lstsq(matrix, UU, rcond=options['rcond'])
            except np.linalg.LinAlgError as e:
                raise InversionError('{}: {}'.format(str(type(e)), str(e)))
    elif options['type'] == 'bicgstab':
        for i, UU in enumerate(U):
            R[i], info = bicgstab(matrix, UU, tol=options['tol'], maxiter=options['maxiter'])
            if info != 0:
                if info > 0:
                    raise InversionError('bicgstab failed to converge after {} iterations'.format(info))
                else:
                    raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'.
                                         format(info))
    elif options['type'] == 'bicgstab_spilu':
        ilu = spilu(matrix, drop_tol=options['spilu_drop_tol'], fill_factor=options['spilu_fill_factor'],
                    drop_rule=options['spilu_drop_rule'], permc_spec=options['spilu_permc_spec'])
        precond = LinearOperator(matrix.shape, ilu.solve)
        for i, UU in enumerate(U):
            R[i], info = bicgstab(matrix, UU, tol=options['tol'], maxiter=options['maxiter'], M=precond)
            if info != 0:
                if info > 0:
                    raise InversionError('bicgstab failed to converge after {} iterations'.format(info))
                else:
                    raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'.
                                         format(info))
    elif options['type'] == 'spsolve':
        for i, UU in enumerate(U):
            R[i] = spsolve(matrix, UU, permc_spec=options['permc_spec'])
    elif options['type'] == 'lgmres':
        for i, UU in enumerate(U):
            R[i], info = lgmres(matrix, UU.copy(i),
                                tol=options['tol'],
                                maxiter=options['maxiter'],
                                inner_m=options['inner_m'],
                                outer_k=options['outer_k'])
            if info > 0:
                raise InversionError('lgmres failed to converge after {} iterations'.format(info))
            assert info == 0
    elif options['type'] == 'least_squares_lsmr':
        for i, UU in enumerate(U):
            R[i], info, itn, _, _, _, _, _ = lsmr(matrix, UU.copy(i),
                                                  damp=options['damp'],
                                                  atol=options['atol'],
                                                  btol=options['btol'],
                                                  conlim=options['conlim'],
                                                  maxiter=options['maxiter'],
                                                  show=options['show'])
            assert 0 <= info <= 7
            if info == 7:
                raise InversionError('lsmr failed to converge after {} iterations'.format(itn))
    elif options['type'] == 'least_squares_lsqr':
        for i, UU in enumerate(U):
            R[i], info, itn, _, _, _, _, _, _, _ = lsqr(matrix, UU.copy(i),
                                                        damp=options['damp'],
                                                        atol=options['atol'],
                                                        btol=options['btol'],
                                                        conlim=options['conlim'],
                                                        iter_lim=options['iter_lim'],
                                                        show=options['show'])
            assert 0 <= info <= 7
            if info == 7:
                raise InversionError('lsmr failed to converge after {} iterations'.format(itn))
    elif options['type'] == 'pyamg':
        if len(U) > 0:
            U_iter = iter(enumerate(U))
            R[0], ml = pyamg.solve(matrix, next(U_iter)[1],
                                   tol=options['tol'],
                                   maxiter=options['maxiter'],
                                   return_solver=True)
            for i, UU in U_iter:
                R[i] = pyamg.solve(matrix, UU,
                                   tol=options['tol'],
                                   maxiter=options['maxiter'],
                                   existing_solver=ml)
    elif options['type'] == 'pyamg-rs':
        ml = pyamg.ruge_stuben_solver(matrix,
                                      strength=options['strength'],
                                      CF=options['CF'],
                                      presmoother=options['presmoother'],
                                      postsmoother=options['postsmoother'],
                                      max_levels=options['max_levels'],
                                      max_coarse=options['max_coarse'],
                                      coarse_solver=options['coarse_solver'])
        for i, UU in enumerate(U):
            R[i] = ml.solve(UU,
                            tol=options['tol'],
                            maxiter=options['maxiter'],
                            cycle=options['cycle'],
                            accel=options['accel'])
    elif options['type'] == 'pyamg-sa':
        ml = pyamg.smoothed_aggregation_solver(matrix,
                                               symmetry=options['symmetry'],
                                               strength=options['strength'],
                                               aggregate=options['aggregate'],
                                               smooth=options['smooth'],
                                               presmoother=options['presmoother'],
                                               postsmoother=options['postsmoother'],
                                               improve_candidates=options['improve_candidates'],
                                               max_levels=options['max_levels'],
                                               max_coarse=options['max_coarse'],
                                               diagonal_dominance=options['diagonal_dominance'])
        for i, UU in enumerate(U):
            R[i] = ml.solve(UU,
                            tol=options['tol'],
                            maxiter=options['maxiter'],
                            cycle=options['cycle'],
                            accel=options['accel'])
    elif options['type'].startswith('generic') or options['type'].startswith('least_squares_generic'):
        logger = getLogger('pymor.la.numpysolvers.apply_inverse')
        logger.warn('You have selected a (potentially slow) generic solver for a NumPy matrix operator!')
        from pymor.operators.basic import NumpyMatrixOperator
        from pymor.la import NumpyVectorArray
        return genericsolvers.apply_inverse(NumpyMatrixOperator(matrix),
                                            NumpyVectorArray(U, copy=False),
                                            options=options).data
    else:
        raise ValueError('Unknown solver type')
    return R
Пример #8
0
    def apply_inverse(op, V, options=None, least_squares=False, check_finite=True, default_solver='pyamg_solve'):
        """Solve linear equation system.

        Applies the inverse of `op` to the vectors in `rhs` using PyAMG.

        Parameters
        ----------
        op
            The linear, non-parametric |Operator| to invert.
        rhs
            |VectorArray| of right-hand sides for the equation system.
        options
            The |solver_options| to use (see :func:`solver_options`).
        check_finite
            Test if solution only containes finite values.
        default_solver
            Default solver to use (pyamg_solve, pyamg_rs, pyamg_sa).

        Returns
        -------
        |VectorArray| of the solution vectors.
        """

        assert V in op.range

        if isinstance(op, NumpyMatrixOperator):
            matrix = op._matrix
        else:
            from pymor.algorithms.to_matrix import to_matrix
            matrix = to_matrix(op)

        options = _parse_options(options, solver_options(), default_solver, None, least_squares)

        V = V.data
        promoted_type = np.promote_types(matrix.dtype, V.dtype)
        R = np.empty((len(V), matrix.shape[1]), dtype=promoted_type)

        if options['type'] == 'pyamg_solve':
            if len(V) > 0:
                V_iter = iter(enumerate(V))
                R[0], ml = pyamg.solve(matrix, next(V_iter)[1],
                                       tol=options['tol'],
                                       maxiter=options['maxiter'],
                                       return_solver=True)
                for i, VV in V_iter:
                    R[i] = pyamg.solve(matrix, VV,
                                       tol=options['tol'],
                                       maxiter=options['maxiter'],
                                       existing_solver=ml)
        elif options['type'] == 'pyamg_rs':
            ml = pyamg.ruge_stuben_solver(matrix,
                                          strength=options['strength'],
                                          CF=options['CF'],
                                          presmoother=options['presmoother'],
                                          postsmoother=options['postsmoother'],
                                          max_levels=options['max_levels'],
                                          max_coarse=options['max_coarse'],
                                          coarse_solver=options['coarse_solver'])
            for i, VV in enumerate(V):
                R[i] = ml.solve(VV,
                                tol=options['tol'],
                                maxiter=options['maxiter'],
                                cycle=options['cycle'],
                                accel=options['accel'])
        elif options['type'] == 'pyamg_sa':
            ml = pyamg.smoothed_aggregation_solver(matrix,
                                                   symmetry=options['symmetry'],
                                                   strength=options['strength'],
                                                   aggregate=options['aggregate'],
                                                   smooth=options['smooth'],
                                                   presmoother=options['presmoother'],
                                                   postsmoother=options['postsmoother'],
                                                   improve_candidates=options['improve_candidates'],
                                                   max_levels=options['max_levels'],
                                                   max_coarse=options['max_coarse'],
                                                   diagonal_dominance=options['diagonal_dominance'])
            for i, VV in enumerate(V):
                R[i] = ml.solve(VV,
                                tol=options['tol'],
                                maxiter=options['maxiter'],
                                cycle=options['cycle'],
                                accel=options['accel'])
        else:
            raise ValueError('Unknown solver type')

        if check_finite:
            if not np.isfinite(np.sum(R)):
                raise InversionError('Result contains non-finite values')

        return op.source.from_data(R)
Пример #9
0
def diffuse_inprob(inprobs, paths, segs, imgs):
    #inprobs is a list of inside probability for superpixels

    init_prob = []
    id2index = []
    index = 0
    n_last = len(np.unique(segs[-1]))
    for i in range(len(inprobs)):
        id2index.append({})
        for (jj, j) in enumerate(inprobs[i]):
            init_prob.append(j)
            id2index[i][jj] = index
            index += 1

    dist = []
    row_index = []
    col_index = []
    rgbs = np.zeros((len(init_prob), 3))
    n_frames = len(imgs)

    for (i, id) in enumerate(paths.keys()):
        frame = paths[id].frame
        rows = paths[id].rows
        cols = paths[id].cols

        unique_frame = np.unique(frame)

        for f in unique_frame:

            if f == n_frames - 1: continue
            r1 = rows[frame == f]
            c1 = cols[frame == f]
            index1 = id2index[f][segs[f][r1[0], c1[0]]]

            rgb1 = np.mean(imgs[f][r1, c1], axis=0)
            rgbs[index1] = rgb1
            for f2 in unique_frame:
                if f >= f2: continue
                if f2 == n_frames - 1: continue
                r2 = rows[frame == f2]
                c2 = cols[frame == f2]
                rgb2 = np.mean(imgs[f2][r2, c2], axis=0)

                index2 = id2index[f2][segs[f2][r2[0], c2[0]]]
                rgbs[index2] = rgb2

                d = np.linalg.norm(rgb1 - rgb2)**2

                row_index.append(index1)
                row_index.append(index2)
                col_index.append(index2)
                col_index.append(index1)

                dist.append(d)
                dist.append(d)

    adjs = sp_adj(segs)

    for i in range(n_frames - 1):
        for j in range(adjs[i].shape[0]):
            index1 = id2index[i][j]
            rgb1 = rgbs[index1]

            row_index.append(index1)
            col_index.append(index1)
            dist.append(0)

            for k in np.nonzero(adjs[i][j])[0]:

                if j > k: continue
                index2 = id2index[i][k]
                rgb2 = rgbs[index2]

                d = np.linalg.norm(rgb1 - rgb2)**2

                row_index.append(index1)
                row_index.append(index2)
                col_index.append(index2)
                col_index.append(index1)

                dist.append(d)
                dist.append(d)

    sigma = 30
    values2 = np.exp(-np.array(dist) / (2 * sigma**2))

    from scipy.sparse import csr_matrix, spdiags
    n_node = len(init_prob)
    W = csr_matrix((values2, (row_index, col_index)), shape=(n_node, n_node))

    inv_D = spdiags(1.0 / ((W.sum(axis=1)).flatten()), 0, W.shape[0],
                    W.shape[1])
    D = spdiags(W.sum(axis=1).flatten(), 0, W.shape[0], W.shape[1])
    lam = 10
    lhs = D + lam * (D - W)
    from scipy.sparse import eye

    from scipy.sparse.linalg import spsolve, lsmr
    #    diffused_prob = spsolve(lhs, D.dot(np.array(init_prob)))
    diffused_prob = solve(lhs, D.dot(np.array(init_prob)))

    diffused_probs = []

    count = 0
    for i in range(len(inprobs)):
        diffused_probs.append(diffused_prob[count:len(inprobs[i]) + count])
        count += len(inprobs[i])

    return diffused_probs
Пример #10
0
def _apply_inverse(matrix, V, options=None):
    """Solve linear equation system.

    Applies the inverse of `matrix` to the row vectors in `V`.

    See :func:`dense_options` for documentation of all possible options for
    sparse matrices.

    See :func:`sparse_options` for documentation of all possible options for
    sparse matrices.

    This method is called by :meth:`pymor.core.NumpyMatrixOperator.apply_inverse`
    and usually should not be used directly.

    Parameters
    ----------
    matrix
        The |NumPy| matrix to invert.
    V
        2-dimensional |NumPy array| containing as row vectors
        the right-hand sides of the linear equation systems to
        solve.
    options
        The solver options to use. (See :func:`_options`.)

    Returns
    -------
    |NumPy array| of the solution vectors.
    """

    default_options = _options(matrix)

    if options is None:
        options = default_options.values()[0]
    elif isinstance(options, str):
        if options == "least_squares":
            for k, v in default_options.iteritems():
                if k.startswith("least_squares"):
                    options = v
                    break
            assert not isinstance(options, str)
        else:
            options = default_options[options]
    else:
        assert (
            "type" in options
            and options["type"] in default_options
            and options.viewkeys() <= default_options[options["type"]].viewkeys()
        )
        user_options = options
        options = default_options[user_options["type"]]
        options.update(user_options)

    R = np.empty((len(V), matrix.shape[1]), dtype=np.promote_types(matrix.dtype, V.dtype))

    if options["type"] == "solve":
        for i, VV in enumerate(V):
            try:
                R[i] = np.linalg.solve(matrix, VV)
            except np.linalg.LinAlgError as e:
                raise InversionError("{}: {}".format(str(type(e)), str(e)))
    elif options["type"] == "least_squares_lstsq":
        for i, VV in enumerate(V):
            try:
                R[i], _, _, _ = np.linalg.lstsq(matrix, VV, rcond=options["rcond"])
            except np.linalg.LinAlgError as e:
                raise InversionError("{}: {}".format(str(type(e)), str(e)))
    elif options["type"] == "bicgstab":
        for i, VV in enumerate(V):
            R[i], info = bicgstab(matrix, VV, tol=options["tol"], maxiter=options["maxiter"])
            if info != 0:
                if info > 0:
                    raise InversionError("bicgstab failed to converge after {} iterations".format(info))
                else:
                    raise InversionError("bicgstab failed with error code {} (illegal input or breakdown)".format(info))
    elif options["type"] == "bicgstab_spilu":
        ilu = spilu(
            matrix,
            drop_tol=options["spilu_drop_tol"],
            fill_factor=options["spilu_fill_factor"],
            drop_rule=options["spilu_drop_rule"],
            permc_spec=options["spilu_permc_spec"],
        )
        precond = LinearOperator(matrix.shape, ilu.solve)
        for i, VV in enumerate(V):
            R[i], info = bicgstab(matrix, VV, tol=options["tol"], maxiter=options["maxiter"], M=precond)
            if info != 0:
                if info > 0:
                    raise InversionError("bicgstab failed to converge after {} iterations".format(info))
                else:
                    raise InversionError("bicgstab failed with error code {} (illegal input or breakdown)".format(info))
    elif options["type"] == "spsolve":
        try:
            if scipy.version.version >= "0.14":
                if hasattr(matrix, "factorization"):
                    R = matrix.factorization.solve(V.T).T
                elif options["keep_factorization"]:
                    matrix.factorization = splu(matrix, permc_spec=options["permc_spec"])
                    R = matrix.factorization.solve(V.T).T
                else:
                    R = spsolve(matrix, V.T, permc_spec=options["permc_spec"]).T
            else:
                if hasattr(matrix, "factorization"):
                    for i, VV in enumerate(V):
                        R[i] = matrix.factorization.solve(VV)
                elif options["keep_factorization"]:
                    matrix.factorization = splu(matrix, permc_spec=options["permc_spec"])
                    for i, VV in enumerate(V):
                        R[i] = matrix.factorization.solve(VV)
                elif len(V) > 1:
                    factorization = splu(matrix, permc_spec=options["permc_spec"])
                    for i, VV in enumerate(V):
                        R[i] = factorization.solve(VV)
                else:
                    R = spsolve(matrix, V.T, permc_spec=options["permc_spec"]).reshape((1, -1))
        except RuntimeError as e:
            raise InversionError(e)
    elif options["type"] == "lgmres":
        for i, VV in enumerate(V):
            R[i], info = lgmres(
                matrix,
                VV.copy(i),
                tol=options["tol"],
                maxiter=options["maxiter"],
                inner_m=options["inner_m"],
                outer_k=options["outer_k"],
            )
            if info > 0:
                raise InversionError("lgmres failed to converge after {} iterations".format(info))
            assert info == 0
    elif options["type"] == "least_squares_lsmr":
        for i, VV in enumerate(V):
            R[i], info, itn, _, _, _, _, _ = lsmr(
                matrix,
                VV.copy(i),
                damp=options["damp"],
                atol=options["atol"],
                btol=options["btol"],
                conlim=options["conlim"],
                maxiter=options["maxiter"],
                show=options["show"],
            )
            assert 0 <= info <= 7
            if info == 7:
                raise InversionError("lsmr failed to converge after {} iterations".format(itn))
    elif options["type"] == "least_squares_lsqr":
        for i, VV in enumerate(V):
            R[i], info, itn, _, _, _, _, _, _, _ = lsqr(
                matrix,
                VV.copy(i),
                damp=options["damp"],
                atol=options["atol"],
                btol=options["btol"],
                conlim=options["conlim"],
                iter_lim=options["iter_lim"],
                show=options["show"],
            )
            assert 0 <= info <= 7
            if info == 7:
                raise InversionError("lsmr failed to converge after {} iterations".format(itn))
    elif options["type"] == "pyamg":
        if len(V) > 0:
            V_iter = iter(enumerate(V))
            R[0], ml = pyamg.solve(
                matrix, next(V_iter)[1], tol=options["tol"], maxiter=options["maxiter"], return_solver=True
            )
            for i, VV in V_iter:
                R[i] = pyamg.solve(matrix, VV, tol=options["tol"], maxiter=options["maxiter"], existing_solver=ml)
    elif options["type"] == "pyamg-rs":
        ml = pyamg.ruge_stuben_solver(
            matrix,
            strength=options["strength"],
            CF=options["CF"],
            presmoother=options["presmoother"],
            postsmoother=options["postsmoother"],
            max_levels=options["max_levels"],
            max_coarse=options["max_coarse"],
            coarse_solver=options["coarse_solver"],
        )
        for i, VV in enumerate(V):
            R[i] = ml.solve(
                VV, tol=options["tol"], maxiter=options["maxiter"], cycle=options["cycle"], accel=options["accel"]
            )
    elif options["type"] == "pyamg-sa":
        ml = pyamg.smoothed_aggregation_solver(
            matrix,
            symmetry=options["symmetry"],
            strength=options["strength"],
            aggregate=options["aggregate"],
            smooth=options["smooth"],
            presmoother=options["presmoother"],
            postsmoother=options["postsmoother"],
            improve_candidates=options["improve_candidates"],
            max_levels=options["max_levels"],
            max_coarse=options["max_coarse"],
            diagonal_dominance=options["diagonal_dominance"],
        )
        for i, VV in enumerate(V):
            R[i] = ml.solve(
                VV, tol=options["tol"], maxiter=options["maxiter"], cycle=options["cycle"], accel=options["accel"]
            )
    elif options["type"].startswith("generic") or options["type"].startswith("least_squares_generic"):
        logger = getLogger("pymor.operators.numpy._apply_inverse")
        logger.warn("You have selected a (potentially slow) generic solver for a NumPy matrix operator!")
        from pymor.operators.numpy import NumpyMatrixOperator
        from pymor.vectorarrays.numpy import NumpyVectorArray

        return genericsolvers.apply_inverse(
            NumpyMatrixOperator(matrix), NumpyVectorArray(V, copy=False), options=options
        ).data
    else:
        raise ValueError("Unknown solver type")
    return R
Пример #11
0
def blend(img_target, img_source, img_mask, offset, center):
    # compute regions to be blended
    # clip and normalize mask image
    # create coefficient matrix
    if (img_target.shape != img_source.shape):
        img_source = cv2.resize(img_source,
                                (img_target.shape[1], img_target.shape[0]))
        img_mask = cv2.resize(img_mask,
                              (img_target.shape[1], img_target.shape[0]))
    img_source = np.roll(img_source, offset[1], axis=0)
    img_source = np.roll(img_source, offset[0], axis=1)
    img_mask = np.roll(img_mask, offset[1], axis=0)
    img_mask = np.roll(img_mask, offset[0], axis=1)
    img_mask = rgb2gray(img_mask)
    zeros = np.nonzero(img_mask)
    sizeofzero = zeros[0].shape[0] / img_mask.shape[
        0]  #ratio of white to black features
    erosion = int(sizeofzero * (80 / 120))
    SE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,
                                   (erosion + 50, erosion + 50))
    if (erosion - 40 < 0):
        SE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,
                                       (erosion + 35, erosion + 35))
        SE2 = cv2.getStructuringElement(cv2.MORPH_RECT,
                                        (erosion + 9, erosion + 9))
    else:
        SE2 = cv2.getStructuringElement(cv2.MORPH_RECT,
                                        (erosion - 30, erosion - 5))
    #img_mask[0:int(center[0]),::]=binary_erosion(img_mask[0:int(center[0]),::],SE)
    #img_mask[int(center[0]):img_mask.shape[0],::]=binary_erosion( img_mask[int(center[0]):img_mask.shape[0],::],SE2)
    img_mask = binary_erosion(img_mask, SE)
    img_mask = binary_dilation(img_mask, SE2)
    show_images([img_mask])
    #img_mask=binary_dilation(img_mask,SE1)
    #SE=np.ones(())
    A = scipy.sparse.identity(img_mask.shape[0] * img_mask.shape[1],
                              format='lil')
    for j in range(img_mask.shape[0]):
        for i in range(img_mask.shape[1]):
            if img_mask[j][i] != 0:
                index = i + j * img_mask.shape[1]
                A[index, index] = 4
                if index + 1 < (img_mask.shape[0] * img_mask.shape[1]):
                    A[index, index + 1] = -1
                if index - 1 >= 0:
                    A[index, index - 1] = -1
                if index + img_mask.shape[
                        1] < img_mask.shape[0] * img_mask.shape[1]:
                    A[index, index + img_mask.shape[1]] = -1
                if index - img_mask.shape[1] >= 0:
                    A[index, index - img_mask.shape[1]] = -1
    A = A.tocsr()

    # create poisson matrix for b
    P = pyamg.gallery.poisson(img_mask.shape)

    # for each layer (ex. RGB)
    for RGB in range(3):
        # get subimages
        t = img_target[:, :, RGB]
        s = img_source[:, :, RGB]
        t = t.flatten()
        s = s.flatten()
        # create b
        b = P * s
        laplace = np.abs(np.reshape(b, img_mask.shape))
        F2 = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
        filter1 = np.abs(convolve2d(in1=img_source[:, :, RGB], in2=F2))
        show_images([laplace, filter1], ["poisson", "LOG"])

        for y in range(img_mask.shape[0]):
            for x in range(img_mask.shape[1]):
                if img_mask[y][x] == 0:
                    index = x + y * img_mask.shape[1]
                    b[index] = t[index]

        # solve Ax = b
        x = pyamg.solve(A, b, verb=False, tol=1e-10)
        # assign x to target image
        x = np.reshape(x, img_mask.shape)
        x[x > 255] = 255
        x[x < 0] = 0
        x = np.array(x, img_target.dtype)
        img_target[:, :, RGB] = x
    return img_target
Пример #12
0
def _apply_inverse(matrix, V, options=None):
    """Solve linear equation system.

    Applies the inverse of `matrix` to the row vectors in `V`.

    See :func:`dense_options` for documentation of all possible options for
    sparse matrices.

    See :func:`sparse_options` for documentation of all possible options for
    sparse matrices.

    This method is called by :meth:`pymor.core.NumpyMatrixOperator.apply_inverse`
    and usually should not be used directly.

    Parameters
    ----------
    matrix
        The |NumPy| matrix to invert.
    V
        2-dimensional |NumPy array| containing as row vectors
        the right-hand sides of the linear equation systems to
        solve.
    options
        The solver options to use. (See :func:`_options`.)

    Returns
    -------
    |NumPy array| of the solution vectors.
    """

    default_options = _options(matrix)

    if options is None:
        options = next(iter(default_options.values()))
    elif isinstance(options, str):
        if options == 'least_squares':
            for k, v in default_options.items():
                if k.startswith('least_squares'):
                    options = v
                    break
            assert not isinstance(options, str)
        else:
            options = default_options[options]
    else:
        assert 'type' in options and options['type'] in default_options \
            and options.keys() <= default_options[options['type']].keys()
        user_options = options
        options = default_options[user_options['type']]
        options.update(user_options)

    promoted_type = np.promote_types(matrix.dtype, V.dtype)
    R = np.empty((len(V), matrix.shape[1]), dtype=promoted_type)

    if options['type'] == 'solve':
        for i, VV in enumerate(V):
            try:
                R[i] = np.linalg.solve(matrix, VV)
            except np.linalg.LinAlgError as e:
                raise InversionError('{}: {}'.format(str(type(e)), str(e)))
    elif options['type'] == 'least_squares_lstsq':
        for i, VV in enumerate(V):
            try:
                R[i], _, _, _ = np.linalg.lstsq(matrix,
                                                VV,
                                                rcond=options['rcond'])
            except np.linalg.LinAlgError as e:
                raise InversionError('{}: {}'.format(str(type(e)), str(e)))
    elif options['type'] == 'bicgstab':
        for i, VV in enumerate(V):
            R[i], info = bicgstab(matrix,
                                  VV,
                                  tol=options['tol'],
                                  maxiter=options['maxiter'])
            if info != 0:
                if info > 0:
                    raise InversionError(
                        'bicgstab failed to converge after {} iterations'.
                        format(info))
                else:
                    raise InversionError(
                        'bicgstab failed with error code {} (illegal input or breakdown)'
                        .format(info))
    elif options['type'] == 'bicgstab_spilu':
        # workaround for https://github.com/pymor/pymor/issues/171
        try:
            ilu = spilu(matrix,
                        drop_tol=options['spilu_drop_tol'],
                        fill_factor=options['spilu_fill_factor'],
                        drop_rule=options['spilu_drop_rule'],
                        permc_spec=options['spilu_permc_spec'])
        except TypeError as t:
            logger = getLogger('pymor.operators.numpy._apply_inverse')
            logger.error("ignoring drop_rule in ilu factorization")
            ilu = spilu(matrix,
                        drop_tol=options['spilu_drop_tol'],
                        fill_factor=options['spilu_fill_factor'],
                        permc_spec=options['spilu_permc_spec'])
        precond = LinearOperator(matrix.shape, ilu.solve)
        for i, VV in enumerate(V):
            R[i], info = bicgstab(matrix,
                                  VV,
                                  tol=options['tol'],
                                  maxiter=options['maxiter'],
                                  M=precond)
            if info != 0:
                if info > 0:
                    raise InversionError(
                        'bicgstab failed to converge after {} iterations'.
                        format(info))
                else:
                    raise InversionError(
                        'bicgstab failed with error code {} (illegal input or breakdown)'
                        .format(info))
    elif options['type'] == 'spsolve':
        try:
            # maybe remove unusable factorization:
            if hasattr(matrix, 'factorization'):
                fdtype = matrix.factorizationdtype
                if not np.can_cast(V.dtype, fdtype, casting='safe'):
                    del matrix.factorization

            if list(map(int, scipy.version.version.split('.'))) >= [0, 14, 0]:
                if hasattr(matrix, 'factorization'):
                    # we may use a complex factorization of a real matrix to
                    # apply it to a real vector. In that case, we downcast
                    # the result here, removing the imaginary part,
                    # which should be zero.
                    R = matrix.factorization.solve(V.T).T.astype(promoted_type,
                                                                 copy=False)
                elif options['keep_factorization']:
                    # the matrix is always converted to the promoted type.
                    # if matrix.dtype == promoted_type, this is a no_op
                    matrix.factorization = splu(
                        matrix_astype_nocopy(matrix, promoted_type),
                        permc_spec=options['permc_spec'])
                    matrix.factorizationdtype = promoted_type
                    R = matrix.factorization.solve(V.T).T
                else:
                    # the matrix is always converted to the promoted type.
                    # if matrix.dtype == promoted_type, this is a no_op
                    R = spsolve(matrix_astype_nocopy(matrix, promoted_type),
                                V.T,
                                permc_spec=options['permc_spec']).T
            else:
                # see if-part for documentation
                if hasattr(matrix, 'factorization'):
                    for i, VV in enumerate(V):
                        R[i] = matrix.factorization.solve(VV).astype(
                            promoted_type, copy=False)
                elif options['keep_factorization']:
                    matrix.factorization = splu(
                        matrix_astype_nocopy(matrix, promoted_type),
                        permc_spec=options['permc_spec'])
                    matrix.factorizationdtype = promoted_type
                    for i, VV in enumerate(V):
                        R[i] = matrix.factorization.solve(VV)
                elif len(V) > 1:
                    factorization = splu(matrix_astype_nocopy(
                        matrix, promoted_type),
                                         permc_spec=options['permc_spec'])
                    for i, VV in enumerate(V):
                        R[i] = factorization.solve(VV)
                else:
                    R = spsolve(matrix_astype_nocopy(matrix, promoted_type),
                                V.T,
                                permc_spec=options['permc_spec']).reshape(
                                    (1, -1))
        except RuntimeError as e:
            raise InversionError(e)
    elif options['type'] == 'lgmres':
        for i, VV in enumerate(V):
            R[i], info = lgmres(matrix,
                                VV.copy(i),
                                tol=options['tol'],
                                maxiter=options['maxiter'],
                                inner_m=options['inner_m'],
                                outer_k=options['outer_k'])
            if info > 0:
                raise InversionError(
                    'lgmres failed to converge after {} iterations'.format(
                        info))
            assert info == 0
    elif options['type'] == 'least_squares_lsmr':
        for i, VV in enumerate(V):
            R[i], info, itn, _, _, _, _, _ = lsmr(matrix,
                                                  VV.copy(i),
                                                  damp=options['damp'],
                                                  atol=options['atol'],
                                                  btol=options['btol'],
                                                  conlim=options['conlim'],
                                                  maxiter=options['maxiter'],
                                                  show=options['show'])
            assert 0 <= info <= 7
            if info == 7:
                raise InversionError(
                    'lsmr failed to converge after {} iterations'.format(itn))
    elif options['type'] == 'least_squares_lsqr':
        for i, VV in enumerate(V):
            R[i], info, itn, _, _, _, _, _, _, _ = lsqr(
                matrix,
                VV.copy(i),
                damp=options['damp'],
                atol=options['atol'],
                btol=options['btol'],
                conlim=options['conlim'],
                iter_lim=options['iter_lim'],
                show=options['show'])
            assert 0 <= info <= 7
            if info == 7:
                raise InversionError(
                    'lsmr failed to converge after {} iterations'.format(itn))
    elif options['type'] == 'pyamg':
        if len(V) > 0:
            V_iter = iter(enumerate(V))
            R[0], ml = pyamg.solve(matrix,
                                   next(V_iter)[1],
                                   tol=options['tol'],
                                   maxiter=options['maxiter'],
                                   return_solver=True)
            for i, VV in V_iter:
                R[i] = pyamg.solve(matrix,
                                   VV,
                                   tol=options['tol'],
                                   maxiter=options['maxiter'],
                                   existing_solver=ml)
    elif options['type'] == 'pyamg-rs':
        ml = pyamg.ruge_stuben_solver(matrix,
                                      strength=options['strength'],
                                      CF=options['CF'],
                                      presmoother=options['presmoother'],
                                      postsmoother=options['postsmoother'],
                                      max_levels=options['max_levels'],
                                      max_coarse=options['max_coarse'],
                                      coarse_solver=options['coarse_solver'])
        for i, VV in enumerate(V):
            R[i] = ml.solve(VV,
                            tol=options['tol'],
                            maxiter=options['maxiter'],
                            cycle=options['cycle'],
                            accel=options['accel'])
    elif options['type'] == 'pyamg-sa':
        ml = pyamg.smoothed_aggregation_solver(
            matrix,
            symmetry=options['symmetry'],
            strength=options['strength'],
            aggregate=options['aggregate'],
            smooth=options['smooth'],
            presmoother=options['presmoother'],
            postsmoother=options['postsmoother'],
            improve_candidates=options['improve_candidates'],
            max_levels=options['max_levels'],
            max_coarse=options['max_coarse'],
            diagonal_dominance=options['diagonal_dominance'])
        for i, VV in enumerate(V):
            R[i] = ml.solve(VV,
                            tol=options['tol'],
                            maxiter=options['maxiter'],
                            cycle=options['cycle'],
                            accel=options['accel'])
    elif options['type'].startswith('generic') or options['type'].startswith(
            'least_squares_generic'):
        logger = getLogger('pymor.operators.numpy._apply_inverse')
        logger.warn(
            'You have selected a (potentially slow) generic solver for a NumPy matrix operator!'
        )
        from pymor.operators.numpy import NumpyMatrixOperator
        from pymor.vectorarrays.numpy import NumpyVectorArray
        return genericsolvers.apply_inverse(NumpyMatrixOperator(matrix),
                                            NumpyVectorArray(V, copy=False),
                                            options=options).data
    else:
        raise ValueError('Unknown solver type')
    return R
Пример #13
0
def poisson_blend(img_source, dest_img, img_mask, offset=(0, 0)):
  # http://opencv.jp/opencv2-x-samples/poisson-blending
  img_target = np.copy(dest_img)
  import pyamg
  # compute regions to be blended
  region_source = (
    max(-offset[0], 0),
    max(-offset[1], 0),
    min(img_target.shape[0] - offset[0], img_source.shape[0]),
    min(img_target.shape[1] - offset[1], img_source.shape[1]))
  region_target = (
    max(offset[0], 0),
    max(offset[1], 0),
    min(img_target.shape[0], img_source.shape[0] + offset[0]),
    min(img_target.shape[1], img_source.shape[1] + offset[1]))
  region_size = (region_source[2] - region_source[0],
                 region_source[3] - region_source[1])

  # clip and normalize mask image
  img_mask = img_mask[region_source[0]:region_source[2],
                      region_source[1]:region_source[3]]

  # create coefficient matrix
  coff_mat = scipy.sparse.identity(np.prod(region_size), format='lil')
  for y in range(region_size[0]):
    for x in range(region_size[1]):
      if img_mask[y, x]:
        index = x + y * region_size[1]
        coff_mat[index, index] = 4
        if index + 1 < np.prod(region_size):
          coff_mat[index, index + 1] = -1
        if index - 1 >= 0:
          coff_mat[index, index - 1] = -1
        if index + region_size[1] < np.prod(region_size):
          coff_mat[index, index + region_size[1]] = -1
        if index - region_size[1] >= 0:
          coff_mat[index, index - region_size[1]] = -1
  coff_mat = coff_mat.tocsr()

  # create poisson matrix for b
  poisson_mat = pyamg.gallery.poisson(img_mask.shape)
  # for each layer (ex. RGB)
  for num_layer in range(img_target.shape[2]):
    # get subimages
    t = img_target[region_target[0]:region_target[2],
                   region_target[1]:region_target[3], num_layer]
    s = img_source[region_source[0]:region_source[2],
                   region_source[1]:region_source[3], num_layer]
    t = t.flatten()
    s = s.flatten()

    # create b
    b = poisson_mat * s
    for y in range(region_size[0]):
      for x in range(region_size[1]):
        if not img_mask[y, x]:
          index = x + y * region_size[1]
          b[index] = t[index]

    # solve Ax = b
    x = pyamg.solve(coff_mat, b, verb=False, tol=1e-10)

    # assign x to target image
    x = np.reshape(x, region_size)
    x[x > 255] = 255
    x[x < 0] = 0
    x = np.array(x, img_target.dtype)
    img_target[region_target[0]:region_target[2],
               region_target[1]:region_target[3], num_layer] = x

  return img_target
Пример #14
0
def blend(img_target, img_source, img_mask, offset=(0, 0), mode=0):
    # modes:
    #	0 — standard
    #	1 — mixing
    #	2 — average
    # compute regions to be blended
    region_source = (max(-offset[0], 0), max(-offset[1], 0),
                     min(img_target.shape[0] - offset[0], img_source.shape[0]),
                     min(img_target.shape[1] - offset[1], img_source.shape[1]))
    region_target = (max(offset[0], 0), max(offset[1], 0),
                     min(img_target.shape[0], img_source.shape[0] + offset[0]),
                     min(img_target.shape[1], img_source.shape[1] + offset[1]))
    region_size = (region_source[2] - region_source[0],
                   region_source[3] - region_source[1])

    # clip and normalize mask image
    img_mask = img_mask[region_source[0]:region_source[2],
                        region_source[1]:region_source[3]]

    img_mask = prepare_mask(img_mask)
    #img_mask[img_mask==0] = False
    #img_mask[img_mask!=False] = True

    # create coefficient matrix
    A = scipy.sparse.identity(np.prod(region_size), format='lil')
    for y in range(region_size[0]):
        for x in range(region_size[1]):
            if img_mask[y, x] != 0:
                index = x + y * region_size[1]
                Np = 0
                if index + 1 < np.prod(region_size):
                    A[index, index + 1] = -1
                    Np += 1
                if index - 1 >= 0:
                    A[index, index - 1] = -1
                    Np += 1
                if index + region_size[1] < np.prod(region_size):
                    A[index, index + region_size[1]] = -1
                    Np += 1
                if index - region_size[1] >= 0:
                    A[index, index - region_size[1]] = -1
                    Np += 1
                A[index, index] = Np
    A = A.tocsr()

    # create poisson matrix for b
    P = pyamg.gallery.poisson(img_mask.shape)

    # for each layer (ex. RGB)
    N = 1 if len(img_target.shape) < 3 else img_target.shape[2]

    for num_layer in range(N):
        # get subimages
        if N == 1:
            tar = img_target[region_target[0]:region_target[2],
                             region_target[1]:region_target[3]]
            sour = img_source[region_source[0]:region_source[2],
                              region_source[1]:region_source[3]]
        else:
            tar = img_target[region_target[0]:region_target[2],
                             region_target[1]:region_target[3], num_layer]
            sour = img_source[region_source[0]:region_source[2],
                              region_source[1]:region_source[3], num_layer]
        t = tar.flatten()
        s = sour.flatten()

        # create b

        B = P * s
        for y in range(region_size[0]):
            for x in range(region_size[1]):
                if img_mask[y, x] == 0:
                    index = x + y * region_size[1]
                    #B[index] = t[index]

        #b = scipy.sparse.lil_matrix((np.prod(region_size)))
        b = np.zeros(np.prod(region_size))
        for y in range(region_size[0]):
            for x in range(region_size[1]):
                index = x + y * region_size[1]
                if img_mask[y, x] != 0:
                    sum = 0
                    neighbors = [[1, 0], [0, 1], [0, -1], [-1, 0]]
                    checkIfOutOfRange = lambda ind: ind[0] >= 0 and ind[
                        1] >= 0 and ind[0] < region_size[0] and ind[
                            1] < region_size[1]
                    for nb in neighbors:
                        p2 = tuple(np.array([y, x]) + np.array(nb))
                        if checkIfOutOfRange(p2) and img_mask[p2] != 0:
                            s1 = int(sour[y, x]) - int(sour[p2])
                            s2 = int(tar[y, x]) - int(tar[p2])
                            if mode == 0:  #standard
                                sum += s1
                            elif mode == 1:  #mixing
                                sum += s1 if abs(s1) >= abs(s2) else s2
                            elif mode == 2:  #average
                                sum += (1.0 * (s1 + s2)) / 2
                            elif mode == -1:
                                pass
                    b[index] = sum
                else:
                    pass
                    b[index] = t[index]

        # solve Ax = b
        x = pyamg.solve(A, b, verb=False, tol=1e-10)
        #print time.time() - start
        #print region_target
        #x = seidel(A,b, 1e-10)

        # assign x to target image
        x = np.reshape(x, region_size)
        x[x > 255] = 255
        x[x < 0] = 0
        x = np.array(x, img_target.dtype)
        #print x.shape
        if N == 1:
            img_target[region_target[0]:region_target[2],
                       region_target[1]:region_target[3]] = x
        else:
            img_target[region_target[0]:region_target[2],
                       region_target[1]:region_target[3], num_layer] = x

    return img_target
Пример #15
0
def poisson_blend(img_source, dest_img, img_mask, offset=(0, 0)):
    # http://opencv.jp/opencv2-x-samples/poisson-blending
    img_target = np.copy(dest_img)
    import pyamg
    # compute regions to be blended
    region_source = (max(-offset[0], 0), max(-offset[1], 0),
                     min(img_target.shape[0] - offset[0], img_source.shape[0]),
                     min(img_target.shape[1] - offset[1], img_source.shape[1]))
    region_target = (max(offset[0], 0), max(offset[1], 0),
                     min(img_target.shape[0], img_source.shape[0] + offset[0]),
                     min(img_target.shape[1], img_source.shape[1] + offset[1]))
    region_size = (region_source[2] - region_source[0],
                   region_source[3] - region_source[1])

    # clip and normalize mask image
    img_mask = img_mask[region_source[0]:region_source[2],
                        region_source[1]:region_source[3]]

    # create coefficient matrix
    coff_mat = scipy.sparse.identity(np.prod(region_size), format='lil')
    for y in range(region_size[0]):
        for x in range(region_size[1]):
            if img_mask[y, x]:
                index = x + y * region_size[1]
                coff_mat[index, index] = 4
                if index + 1 < np.prod(region_size):
                    coff_mat[index, index + 1] = -1
                if index - 1 >= 0:
                    coff_mat[index, index - 1] = -1
                if index + region_size[1] < np.prod(region_size):
                    coff_mat[index, index + region_size[1]] = -1
                if index - region_size[1] >= 0:
                    coff_mat[index, index - region_size[1]] = -1
    coff_mat = coff_mat.tocsr()

    # create poisson matrix for b
    poisson_mat = pyamg.gallery.poisson(img_mask.shape)
    # for each layer (ex. RGB)
    for num_layer in range(img_target.shape[2]):
        # get subimages
        t = img_target[region_target[0]:region_target[2],
                       region_target[1]:region_target[3], num_layer]
        s = img_source[region_source[0]:region_source[2],
                       region_source[1]:region_source[3], num_layer]
        t = t.flatten()
        s = s.flatten()

        # create b
        b = poisson_mat * s
        for y in range(region_size[0]):
            for x in range(region_size[1]):
                if not img_mask[y, x]:
                    index = x + y * region_size[1]
                    b[index] = t[index]

        # solve Ax = b
        x = pyamg.solve(coff_mat, b, verb=False, tol=1e-10)

        # assign x to target image
        x = np.reshape(x, region_size)
        x[x > 255] = 255
        x[x < 0] = 0
        x = np.array(x, img_target.dtype)
        img_target[region_target[0]:region_target[2],
                   region_target[1]:region_target[3], num_layer] = x

    return img_target
Пример #16
0
def blend(img_target, img_source, img_mask, offset=(0, 0)):
    # compute regions to be blended
    region_source = (max(-offset[0], 0), max(-offset[1], 0),
                     min(img_target.shape[0] - offset[0], img_source.shape[0]),
                     min(img_target.shape[1] - offset[1], img_source.shape[1]))
    region_target = (max(offset[0], 0), max(offset[1], 0),
                     min(img_target.shape[0], img_source.shape[0] + offset[0]),
                     min(img_target.shape[1], img_source.shape[1] + offset[1]))
    region_size = (region_source[2] - region_source[0],
                   region_source[3] - region_source[1])

    # clip and normalize mask image
    img_mask = img_mask[region_source[0]:region_source[2],
                        region_source[1]:region_source[3]]
    img_mask = prepare_mask(img_mask)
    img_mask[img_mask == 0] = False
    img_mask[img_mask != False] = True

    # create coefficient matrix
    A = scipy.sparse.identity(np.prod(region_size), format='lil')
    for y in range(region_size[0]):
        for x in range(region_size[1]):
            if img_mask[y, x]:
                index = x + y * region_size[1]
                A[index, index] = 4
                if index + 1 < np.prod(region_size):
                    A[index, index + 1] = -1
                if index - 1 >= 0:
                    A[index, index - 1] = -1
                if index + region_size[1] < np.prod(region_size):
                    A[index, index + region_size[1]] = -1
                if index - region_size[1] >= 0:
                    A[index, index - region_size[1]] = -1
    A = A.tocsr()

    # create poisson matrix for b
    P = pyamg.gallery.poisson(img_mask.shape)

    # for each layer (ex. RGB)
    for num_layer in range(img_target.shape[2]):
        # get subimages
        t = img_target[region_target[0]:region_target[2],
                       region_target[1]:region_target[3], num_layer]
        s = img_source[region_source[0]:region_source[2],
                       region_source[1]:region_source[3], num_layer]
        t = t.flatten()
        s = s.flatten()

        # create b
        b = P * s
        for y in range(region_size[0]):
            for x in range(region_size[1]):
                if not img_mask[y, x]:
                    index = x + y * region_size[1]
                    b[index] = t[index]

        # solve Ax = b
        x = pyamg.solve(A, b, verb=False, tol=1e-10)

        # assign x to target image
        x = np.reshape(x, region_size)
        x[x > 255] = 255
        x[x < 0] = 0
        x = np.array(x, img_target.dtype)
        img_target[region_target[0]:region_target[2],
                   region_target[1]:region_target[3], num_layer] = x

    return img_target
Пример #17
0
handle an arbitrary matrix.

"""

from scipy import rand
from numpy import arange, array           
from pyamg import solve               
from pyamg.gallery import poisson         
from pyamg.util.linalg import norm        

if __name__ == '__main__':

    ##
    # Run solve(...) with the verbose option
    n = 100
    A = poisson((n,n),format='csr')         
    b = array(arange(A.shape[0]), dtype=float)
    print ""
    x = solve(A,b,verb=True)
    
    ##
    # Return the solver generated by solve(...) so that it can be used again
    print ""
    (x,ml) = solve(A,b,verb=True,return_solver=True,tol=1e-8)               
    # run for a new right-hand-side
    b2 = rand(b.shape[0],)
    print ""
    x2 = solve(A,b2,verb=True,existing_solver=ml,tol=1e-8)
    print ""

Пример #18
0
def _apply_inverse(matrix, V, options=None):
    """Solve linear equation system.

    Applies the inverse of `matrix` to the row vectors in `V`.

    See :func:`dense_options` for documentation of all possible options for
    sparse matrices.

    See :func:`sparse_options` for documentation of all possible options for
    sparse matrices.

    This method is called by :meth:`pymor.core.NumpyMatrixOperator.apply_inverse`
    and usually should not be used directly.

    Parameters
    ----------
    matrix
        The |NumPy| matrix to invert.
    V
        2-dimensional |NumPy array| containing as row vectors
        the right-hand sides of the linear equation systems to
        solve.
    options
        The solver options to use. (See :func:`_options`.)

    Returns
    -------
    |NumPy array| of the solution vectors.
    """

    default_options = _options(matrix)

    if options is None:
        options = default_options.values()[0]
    elif isinstance(options, str):
        if options == 'least_squares':
            for k, v in default_options.iteritems():
                if k.startswith('least_squares'):
                    options = v
                    break
            assert not isinstance(options, str)
        else:
            options = default_options[options]
    else:
        assert 'type' in options and options['type'] in default_options \
            and options.viewkeys() <= default_options[options['type']].viewkeys()
        user_options = options
        options = default_options[user_options['type']]
        options.update(user_options)

    promoted_type = np.promote_types(matrix.dtype, V.dtype)
    R = np.empty((len(V), matrix.shape[1]), dtype=promoted_type)

    if options['type'] == 'solve':
        for i, VV in enumerate(V):
            try:
                R[i] = np.linalg.solve(matrix, VV)
            except np.linalg.LinAlgError as e:
                raise InversionError('{}: {}'.format(str(type(e)), str(e)))
    elif options['type'] == 'least_squares_lstsq':
        for i, VV in enumerate(V):
            try:
                R[i], _, _, _ = np.linalg.lstsq(matrix, VV, rcond=options['rcond'])
            except np.linalg.LinAlgError as e:
                raise InversionError('{}: {}'.format(str(type(e)), str(e)))
    elif options['type'] == 'bicgstab':
        for i, VV in enumerate(V):
            R[i], info = bicgstab(matrix, VV, tol=options['tol'], maxiter=options['maxiter'])
            if info != 0:
                if info > 0:
                    raise InversionError('bicgstab failed to converge after {} iterations'.format(info))
                else:
                    raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'.
                                         format(info))
    elif options['type'] == 'bicgstab_spilu':
        ilu = spilu(matrix, drop_tol=options['spilu_drop_tol'], fill_factor=options['spilu_fill_factor'],
                    drop_rule=options['spilu_drop_rule'], permc_spec=options['spilu_permc_spec'])
        precond = LinearOperator(matrix.shape, ilu.solve)
        for i, VV in enumerate(V):
            R[i], info = bicgstab(matrix, VV, tol=options['tol'], maxiter=options['maxiter'], M=precond)
            if info != 0:
                if info > 0:
                    raise InversionError('bicgstab failed to converge after {} iterations'.format(info))
                else:
                    raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'.
                                         format(info))
    elif options['type'] == 'spsolve':
        try:
            # maybe remove unusable factorization:
            if hasattr(matrix, 'factorization'):
                fdtype = matrix.factorizationdtype
                if not np.can_cast(V.dtype, fdtype, casting='safe'):
                    del matrix.factorization

            if map(int, scipy.version.version.split('.')) >= [0, 14, 0]:
                if hasattr(matrix, 'factorization'):
                    # we may use a complex factorization of a real matrix to
                    # apply it to a real vector. In that case, we downcast
                    # the result here, removing the imaginary part,
                    # which should be zero.
                    R = matrix.factorization.solve(V.T).T.astype(promoted_type, copy=False)
                elif options['keep_factorization']:
                    # the matrix is always converted to the promoted type.
                    # if matrix.dtype == promoted_type, this is a no_op
                    matrix.factorization = splu(matrix_astype_nocopy(matrix, promoted_type), permc_spec=options['permc_spec'])
                    matrix.factorizationdtype = promoted_type
                    R = matrix.factorization.solve(V.T).T
                else:
                    # the matrix is always converted to the promoted type.
                    # if matrix.dtype == promoted_type, this is a no_op
                    R = spsolve(matrix_astype_nocopy(matrix, promoted_type), V.T, permc_spec=options['permc_spec']).T
            else:
                # see if-part for documentation
                if hasattr(matrix, 'factorization'):
                    for i, VV in enumerate(V):
                        R[i] = matrix.factorization.solve(VV).astype(promoted_type, copy=False)
                elif options['keep_factorization']:
                    matrix.factorization = splu(matrix_astype_nocopy(matrix, promoted_type), permc_spec=options['permc_spec'])
                    matrix.factorizationdtype = promoted_type
                    for i, VV in enumerate(V):
                        R[i] = matrix.factorization.solve(VV)
                elif len(V) > 1:
                    factorization = splu(matrix_astype_nocopy(matrix, promoted_type), permc_spec=options['permc_spec'])
                    for i, VV in enumerate(V):
                        R[i] = factorization.solve(VV)
                else:
                    R = spsolve(matrix_astype_nocopy(matrix, promoted_type), V.T, permc_spec=options['permc_spec']).reshape((1, -1))
        except RuntimeError as e:
            raise InversionError(e)
    elif options['type'] == 'lgmres':
        for i, VV in enumerate(V):
            R[i], info = lgmres(matrix, VV.copy(i),
                                tol=options['tol'],
                                maxiter=options['maxiter'],
                                inner_m=options['inner_m'],
                                outer_k=options['outer_k'])
            if info > 0:
                raise InversionError('lgmres failed to converge after {} iterations'.format(info))
            assert info == 0
    elif options['type'] == 'least_squares_lsmr':
        for i, VV in enumerate(V):
            R[i], info, itn, _, _, _, _, _ = lsmr(matrix, VV.copy(i),
                                                  damp=options['damp'],
                                                  atol=options['atol'],
                                                  btol=options['btol'],
                                                  conlim=options['conlim'],
                                                  maxiter=options['maxiter'],
                                                  show=options['show'])
            assert 0 <= info <= 7
            if info == 7:
                raise InversionError('lsmr failed to converge after {} iterations'.format(itn))
    elif options['type'] == 'least_squares_lsqr':
        for i, VV in enumerate(V):
            R[i], info, itn, _, _, _, _, _, _, _ = lsqr(matrix, VV.copy(i),
                                                        damp=options['damp'],
                                                        atol=options['atol'],
                                                        btol=options['btol'],
                                                        conlim=options['conlim'],
                                                        iter_lim=options['iter_lim'],
                                                        show=options['show'])
            assert 0 <= info <= 7
            if info == 7:
                raise InversionError('lsmr failed to converge after {} iterations'.format(itn))
    elif options['type'] == 'pyamg':
        if len(V) > 0:
            V_iter = iter(enumerate(V))
            R[0], ml = pyamg.solve(matrix, next(V_iter)[1],
                                   tol=options['tol'],
                                   maxiter=options['maxiter'],
                                   return_solver=True)
            for i, VV in V_iter:
                R[i] = pyamg.solve(matrix, VV,
                                   tol=options['tol'],
                                   maxiter=options['maxiter'],
                                   existing_solver=ml)
    elif options['type'] == 'pyamg-rs':
        ml = pyamg.ruge_stuben_solver(matrix,
                                      strength=options['strength'],
                                      CF=options['CF'],
                                      presmoother=options['presmoother'],
                                      postsmoother=options['postsmoother'],
                                      max_levels=options['max_levels'],
                                      max_coarse=options['max_coarse'],
                                      coarse_solver=options['coarse_solver'])
        for i, VV in enumerate(V):
            R[i] = ml.solve(VV,
                            tol=options['tol'],
                            maxiter=options['maxiter'],
                            cycle=options['cycle'],
                            accel=options['accel'])
    elif options['type'] == 'pyamg-sa':
        ml = pyamg.smoothed_aggregation_solver(matrix,
                                               symmetry=options['symmetry'],
                                               strength=options['strength'],
                                               aggregate=options['aggregate'],
                                               smooth=options['smooth'],
                                               presmoother=options['presmoother'],
                                               postsmoother=options['postsmoother'],
                                               improve_candidates=options['improve_candidates'],
                                               max_levels=options['max_levels'],
                                               max_coarse=options['max_coarse'],
                                               diagonal_dominance=options['diagonal_dominance'])
        for i, VV in enumerate(V):
            R[i] = ml.solve(VV,
                            tol=options['tol'],
                            maxiter=options['maxiter'],
                            cycle=options['cycle'],
                            accel=options['accel'])
    elif options['type'].startswith('generic') or options['type'].startswith('least_squares_generic'):
        logger = getLogger('pymor.operators.numpy._apply_inverse')
        logger.warn('You have selected a (potentially slow) generic solver for a NumPy matrix operator!')
        from pymor.operators.numpy import NumpyMatrixOperator
        from pymor.vectorarrays.numpy import NumpyVectorArray
        return genericsolvers.apply_inverse(NumpyMatrixOperator(matrix),
                                            NumpyVectorArray(V, copy=False),
                                            options=options).data
    else:
        raise ValueError('Unknown solver type')
    return R
Пример #19
0
def poisson(img_bgr, M, mask):
    rows, cols, ch = img_bgr[0].shape
    # Handling panorama boudaries
    x_max = cols
    y_min = 0
    y_max = rows
    position = []
    warp_mask = []
    ### calculate img size of output
    ### d_size is current img border after homography
    for i in range(1, len(img_bgr)):
        # Define d_size for output img
        x = np.array([[0, cols], [0, cols]])
        y = np.array([[0, 0], [rows, rows]])
        d_size_x = x*M[i-1][0,0] + y*M[i-1][0,1] + 1*M[i-1][0,2]
        d_size_y = x*M[i-1][1,0] + y*M[i-1][1,1] + 1*M[i-1][1,2]
        d_size_x = d_size_x.astype(int)
        d_size_y = d_size_y.astype(int)
        if max(d_size_x[0,1], d_size_x[1,1]) > x_max:
            x_max = max(d_size_x[0,1], d_size_x[1,1])
        if min(d_size_y[0,0], d_size_y[0,1]) < y_min:
            y_min = min(d_size_y[0,0], d_size_y[0,1])
        if max(d_size_y[1,0], d_size_y[1,1]) > y_max:
            y_max = max(d_size_y[1,0], d_size_y[1,1])

    ### panorama is initialized with full size
    panorama = np.zeros((y_max-y_min+1, x_max+1, 3))
    ### process each image
    ### no image is pasted at this step
    ### only calculate refined homography and mask
    for i in range(len(img_bgr)):
        print 'processing img', i
        ### calculate borders
        x = np.array([[0, cols-1], [0, cols-1]])
        y = np.array([[0, 0], [rows-1, rows-1]])
        if i == 0:
            #panorama[-y_min:rows-y_min, 0:cols, :] += img_bgr[i]
            position.append([-y_min, rows-y_min-1, 0, cols-1])
            warp_mask.append(mask)
            continue
        if i > 0:
            ### again d_size is the border of current image on absolute coordinate
            d_size_x = x*M[i-1][0,0] + y*M[i-1][0,1] + 1*M[i-1][0,2]
            d_size_y = x*M[i-1][1,0] + y*M[i-1][1,1] + 1*M[i-1][1,2]
        y_begin = int(min(d_size_y[0,0], d_size_y[0,1]) - y_min)
        y_end = int(max(d_size_y[1,0], d_size_y[1,1]) - y_min)
        x_begin = int(min(d_size_x[0,0], d_size_x[1,0]))
        x_end = int(max(d_size_x[0,1], d_size_x[1,1]))
        position.append([y_begin, y_end, x_begin, x_end])
        
        
        ### this is to match cv2.warpPerspective
        ### move the image after homography to top-left and corp to desired size
        H = np.copy(M[i-1])
        H[0,2] -= min(d_size_x[0,0], d_size_x[1,0])
        H[1,2] -= min(d_size_y[0,0], d_size_y[0,1])
        
        d_size = (x_end-x_begin+1, y_end-y_begin+1)
        warp_mask.append(cv2.warpPerspective(mask, H, d_size, None, cv2.INTER_NEAREST))
         
        
    mask_xor = [] ### mask for current image, starting from img0
    mask_and = [] ### mask for image overlay, starting from img1(overlay with 0)
    for i in range(len(img_bgr)):
        if i != len(img_bgr)-1:
        ### calculate coordinate of overlay area
            if( position[i][0] > position[i+1][0] ):
                y_begin = 0
                ny_begin = position[i][0] - position[i+1][0]
            else:
                y_begin = position[i+1][0] - position[i][0]
                ny_begin = 0
            if( position[i][1] > position[i+1][1] ):
                y_end = position[i+1][1] - position[i][0]
                ny_end = position[i+1][1] - position[i+1][0]
            else:
                y_end = position[i][1] - position[i][0] 
                ny_end = position[i][1] - position[i+1][0]
            x_begin = position[i+1][2] - position[i][2]
            x_end = position[i][3] - position[i][2]
            nx_begin = 0
            nx_end = position[i][3] - position[i+1][2]
            ### calculate masks
            tmp_mask = np.copy(warp_mask[i]) ### mask for current image
            ntmp_mask = np.zeros((warp_mask[i+1].shape)) ### overlay mask for next image(relative to next image)
            ntmp_mask[ny_begin:ny_end, nx_begin:nx_end] = warp_mask[i+1][ny_begin:ny_end, nx_begin:nx_end]  \
                                                        * tmp_mask[y_begin:y_end, x_begin:x_end]
            mask_and.append(ntmp_mask)
            if i != 0:
                ### first image has no previous 
                tmp_mask -= mask_and[i-1]
            #tmp_mask[y_begin:y_end, x_begin:x_end] -= ntmp_mask[ny_begin:ny_end, nx_begin:nx_end]
            mask_xor.append(tmp_mask)
        else:
            ### last image has no next image
            tmp_mask = np.copy(warp_mask[i])
            tmp_mask -= mask_and[i-1]
            mask_xor.append(tmp_mask)


    
    ### image blending 
    pwarp_img_bgr = np.zeros(mask_xor[0].shape, dtype='float64')
    for i in range(len(img_bgr)):
        y_begin, y_end, x_begin, x_end = position[i]
        ### directly paste first image
        if i == 0:
            panorama[y_begin:y_end+1, x_begin:x_end+1, 0] = img_bgr[i][:, :, 0] * mask_xor[0]
            panorama[y_begin:y_end+1, x_begin:x_end+1, 1] = img_bgr[i][:, :, 1] * mask_xor[0]
            panorama[y_begin:y_end+1, x_begin:x_end+1, 2] = img_bgr[i][:, :, 2] * mask_xor[0]
            pwarp_img_bgr = img_bgr[i]
            pwarp_img_bgr = pwarp_img_bgr.astype('float64')
            continue


        ### d_size is the desired corp size
        d_size_x = x*M[i-1][0,0] + y*M[i-1][0,1] + 1*M[i-1][0,2]
        d_size_y = x*M[i-1][1,0] + y*M[i-1][1,1] + 1*M[i-1][1,2]
        H = np.copy(M[i-1])
        H[0,2] -= min(d_size_x[0,0], d_size_x[1,0])
        H[1,2] -= min(d_size_y[0,0], d_size_y[0,1])

        d_size = (x_end-x_begin+1, y_end-y_begin+1)
        print 'warp img size:', d_size
        warp_img_bgr = np.zeros((y_end-y_begin+1, x_end-x_begin+1, 3))
        warp_img_bgr[:,:,0] = cv2.warpPerspective(img_bgr[i][:,:,0], H, d_size, None, cv2.INTER_NEAREST)
        warp_img_bgr[:,:,1] = cv2.warpPerspective(img_bgr[i][:,:,1], H, d_size, None, cv2.INTER_NEAREST)
        warp_img_bgr[:,:,2] = cv2.warpPerspective(img_bgr[i][:,:,2], H, d_size, None, cv2.INTER_NEAREST)

        ### directly paste image to panorama first
        panorama[y_begin:y_end+1, x_begin:x_end+1, 0] += warp_img_bgr[:, :, 0] * mask_xor[i]
        panorama[y_begin:y_end+1, x_begin:x_end+1, 1] += warp_img_bgr[:, :, 1] * mask_xor[i]
        panorama[y_begin:y_end+1, x_begin:x_end+1, 2] += warp_img_bgr[:, :, 2] * mask_xor[i]

        ### calculate coordinate of overlay area
        ### no_prefix: current image
        ### p        : panorama
        if( position[i-1][0] > position[i][0] ):
            py_begin    = 0 
            y_begin     = position[i-1][0] - position[i][0]
            oy_begin    = position[i-1][0]
        else:
            py_begin    = position[i][0] - position[i-1][0]
            y_begin     = 0
            oy_begin    = position[i][0]
        if( position[i-1][1] > position[i][1] ):
            py_end      = position[i][1] - position[i-1][0]
            y_end       = position[i][1] - position[i][0]
            oy_end      = position[i][1]
        else:
            py_end      = position[i-1][1] -position[i-1][0]
            y_end       = position[i-1][1] - position[i][0]
            oy_end      = position[i-1][1]
        px_begin    = position[i][2] - position[i-1][2]
        px_end      = position[i-1][3] - position[i-1][2]
        x_begin     = 0
        x_end       = position[i-1][3] - position[i][2]
        ox_begin    = position[i][2]
        ox_end      = position[i-1][3]

 
        ### poisson blending
        ### first cut the overlay block
        overlay_bgr = warp_img_bgr[y_begin:y_end, x_begin:x_end, :]
        poverlay_bgr = panorama[oy_begin:oy_end, ox_begin:ox_end, :]
        mask_overlay = mask_and[i-1][y_begin:y_end, x_begin:x_end]
        ### performed on 3 channel seperately
        for c in range(3):
            overlay = overlay_bgr[:, :, c]
            poverlay = poverlay_bgr[:, :, c]
            
            rows = len(overlay)
            cols = len(overlay[0])
            ### fill in Ax = b and solve x
            print 'size'
            print rows, cols
            A = scipy.sparse.identity(rows*cols, format='lil')
            B = np.zeros(rows*cols) 
            ### fill in A
            for row in range(rows):
                for col in range(cols):
                    ### print progress
                    print "\r",
                    print str(c) + " " + str(int((row*cols+col)/float(rows*cols)*100)),
                    Vpq = 0
                    Np = 0     ### neighbor count
                    neighbor = [0, 0, 0, 0] ### up, down, right, left
                    if(mask_overlay[row, col]):
                        fp = overlay[row, col]
                        gp = poverlay[row, col]
                        ### inside mask
                        ### get difference that is larger
                        if( row>0 ):
                            ### has up neighbor
                            fq = overlay[row-1, col]
                            gq = poverlay[row-1, col]
                            if( mask_overlay[row-1, col] ):
                                Vpq += gp-gq
                            else:
                                Vpq += (fp-fq, gp-gq)[col<(cols/2)]
                            neighbor[0] = -1
                            Np += 1
                        if( row<rows-1 ):
                            ### has down neighbor
                            fq = overlay[row+1, col]
                            gq = poverlay[row+1, col]
                            if( mask_overlay[row+1, col] ):
                                Vpq += gp-gq
                            else:
                                Vpq += (fp-fq, gp-gq)[col<(cols/2)]
                            neighbor[1] = -1
                            Np += 1
                        if( col<cols-1 ):
                            ### has right neighbor
                            fq = overlay[row, col+1]
                            gq = poverlay[row, col+1]
                            if( mask_overlay[row, col+1] ):
                                Vpq += gp-gq
                            else:
                                Vpq += (fp-fq, gp-gq)[col<(cols/2)]
                            neighbor[2] = -1
                            Np += 1
                        if( col>0 ):
                            ### has left neighbor
                            fq = overlay[row, col-1]
                            gq = poverlay[row, col-1]
                            if( mask_overlay[row, col-1] ):
                                Vpq += gp-gq
                            else:
                                Vpq += (fp-fq, gp-gq)[col<(cols/2)]
                            neighbor[3] = -1
                            Np += 1
                        ### fill the coefficients
                        line = row*cols+col
                        A[line, row*cols+col] = Np 
                        A[line, (row-1)*cols+col] += neighbor[0]
                        A[line, (row+1)*cols+col] += neighbor[1]
                        A[line, row*cols+col+1] += neighbor[2]
                        A[line, row*cols+col-1] += neighbor[3]
                        B[row*cols+col] = Vpq
                    else:
                        ### not inside mask
                        B[row*cols+col] = (poverlay[row, col], overlay[row, col])[col>(cols/2)] 
            print 'solving'
            A = A.tocsr()
            result = pyamg.solve(A, B, verb=False, tol=1e-10)
            result[result>255] = 255
            result[result<0] = 0
            panorama[oy_begin:oy_end, ox_begin:ox_end, c] *= (1-mask_overlay) 
            panorama[oy_begin:oy_end, ox_begin:ox_end, c] += mask_overlay * np.reshape(result, (rows, cols))
        pwarp_img_bgr = warp_img_bgr
        cv2.imwrite('panorama'+str(i)+'.jpg', panorama) 
                       
                            
    cv2.imwrite('panorama.jpg', panorama) 
    return panorama
Пример #20
0
def blend(img_target, img_source, img_mask, offset=(0, 0)):
    # compute regions to be blended
    region_source = (
            max(-offset[0], 0),
            max(-offset[1], 0),
            min(img_target.shape[0]-offset[0], img_source.shape[0]),
            min(img_target.shape[1]-offset[1], img_source.shape[1]))
    region_target = (
            max(offset[0], 0),
            max(offset[1], 0),
            min(img_target.shape[0], img_source.shape[0]+offset[0]),
            min(img_target.shape[1], img_source.shape[1]+offset[1]))
    region_size = (region_source[2]-region_source[0], region_source[3]-region_source[1])

    # clip and normalize mask image
    img_mask = img_mask[region_source[0]:region_source[2], region_source[1]:region_source[3]]
    img_mask[img_mask==0] = False
    img_mask[img_mask!=False] = True

    # create coefficient matrix
    A = scipy.sparse.identity(np.prod(region_size), format='lil')
    for y in range(region_size[0]):
        for x in range(region_size[1]):
            if img_mask[y,x]:
                index = x+y*region_size[1]
                A[index, index] = 4
                if index+1 < np.prod(region_size):
                    A[index, index+1] = -1
                if index-1 >= 0:
                    A[index, index-1] = -1
                if index+region_size[1] < np.prod(region_size):
                    A[index, index+region_size[1]] = -1
                if index-region_size[1] >= 0:
                    A[index, index-region_size[1]] = -1
    A = A.tocsr()
    
    # create poisson matrix for b
    P = pyamg.gallery.poisson(img_mask.shape)

    # for each layer (ex. RGB)
    for num_layer in range(img_target.shape[2]):
        # get subimages
        t = img_target[region_target[0]:region_target[2],region_target[1]:region_target[3],num_layer]
        s = img_source[region_source[0]:region_source[2], region_source[1]:region_source[3],num_layer]
        t = t.flatten()
        s = s.flatten()

        # create b
        b = P * s
        for y in range(region_size[0]):
            for x in range(region_size[1]):
                if not img_mask[y,x]:
                    index = x+y*region_size[1]
                    b[index] = t[index]

        # solve Ax = b
        x = pyamg.solve(A,b,verb=False,tol=1e-10)

        # assign x to target image
        x = np.reshape(x, region_size)
        x[x>255] = 255
        x[x<0] = 0
        x = np.array(x, img_target.dtype)
        img_target[region_target[0]:region_target[2],region_target[1]:region_target[3],num_layer] = x

    return img_target
Пример #21
0
   def solve_withPyAMG(self, delfineVar, parameter):
       """Solves the equation system with pyAMG.
           Input:
           elliptic = AssembleElliptic() [AssembleElliptic.py]
       """
       
       # Reads  solver data
       # Alternatives: CG (with or without PreCond) | GMRES (w/ or w/o PC)
       #                     | LU (still pending))
       solverType = parameter.num.pressSolv.type
       tolerance = parameter.num.pressSolv.tolerance
       maxStep = parameter.num.pressSolv.maxNumSteps
       
       # Reads type of preconditioner
       # Alternatives: AMG | ILU | None
       preCondType = parameter.num.pressSolv.preConditioning.type
       
       
       # Getting data from elliptic eq. assembler
       A = delfineVar.A
       rhs = delfineVar.rhs
       
       # Get sparse matrix data
       (row,col,data) = A.data()
       n = A.size(0)
       
       # It was commented the line 126 and 129 of the file compressed.py
       # of the scipy package located in /usr/local/lib/python2.6/dist-packages
       # /scipy/sparse in order to avoid some annoying warning messages.
       # If some strange behaviour takes place in this solver routine, this 
       # information may be important for debugging
       Asp = csr_matrix( (data,col.view(),row.view()), shape=(n,n))
       
       # Get right-hand side vector(rhs) data
       b = rhs.data()
       residuals = []
       
       # Solves equation system
       if (solverType == 'blackbox'):
           # Uses PyAMG blackbox solver, which implies that the program detect automatically
           # the best solver parameters for the case. Very useful for debugging and
           # "difficult" to converge cases. Does not allow to set max. iterations or this kind
           # of stuff.
           x = solve(Asp, b, verb=True,tol=tolerance)
       else:
           if (preCondType == "amg"):
               # Using AMG Solver as preconditioner with 'solverType' (cg,gmres) as 
               # accelerator. If ilu is defined as solver, it will use pure AMG without
               # accelaration.
               nCoarse = parameter.num.pressSolv.preConditioning.numCoarseLevel
               ml = smoothed_aggregation_solver(Asp, max_levels=nCoarse, max_coarse=1)
               if ((solverType == "cg") | (solverType == "gmres")):
                   # Use CG or GMRES acceleration
                   x = ml.solve(b,tol=tolerance, maxiter=maxStep, cycle='V', accel=solverType,residuals=residuals)
               elif(solverType == "none"):
                   # No accelaration (stand-alone AMG)
                   x = ml.solve(b,tol=tolerance, maxiter=maxStep, cycle='V', residuals=residuals)
               elif (solverType == "lu"):
                   # Trying to use a direct LU solver with amg, but it is not coherent
                   print "Error(7):"
                   print "Direct solver not compatible with amg"
                   print "You can try: amg+cg,amg+gmres,amg+none,"
                   print "             none+cg,none+gmres,none+lu,"
                   print "             ilu+cg,ilu+gmres"
                   print " "
                   sys.exit(1)
               print ml
               
               ####################################
               # Print customized spectrum of multigrid operator
               # This function is efficient just for a small n (max=32)
               
               #from pyamg.util.utils import hierarchy_spectrum
               #hierarchy_spectrum(ml, filter=True, plot=True)
      
               ####################################
               
           elif (preCondType == "none") :
               # Iterate without preconditioner
               if (solverType == "cg"):
                   # Using conventional Conjugate Gradients Solver
                   (x, flag) = cg(Asp,b, maxiter=maxStep, tol=tolerance,  residuals=residuals)
               elif (solverType == "gmres"):
                   # Using conventional Generalized Minimum Residual Method Solver
                   (x, flag) = gmres(Asp,b, maxiter=maxStep, tol=tolerance,  residuals=residuals)
               elif (solverType == "lu"):
                   # Using a direct LU solver
                   # (still pending, to be done with dolfin solver schema, not pyamg)
                   print "Error(8):"
                   print "Direct solver still not available, use cg or gmres instead"
                   print " "
                   sys.exit(1)
               elif (solverType == "none"):
                   # Using a direct LU solver
                   # (still pending, to be done with dolfin solver schema, not pyamg)
                   print "Error(9):"
                   print "Invalid solver + preconditioner option!"
                   print "You can try: amg+cg,amg+gmres,amg+none,"
                   print "             none+cg,none+gmres,none+lu,"
                   print "             ilu+cg,ilu+gmres"
                   print " "
                   sys.exit(1)
                   
           elif (preCondType == "ilu"):
                   # Using a ILU preconditioner
                   # (still pending, to be done with dolfin solver schema, not pyamg)
                   print "Error(10):"
                   print "ILU Preconditioner still not available, use amg or none instead"
                   print " "
                   sys.exit(1)
       
       # Print residuals history
       if (solverType != 'blackbox'):
           pass
           #residuals = residuals/residuals[0]
 
       # Define return parameters
       delfineVar.x = x
       delfineVar.residuals = residuals
Пример #22
0
    def apply_inverse(self, U, ind=None, mu=None, options=None):

        default_options = self.invert_options

        if options is None:
            options = default_options.values()[0]
        elif isinstance(options, str):
            options = default_options[options]
        else:
            assert 'type' in options and options['type'] in default_options \
                and options.viewkeys() <= default_options[options['type']].viewkeys()
            user_options = options
            options = default_options[user_options['type']]
            options.update(user_options)

        assert isinstance(U, NumpyVectorArray)
        assert self.dim_range == U.dim

        U = U._array[:U._len] if ind is None else U._array[ind]
        if U.shape[1] == 0:
            return NumpyVectorArray(U)
        R = np.empty((len(U), self.dim_source))

        if self.sparse:
            if options['type'] == 'bicgstab':
                for i, UU in enumerate(U):
                    R[i], info = bicgstab(self._matrix, UU, tol=options['tol'], maxiter=options['maxiter'])
                    if info != 0:
                        if info > 0:
                            raise InversionError('bicgstab failed to converge after {} iterations'.format(info))
                        else:
                            raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'.
                                                 format(info))
            elif options['type'] == 'bicgstab-spilu':
                ilu = spilu(self._matrix, drop_tol=options['spilu_drop_tol'], fill_factor=options['spilu_fill_factor'],
                            drop_rule=options['spilu_drop_rule'], permc_spec=options['spilu_permc_spec'])
                precond = LinearOperator(self._matrix.shape, ilu.solve)
                for i, UU in enumerate(U):
                    R[i], info = bicgstab(self._matrix, UU, tol=options['tol'], maxiter=options['maxiter'], M=precond)
                    if info != 0:
                        if info > 0:
                            raise InversionError('bicgstab failed to converge after {} iterations'.format(info))
                        else:
                            raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'.
                                                 format(info))
            elif options['type'] == 'spsolve':
                for i, UU in enumerate(U):
                    R[i] = spsolve(self._matrix, UU, permc_spec=options['permc_spec'])
            elif options['type'] == 'pyamg':
                if len(U) > 0:
                    U_iter = iter(enumerate(U))
                    R[0], ml = pyamg.solve(self._matrix, next(U_iter)[1],
                                           tol=options['tol'],
                                           maxiter=options['maxiter'],
                                           return_solver=True)
                    for i, UU in U_iter:
                        R[i] = pyamg.solve(self._matrix, UU,
                                           tol=options['tol'],
                                           maxiter=options['maxiter'],
                                           existing_solver=ml)
            elif options['type'] == 'pyamg-rs':
                ml = pyamg.ruge_stuben_solver(self._matrix,
                                              strength=options['strength'],
                                              CF=options['CF'],
                                              presmoother=options['presmoother'],
                                              postsmoother=options['postsmoother'],
                                              max_levels=options['max_levels'],
                                              max_coarse=options['max_coarse'],
                                              coarse_solver=options['coarse_solver'])
                for i, UU in enumerate(U):
                    R[i] = ml.solve(UU,
                                    tol=options['tol'],
                                    maxiter=options['maxiter'],
                                    cycle=options['cycle'],
                                    accel=options['accel'])
            elif options['type'] == 'pyamg-sa':
                ml = pyamg.smoothed_aggregation_solver(self._matrix,
                                                       symmetry=options['symmetry'],
                                                       strength=options['strength'],
                                                       aggregate=options['aggregate'],
                                                       smooth=options['smooth'],
                                                       presmoother=options['presmoother'],
                                                       postsmoother=options['postsmoother'],
                                                       improve_candidates=options['improve_candidates'],
                                                       max_levels=options['max_levels'],
                                                       max_coarse=options['max_coarse'],
                                                       diagonal_dominance=options['diagonal_dominance'])
                for i, UU in enumerate(U):
                    R[i] = ml.solve(UU,
                                    tol=options['tol'],
                                    maxiter=options['maxiter'],
                                    cycle=options['cycle'],
                                    accel=options['accel'])
            else:
                raise ValueError('Unknown solver type')
        else:
            for i, UU in enumerate(U):
                try:
                    R[i] = np.linalg.solve(self._matrix, UU)
                except np.linalg.LinAlgError as e:
                    raise InversionError('{}: {}'.format(str(type(e)), str(e)))

        return NumpyVectorArray(R)
Пример #23
0
def diffuse_inprob(inprobs, paths, segs, imgs):
    #inprobs is a list of inside probability for superpixels
                               
    init_prob = []
    id2index = []
    index = 0
    n_last = len(np.unique(segs[-1]))
    for i in range(len(inprobs)):
        id2index.append({})
        for (jj,j) in enumerate(inprobs[i]):
             init_prob.append(j)
             id2index[i][jj] = index
             index += 1
        
    dist = []
    row_index = []
    col_index = []
    rgbs = np.zeros((len(init_prob),3))
    n_frames = len(imgs)
    
    for (i,id) in enumerate(paths.keys()):
        frame = paths[id].frame
        rows = paths[id].rows
        cols = paths[id].cols
    
        unique_frame = np.unique(frame)
    
        for f in unique_frame:
    
            if f == n_frames-1: continue
            r1 = rows[frame == f]
            c1 = cols[frame == f]
            index1 = id2index[f][segs[f][r1[0],c1[0]]]
            
            rgb1 = np.mean(imgs[f][r1,c1],axis=0)
            rgbs[index1] = rgb1
            for f2 in unique_frame:
                if f >= f2: continue
                if f2 == n_frames-1: continue            
                r2 = rows[frame == f2]
                c2 = cols[frame == f2]
                rgb2 = np.mean(imgs[f2][r2,c2],axis=0)
                
                index2 = id2index[f2][segs[f2][r2[0],c2[0]]]
                rgbs[index2] = rgb2
                
                d = np.linalg.norm(rgb1-rgb2) **2
    
                row_index.append(index1)
                row_index.append(index2)
                col_index.append(index2)
                col_index.append(index1)
    
                dist.append(d)
                dist.append(d)
    
    adjs = sp_adj(segs)
                
    for i in range(n_frames-1):
        for j in range(adjs[i].shape[0]):
            index1 = id2index[i][j]
            rgb1 = rgbs[index1]
    
            row_index.append(index1)
            col_index.append(index1)
            dist.append(0)
            
            for k in np.nonzero(adjs[i][j])[0]:
    
                if j > k: continue
                index2 = id2index[i][k]
                rgb2 = rgbs[index2]
                
                d = np.linalg.norm(rgb1-rgb2) **2
    
                row_index.append(index1)
                row_index.append(index2)
                col_index.append(index2)
                col_index.append(index1)
    
                dist.append(d)
                dist.append(d)
    
    sigma = 30 
    values2 = np.exp(-np.array(dist) / (2*sigma**2))
    
    from scipy.sparse import csr_matrix, spdiags
    n_node = len(init_prob)
    W = csr_matrix((values2, (row_index, col_index)), shape=(n_node, n_node))
    
    inv_D =spdiags(1.0/((W.sum(axis=1)).flatten()), 0, W.shape[0], W.shape[1])
    D =spdiags(W.sum(axis=1).flatten(), 0, W.shape[0], W.shape[1])
    lam = 10
    lhs = D + lam * (D - W)
    from scipy.sparse import eye
    
    from scipy.sparse.linalg import spsolve,lsmr
#    diffused_prob = spsolve(lhs, D.dot(np.array(init_prob)))
    diffused_prob = solve(lhs, D.dot(np.array(init_prob)))
    
    diffused_probs = []
    
    count = 0
    for i in range(len(inprobs)):
        diffused_probs.append(diffused_prob[count:len(inprobs[i])+count])
        count += len(inprobs[i])

    return diffused_probs