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)
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
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
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)
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
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)
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
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)
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
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
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
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
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
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
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
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
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 ""
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
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
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
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
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)
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