Source code for monalisa.gridding._im_deform_field_to_sparse_mat

"""Port of src/gridding123/m/bmImDeformField2SparseMat.m."""

import numpy as np
import scipy.sparse as sp

from monalisa._mat import cell_from_items, cell_items, cell_shape, iscell, isempty, vec
from monalisa.gridding._im_deform_field_to_sparse_mat_ind_weight import im_deform_field_to_sparse_mat_ind_weight
from monalisa.gridding._traj_to_sparse_mat import _row_normalize
from monalisa.sparse._sparse_mat_from_matlab_sparse import sparse_mat_from_matlab_sparse


[docs] def im_deform_field_to_sparse_mat(v, N_u, Dn=None, torus_flag=None, *, nargout=2): """Sparse interpolation matrices of the deformation field ``v``: ``Gn`` (``nargout`` 1), ``(Gu, Gut)`` (2) or ``(Gn, Gu, Gut)`` (3). ``Gu`` warps an image (column format) by ``v``; ``Gut`` is its transpose.""" if iscell(v): vs = cell_items(v) Dns = [None] * len(vs) if isempty(Dn) else cell_items(Dn) res = [im_deform_field_to_sparse_mat(vi, N_u, di, torus_flag, nargout=nargout) for vi, di in zip(vs, Dns, strict=True)] shape = cell_shape(v) if nargout == 1: return cell_from_items(res, shape) return tuple(cell_from_items([r[k] for r in res], shape) for k in range(nargout)) if isempty(v): return (None,) * nargout if nargout > 1 else None torus_flag = False if isempty(torus_flag) else bool(torus_flag) N_u = vec(N_u) Nu_tot = int(np.prod(N_u)) v = np.asarray(v) nPt = int(np.size(v) // N_u.size) if v.size else 0 if nPt != Nu_tot: raise ValueError("In im_deform_field_to_sparse_mat : the deformation field must have as many vectors as " "the number of pixel(voxel) in the image. ") ind_1, ind_2, w, Dn = im_deform_field_to_sparse_mat_ind_weight(v, N_u, Dn, torus_flag) rows = ind_2.ravel().astype(np.int64) - 1 cols = ind_1.ravel().astype(np.int64) - 1 w = w.ravel() def to_bm(m): return sparse_mat_from_matlab_sparse(m, N_u[None, :], np.array([[1.0, 1.0, 1.0]]), "bump", 2.0, None) out = {} if nargout in (1, 3): if Dn.size == 0: raise ValueError("Dn is required for Gn") m = sp.coo_matrix((w * Dn.ravel(), (cols, rows)), shape=(Nu_tot, nPt)) out["Gn"] = to_bm(_row_normalize(m)) out["Gn"].cpp_prepare("one_block", None, None) if nargout in (2, 3): m = _row_normalize(sp.coo_matrix((w, (rows, cols)), shape=(nPt, Nu_tot))) Gu, Gut = to_bm(m), to_bm(m.T) Gu.cpp_prepare("one_block", None, None) Gut.cpp_prepare("one_block", None, None) out["Gu"], out["Gut"] = Gu, Gut if nargout == 1: return out["Gn"] if nargout == 2: return out["Gu"], out["Gut"] return out["Gn"], out["Gu"], out["Gut"]