demeter.utils package
Submodules
demeter.utils.bspline module
- demeter.utils.bspline.bspline_basis(*args)
- demeter.utils.bspline.field2D_bspline(cms, n_pts, degree=(1, 1), dim_stack=0)
Generate 2D fields from a 2D control matrix
- Parameters:
cms – shape = (2,p,q) Control matricies
n_pts – (tuple) grid dimension
degree – (tuple), degree of the spline in each direction
- Returns:
vector field of shape (2,n_pts[0],n_pts[1])
- demeter.utils.bspline.field3D_bspline(cms, n_pts, degree=(1, 1, 1), dim_stack=0)
Generate 3D fields from a 3D control matix
- Parameters:
cms – shape = (3,p,q,r) Control matricies
n_pts – (tuple) grid dimension
degree – (tuple), degree of the spline in each direction
dim_stack – (int) dimension to stack the field
- Returns:
vector field of shape (3,n_pts[0],n_pts[1],n_pts[2]) if dim_stack = 0 vector field of shape (n_pts[0],n_pts[1],n_pts[2],3) if dim_stack = -1
- demeter.utils.bspline.getCMS_allcombinaision()
- demeter.utils.bspline.getCMS_turn()
- demeter.utils.bspline.memo(f)
Memorize the return value for each call to f(args). Then when called again with same args, we can just look it up.
- demeter.utils.bspline.surf_bspline(cm, n_pts, degree=(1, 1))
Generate a 2D surface from a control matrix
:param cm = 2D matrix Control point Matrix :param n_pts = (tuple), number of points on the curve. :param degree = (tuple), degree of the spline in each direction :return:
- demeter.utils.bspline.surf_bspline_3D(cm, n_pts, degree=(1, 1, 1))
Generate a 3D surface from a control matrix
:param cm = 3D matrix Control point Matrix :param n_pts = (tuple), number of points on the curve. :param degree = (tuple), degree of the spline in each direction :return: 3D surface of shape (n_pts[0],n_pts[1],n_pts[2])
test: .. code-block:: python
P_im = torch.rand((5,6,7),dtype=torch.float) img = surf_bspline_3D(P_im,(100,200,300))
demeter.utils.cost_functions module
- class demeter.utils.cost_functions.Combine_ssd_CFM(ssd_target, cfm_target, seg, cancer_on_target=True)
Bases:
object
- class demeter.utils.cost_functions.Mutual_Information(bins=50, min=0, max=1, sigma=10, reduction='sum')
Bases:
Module
This class is a pytorch implementation of the mutual information (MI) calculation between two images. This is an approximation, as the images’ histograms rely on differentiable approximations of rectangular windows.
\[I(X, Y) = H(X) + H(Y) - H(X, Y) = \sum(\sum(p(X, Y) * log(p(Y, Y)/(p(X) * p(Y)))))\]where \(H(X) = -\sum(p(x) * log(p(x)))\) is the entropy
- forward(im1, im2, plot=False)
Forward implementation of a differentiable MI estimator for batched images :param im1: N x … tensor, where N is the batch size
… dimensions can take any form, i.e. 2D images or 3D volumes.
- Parameters:
im2 – N x … tensor, where N is the batch size
- Returns:
N x 1 vector - the approximate MI values between the batched im1 and im2
- independence_plot(joinedLaw_xy, marginal_x, marginal_y)
- class demeter.utils.cost_functions.SoftHistogram1D(bins=50, min=0, max=1, sigma=10)
Bases:
Module
Differentiable 1D histogram calculation (supported via pytorch’s autograd) inupt: x - N x D array, where N is the batch size and D is the length of each data series bins - Number of bins for the histogram min - Scalar min value to be included in the histogram max - Scalar max value to be included in the histogram sigma - Scalar smoothing factor fir the bin approximation via sigmoid functions.
Larger values correspond to sharper edges, and thus yield a more accurate approximation
output: N x bins array, where each row is a histogram
- forward(x)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class demeter.utils.cost_functions.SoftHistogram2D(bins=50, min=0, max=1, sigma=10)
Bases:
Module
Differentiable 1D histogram calculation (supported via pytorch’s autograd) Parameters: ————- x, y - N x D array, where N is the batch size and D is the length of each data series
(i.e. vectorized image or vectorized 3D volume)
bins - Number of bins for the histogram min - Scalar min value to be included in the histogram max - Scalar max value to be included in the histogram sigma - Scalar smoothing factor fir the bin approximation via sigmoid functions.
Larger values correspond to sharper edges, and thus yield a more accurate approximation
Returns:
N x bins array, where each row is a histogram
- forward(x, y)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
demeter.utils.decorators module
- demeter.utils.decorators.deprecated(reason)
This is a decorator which can be used to mark functions as deprecated. It will result in a warning being emitted when the function is used.
Usage example :
@deprecated("use another function") def some_old_function(x, y): return x + y class SomeClass(object): @deprecated("use another method") def some_old_method(self, x, y): return x + y @deprecated("use another class") class SomeOldClass(object): pass some_old_function(5, 3) SomeClass().some_old_method(8, 9) SomeOldClass()
- demeter.utils.decorators.time_it(func)
This decorator is used to measure the execution time (in seconds) of a function
Usage example : .. code-block:: python
import time @time_it def my_function():
print(“I fall alseeep …) time.sleep(2.5) print(“Hello world”)
my_function()
demeter.utils.fft_conv module
- demeter.utils.fft_conv.complex_matmul(a: Tensor, b: Tensor, groups: int = 1) Tensor
Multiplies two complex-valued tensors.
- demeter.utils.fft_conv.fft_conv(signal: Tensor, kernel: Tensor, bias: Tensor = None, padding: int | Iterable[int] = 0, stride: int | Iterable[int] = 1, groups: int = 1) Tensor
Performs N-d convolution of Tensors using a fast fourier transform, which is very fast for large kernel sizes. Also, optionally adds a bias Tensor after the convolution (in order ot mimic the PyTorch direct convolution).
- Parameters:
signal – (Tensor) Input tensor to be convolved with the kernel.
kernel – (Tensor) Convolution kernel.
bias – (Tensor) Bias tensor to add to the output.
padding – (Union[int, Iterable[int]) Number of zero samples to pad the input on the last dimension.
stride – (Union[int, Iterable[int]) Stride size for computing output values.
- Returns:
(Tensor) Convolved tensor
- demeter.utils.fft_conv.to_ntuple(val: int | Iterable[int], n: int) Tuple[int, ...]
Casts to a tuple with length ‘n’. Useful for automatically computing the padding and stride for convolutions, where users may only provide an integer.
- Parameters:
val – (Union[int, Iterable[int]]) Value to cast into a tuple.
n – (int) Desired length of the tuple
- Returns:
(Tuple[int, …]) Tuple of length ‘n’
demeter.utils.fill_saves_overview module
- demeter.utils.fill_saves_overview.append_to_csv_new(file_name, message='')
- demeter.utils.fill_saves_overview.rec(s)
remove_escape_characters
- demeter.utils.fill_saves_overview.update_csv()
demeter.utils.image_3d_visualisation module
demeter.utils.optim module
demeter.utils.reproducing_kernels module
- class demeter.utils.reproducing_kernels.GaussianRKHS(sigma: Tuple, border_type: str = 'replicate', normalized: bool = True, kernel_reach=6, **kwargs)
Bases:
Module
Is equivalent to a gaussian blur. This function support 2d and 3d images in the PyTorch convention
\[\mathrm{kernel} = \exp\left(\frac{-x^2}{2 \sigma^2}\right)\]if normalised is True, the kernel will be L1 normalised: kernel = kernel / kernel.sum() making it equivalent to factorizing by \(\frac{1}{2 \pi}\) but less sensitive to the discretisation choices..
Parameters:
- sigma (Tuple[float, float] or [float,float,float]):
the standard deviation of the kernel.
- border_type (str):
the padding mode to be applied before convolving. The expected modes are:
'constant'
,'reflect'
,'replicate'
or'circular'
. Default:'reflect'
.- normalized (bool):
If True, kernel will be L1 normalized. (kernle.max wil be 1)
- kernel_reach (int):
value times sigma that controls the distance in pixels between the center and the edge of the kernel. The greater it is the closer we are to an actual gaussian kernel. (default = 6)
Examples:
import torch import demeter.utils.torchbox as tb import demeter.utils.reproducing_kernels as rk img_name = '01' # simple disk img_name = 'sri24' # slice of a brain img = tb.reg_open(img_name,size = (300,300)) sigma = (3,5) kernelOp = rk.GaussianRKHS(sigma) print(kernelOp) blured = kernelOp(img_data) fig,ax = plt.subplots(1,2) ax[0].imshow(img_data[0,0]) ax[1].imshow(blured[0,0]) plt.show()
- forward(input: Tensor)
Convolve the input tensor with the Gaussian kernel.
Args:
- input (torch.Tensor):
the input tensor with shape of \((B, C, H, W)\) or \((B, C, D, H, W)\)
Returns:
torch.Tensor: the convolved tensor of same size and numbers of channels as the input.
- get_all_arguments()
Return all the arguments used to initialize the class is used to save the class.
- Returns:
dict
- init_kernel(image)
Run at the integrator initialization. In this case, it checks if the sigma is a tuple of the right dimension according to the given image in the integrator.
Args:
- image (torch.Tensor):
the image to be convolved
- plot()
- class demeter.utils.reproducing_kernels.Multi_scale_GaussianRKHS(list_sigmas, normalized: bool = True, **kwargs)
Bases:
Module
This class is a multiscale Gaussian RKHS. It is equivalent to a multiscale Gaussian blur. This function support 2d and 3d images in the PyTorch convention
Let \(\Gamma = { \sigma_1, \sigma_2, \ldots, \sigma_n}\) be a list of standard deviations.
where \(n\) is the number of elements in \(\Gamma\). if normalised is True, \(k\) is equal to:
\[k_\sigma = \sum_{x \in Omega} \exp\left(\frac{-x^2}{2 \sigma^2}\right) \]else, \(k\) is equal to 1.Parameters:
- list_sigmas: List[Tuple[float,float] or Tuple[float,float,float]]
the standard deviation of the kernel.
Example:
import __init__ import demeter.utils.reproducing_kernels as rk import demeter.utils.torchbox as tb import matplotlib.pyplot as plt import torch sigma= [(5,5),(7,7),(10,10)] kernelOp = rk.Multi_scale_GaussianRKHS(sigma) image = tb.RandomGaussianImage((100,100),5,'pixel').image() image_b = kernelOp(image) fig, ax = plt.subplots(2,2,figsize=(10,5)) ax[0,0].imshow(kernelOp.kernel[0]) ax[0,0].set_title('kernel 1') ax[0,1].plot(kernelOp.kernel[0][kernelOp.kernel[0].shape[0]//2]) ax[1,0].imshow(image[0,0]) ax[1,0].set_title('image') ax[1,1].imshow(image_b[0,0]) ax[1,1].set_title('image_b') plt.show()
- get_all_arguments()
- init_kernel(image)
- plot()
- class demeter.utils.reproducing_kernels.Multi_scale_GaussianRKHS_notAverage(list_sigmas)
Bases:
Module
- class demeter.utils.reproducing_kernels.VolNormalizedGaussianRKHS(sigma: Tuple, sigma_convention='pixel', dx=(1,), border_type: str = 'constant', kernel_reach=6, **kwargs)
Bases:
Module
A kernel that preserves the value of the norm \(V\) for different images resolution.
Let \(\sigma=(\sigma_h)_{1\leq h\leq d}\) be the standard deviation along the different coordinate in \(\R^d\) and \(B=B(0,1)\) the closed ball of radius \(1\). We denote \(D=\text{diag}(\sigma_h^2)\) and we consider the kernel
\[K(x,y)=\frac{1}{\mathrm{Vol}(D^{1/2} B)}\exp\left(-\frac{1}{2}\langle D^{-1}(x-y),(x-y)\rangle\right)D\,.\]call the emph{anisotropic volume normalized gaussian kernel} (AVNG kernel).
Parameters:
- sigma (Tuple[float,float] or [float,float,float]):
the standard deviation of the kernel.
- sigma_convention (str):
default ‘pixel’. expected modes are: {‘pixel’,’continuous’} The unit sigma input should be considered as pixel or continuous.
- dx (Tuple[float,float] or [float,float,float]):
the length of a pixel in each dimension. if the image is isotropic, dx_convention can be a float. If the image is anisotropic, dx_convention must be a tuple of length equal to the image dimension. The default value is 1. (equivalent to pixel unit)
- border_type (str):
the padding mode to be applied before convolving. The expected modes are:
'constant'
,'reflect'
,'replicate'
or'circular'
. Default:'reflect'
.- kernel_reach (int):
the reach of the kernel assuming sigma = 1. For a given value of kernel reach, the kernel size is calculated as kernel_size = max(kernel_reach,int(sigma*kernel_reach/dx)) + (1 - max(kernel_reach,int(sigma*kernel_reach/dx)) %2) meaning that the kernel size is always odd and have (kernel_reach/2) * sigma pixel between the center and the kernel border. The default value is 6, should be enough for most of the applications, but if you notice negative V_norms, increasing this value might help.
- forward(input: Tensor)
Convolve the input tensor with the Gaussian kernel.
Args:
- input (torch.Tensor):
the input tensor with shape of \((B, C, H, W)\) or \((B, C, D, H, W)\)
Returns:
torch.Tensor: the convolved tensor of same size and numbers of channels as the input.
- get_all_arguments()
- init_kernel(image)
- plot()
- demeter.utils.reproducing_kernels.dx_convention_handler(dx_convention, dim)
- demeter.utils.reproducing_kernels.fft_filter(input: Tensor, kernel: Tensor, border_type: str = 'constant', normalized: bool = False) Tensor
Function that convolves a tensor with a kernel. This function is almost the function filter2d from kornia, adapted to work with 2d and 3d tensors.
The function applies a given kernel to a tensor. The kernel is applied independently at each depth channel of the tensor. Before applying the kernel, the function applies padding according to the specified mode so that the output remains in the same shape.
Parameters:
- input (torch.Tensor):
the input tensor with shape of \((B, C, H, W)\) or \((B, C, D, H, W)\)
- kernel (torch.Tensor):
the kernel to be convolved with the input tensor. The kernel shape must be \((1, kH, kW)\) or \((1, kD, kH, kW)\).
- border_type (str):
the padding mode to be applied before convolving. The expected modes are:
'constant'
,'reflect'
,``’replicate’`` or'circular'
. Default:'reflect'
.- normalized (bool):
If True, kernel will be L1 normalized.
Return:
torch.Tensor: the convolved tensor of same size and numbers of channels as the input.
- demeter.utils.reproducing_kernels.get_gaussian_kernel1d(sigma, dx=1, kernel_size=None, normalized=True, kernel_reach=3, device='cpu', dtype=torch.float32)
Function that returns Gaussian filter coefficients.
\[g(x) = \exp\left(\frac{-x^2}{2 \sigma^2}\right)\]Parameters:
- kernel_size (int)
the size of the kernel.
- dx (float)
the spacing between the kernel points.
- normalized (bool)
if True, the kernel will be L1 normalized. (divided by the sum of its elements)
- kernel_reach (int)
value times sigma that controls the distance in pixels between the center and the edge of the kernel. The greater it is the closer we are to an actual gaussian kernel. (default = 6)
- sigma (float, Tensor)
standard deviation of the kernel.
- device (torch.device)
the desired device of the kernel.
- dtype (torch.dtype)
the desired data type of the kernel.
Returns:
torch.Tensor: 1D tensor with the filter coefficients.
- Shape:
Output: \((K,)\)
- demeter.utils.reproducing_kernels.get_gaussian_kernel2d(sigma, dx=(1.0, 1.0), kernel_size=None, normalized=True, kernel_reach=3)
Function that returns Gaussian filter coefficients.
Parameters:
- sigma (Tuple[float, float] or torch.Tensor):
the standard deviation of the kernel.
- dx (Tuple[float, float]):
length of pixels in each direction.
- kernel_size (Tuple[int, int] | None):
the size of the kernel, if None, it will be automatically calculated.
- returns:
2D tensor with the filter coefficients.
- rtype:
torch.Tensor
- Shape:
Output: \((H, W)\)
- demeter.utils.reproducing_kernels.get_gaussian_kernel3d(sigma, dx=(1.0, 1.0, 1.0), kernel_size=None, normalized=True, kernel_reach=3)
Function that returns Gaussian filter coefficients.
Parameters:
- sigma (Tuple[float, float, float] or torch.Tensor):
the standard deviation of the kernel.
- dx (Tuple[float, float, float]):
length of pixels in each direction.
- kernel_size (Tuple[int, int, int] | None):
the size of the kernel, if None, it will be automatically calculated.
- kernel_reach (int):
value times sigma that controls the distance in pixels between the center and the edge of the kernel. The greater it is the closer we are to an actual gaussian kernel. (default = 6)
Returns:
torch.Tensor: 3D tensor with the filter coefficients.
- demeter.utils.reproducing_kernels.get_sigma_from_img_ratio(img_shape, subdiv, c=0.1)
The function get_sigma_from_img_ratio calculates the ideal \(sigma\) values for a Gaussian kernel based on the desired grid granularity. Given an image \(I\) of size \((H, W)\), the goal is to divide the image into a grid of \(n_h\) (in the H direction) and \(n_w\) (in the W direction). Suppose \(x\) is at the center of a square in this \(n_h \times n_w\) grid. We want to choose \(\sigma = (\sigma_h, \sigma_w)\) such that the Gaussian centered at \(x\) is negligible outside the grid square.
In other words, we want to find \(\sigma\) such that:
\[ \begin{align}\begin{aligned}e^{\frac{ -\left(\frac{H}{n_h}\right)^2}{2 \sigma^2}} < c; \qquad c \in \mathbb{R}\\where $c$ is the negligibility constant.\end{aligned}\end{align} \]- Parameters:
img_shape – torch.Tensor or Tuple[int] : shape of the image
subdiv –
int or Tuple[int] or List[Tuple[float]] or List[List[int]] : meant to encode the number of subdivisions of the grid, lets details the different cases:
int : the grid is divided in the same number of subdivisions in each direction
- Tuple[int]the grid is divided in the number of subdivisions given in the tuple
according to the dimensions of the image
List[Tuple[float]] : If a tuple is given, we consider that it contains values of sigmas
- List[List[int]]If a list of list is given, we consider that each element of the list
is a list of integers that represent the number of subdivisions in each direction we simply apply the ‘int case’ to each element of the list.
c – float : value considered as negligible in the gaussian kernel
- demeter.utils.reproducing_kernels.plot_gaussian_kernel_1d(kernel: Tensor, sigma, ax=None, rotated=False)
Function that plots a 1D Gaussian kernel.
Parameters:
- kernel (torch.Tensor):
the kernel to be plotted.
- sigma (float):
the standard deviation of the kernel.
- ax (matplotlib.axes.Axes | None):
the axes to plot the kernel. If None, a new figure will be created.
- rotated (bool):
if True, the kernel will be plotted horizontally.
Returns:
matplotlib.axes.Axes: the axes where the kernel was plotted.
- demeter.utils.reproducing_kernels.plot_gaussian_kernel_2d(kernel: Tensor, sigma, axes=None)
Function that plots a 2D Gaussian kernel.
Parameters:
- kernel (torch.Tensor):
the kernel to be plotted.
- sigma (Tuple[float, float]):
the standard deviation of the kernel.
- axes (matplotlib.axes.Axes | None):
the axes to plot the kernel. If None, a new figure will be created.
Returns:
matplotlib.axes.Axes: the axes where the kernel was plotted.
- demeter.utils.reproducing_kernels.plot_gaussian_kernel_3d(kernel: Tensor, sigma)
Function that plots a 3D Gaussian kernel.
Parameters:
- kernel (torch.Tensor):
the kernel to be plotted.
- sigma (Tuple[float, float, float]):
the standard deviation of the kernel.
- demeter.utils.reproducing_kernels.plot_kernel_on_image(kernelOperator, subdiv=None, image=None, image_shape=None, ax=None)
demeter.utils.toolbox module
- demeter.utils.toolbox.TestCuda(verbose=True)
- demeter.utils.toolbox.annotate_heatmap(im, data=None, valfmt='{x:.2f}', textcolors=['black', 'white'], threshold=None, **textkw)
A function to annotate a heatmap.
- Parameters:
im – The AxesImage to be labeled.
data – Data used to annotate. If None, the image’s data is used. Optional.
valfmt – The format of the annotations inside the heatmap. This should either use the string format method, e.g. “$ {x:.2f}”, or be a matplotlib.ticker.Formatter. Optional.
textcolors – A list or array of two color specifications. The first is used for values below a threshold, the second for those above. Optional.
threshold – Value in data units according to which the colors from textcolors are applied. If None (the default) uses the middle of the colormap as separation. Optional.
**kwargs – All other arguments are forwarded to each call to text used to create the text labels.
- demeter.utils.toolbox.fig_to_image(fig, ax)
- demeter.utils.toolbox.format_time(seconds)
- demeter.utils.toolbox.full_ellipse(x, y, a, b, center, theta=0.0)
Return a boolean matrix of the size given by x,y
- Parameters:
y (x,) – grid from meshgrid
a – constant, control of the wideness of the ellipse
b – constant, control of the wideness of the ellipse
center – has to have a length of two, center coordinates of the ellispe
theta – inclinaison de l’ellispe
- Returns:
- demeter.utils.toolbox.get_freer_gpu()
- demeter.utils.toolbox.get_size(obj, seen=None)
Recursively finds size of objects
- demeter.utils.toolbox.heatmap(data, row_labels, col_labels, ax=None, cbar_kw={}, cbarlabel='', **kwargs)
Create a heatmap from a numpy array and two lists of labels.
- Parameters:
data – A 2D numpy array of shape (N, M).
row_labels – A list or array of length N with the labels for the rows.
col_labels – A list or array of length M with the labels for the columns.
ax – A matplotlib.axes.Axes instance to which the heatmap is plotted. If not provided, use current axes or create a new one. Optional.
cbar_kw – A dictionary with arguments to matplotlib.Figure.colorbar. Optional.
cbarlabel – The label for the colorbar. Optional.
**kwargs – All other arguments are forwarded to imshow.
- demeter.utils.toolbox.imCmp(I1, I2)
- demeter.utils.toolbox.rgb2gray(rgb)
- demeter.utils.toolbox.save_gif_with_plt(image_list, file_name, folder=None, delay=20, duplicate=True, verbose=False, image_args=None, clean=True)
Convert a list og images to a gif
- Parameters:
image_list
file_name – (str) file name withour ‘.gif’ specified
folder – (str) the folder to save the gif, (default: will be saved in
‘gliomorph/figs/gif_box/file_name’ :param delay: (int) millisecond of image duration :param duplicate: (bool) duplicate the first and last frame for longer duration. :return:
- demeter.utils.toolbox.update_progress(progress, message=None)
demeter.utils.torchbox module
- demeter.utils.torchbox.BCH(v, w, order=0)
Evaluate the Backer-Campbell-Hausdorff formula
- class demeter.utils.torchbox.Field_divergence(dx_convention='pixel')
Bases:
Module
- forward(field)
Note: we don’t use the sobel implementation in SpatialGradient to save computation
- class demeter.utils.torchbox.RandomGaussianField(size, n_gaussian, dx_convention, a=None, b=None, c=None)
Bases:
object
Generate a random field made from a sum of N gaussians and compute the theoretical divergence of the field. It is usefully for testing function on random generated fields with known expressions, making it possible to compute theoretical values. It uses the function RandomGaussianImage.
If \(v : \Omega \mapsto \mathbb{R}^d\) for all \(n < d\)
\[v_n = \sum_{i=1}^{N} a_i \exp(- \frac{||X - c_i||^2}{2b_i^2})\]Parameters:
- size: tuple
- tuple with the image dimensions to create (H,W) will create a 2d field of shape (H,W,2),
((D,H,W,3) in 3d)
- n_gaussian: int
Number of gaussians to sum.
- a: list of float
list of the a parameters of the gaussians controlling the amplitude
- b: list of float
list of the b parameters of the gaussians controlling the width
- c: list of float
list of the c parameters of the gaussians controlling the position
- divergence()
- field()
return the field made from the sum of the gaussians : return: torch.Tensor of shape [1,H,W,2] or [1,D,H,W,3]
- class demeter.utils.torchbox.RandomGaussianImage(size, n_gaussians, dx_convention, a=None, b=None, c=None)
Bases:
object
Generate a random image made from a sum of N gaussians and compute the derivative of the image with respect
to the parameters of the gaussians.
self.a[i] * torch.exp(- ((self.X - self.c[i])**2).sum(-1) / (2*self.b[i]**2))
\[I = \sum_{i=1}^{N} a_i \exp(- \frac{||X - c_i||^2}{2b_i^2})\]Parameters:
- size: tuple
tuple with the image dimensions to create
- n_gaussians: int
Number of gaussians to sum.
- dx_convention: str
convention for the grid
- a: list of float
list of the a parameters of the gaussians controling the amplitude
- b: list of float
list of the b parameters of the gaussians controling the width
- c: list of float
list of the c parameters of the gaussians controling the position
Example:
- derivative()
Compute the derivative of the image with respect to the position of the gaussians : return: torch.Tensor of shape [1,2,H,W] of [1,3,D,H,W]
- gaussian(i)
return the gaussian with the parameters a,b,c at pos i :param i: (int) position of the gaussian
- image()
return the image made from the sum of the gaussians : return: torch.Tensor of shape [1,1,H,W] or [1,1,D,H,W]
- demeter.utils.torchbox.addGrid2im(img, n_line, cst=0.1, method='dots')
draw a grid to the image
- Parameters:
img
n_line
cst
method
- Returns:
- demeter.utils.torchbox.checkDiffeo(field)
- demeter.utils.torchbox.compose_fields(field, grid_on, dx_convention='2square')
compose a field on a deformed grid
- demeter.utils.torchbox.deformation_show(deformation, step=2, check_diffeo=False, title='', color=None)
Make a plot showing the deformation.
- Parameters:
deformation (torch.Tensor) – 2D grid tensor of shape (1,H,W,2)
step – Step of the grid (default 2)
int – Step of the grid (default 2)
check_diffeo – Check if the deformation is a diffeomorphism (default False) by showing the sign of the determinant of the Jacobian matrix at each point. green is for positive determinant and red for negative.
bool – Check if the deformation is a diffeomorphism (default False) by showing the sign of the determinant of the Jacobian matrix at each point. green is for positive determinant and red for negative.
title – Title of the plot
str – Title of the plot
color – Color of the grid (default None = black)
str – Color of the grid (default None = black)
- Returns:
None
Example
———-
.. code-block:: python – cms = mbs.getCMS_allcombinaision()
H,W = 100,150 # vector defomation generation v = mbs.field2D_bspline(cms,(H,W),dim_stack=2).unsqueeze(0) v *= 0.5
deform_diff = vff.FieldIntegrator(method=’fast_exp’)(v.clone(),forward= True)
deformation_show(deform_diff,step=4,check_diffeo=True)
- demeter.utils.torchbox.detOfJacobian(jaco)
compute the determinant of the jacobian from field_2d_jacobian
- Parameters:
jaco – B,2,2,H,W tensor B,3,3,D,H,W tensor
- Returns:
B,H,W tensor
- demeter.utils.torchbox.field2diffeo(in_vectField, N=None, save=False, forward=True)
function deprecated; see vector_field_to_flow
- demeter.utils.torchbox.fieldNorm2(field)
- demeter.utils.torchbox.field_2d_hessian(field_grad)
compute the hessian of a field from the jacobian
- Parameters:
field_grad – BxnxpxHxW tensor n = p = 2
- Returns:
Bx8x2xHxW tensor
:example :
hess = field_2d_hessian(I_g) print(‘hess.shape = ‘+str(hess.shape)) fig, axes = plt.subplots(2,4) for x in range(2):
- for d in range(4):
axes[x][d].imshow(hess[0,d,x,:,:].detach().numpy(),cmap=’gray’) axes[x][d].set_title(str((x,d)))
plt.show()
- demeter.utils.torchbox.field_2d_jacobian(field)
compute the jacobian of the field
parameters:
field: field.size (b,h,w,2)
returns:
jacobian of the field.size = (b,2,2,h,w)
- example:
field = torch.zeros((100,100,2)) field[::2,:,0] = 1 field[:,::2,1] = 1 jaco = field_2d_jacobian(field) plt.rc('text',usetex=true) fig, axes = plt.subplots(2,2) axes[0,0].imshow(jaco[0,0,0,:,:].detach().numpy(),cmap='gray') axes[0,0].set_title(r"$\frac{\partial f_1}{\partial x}$") axes[0,1].imshow(jaco[0,0,1,:,:].detach().numpy(),cmap='gray') axes[0,1].set_title(r"$\frac{\partial f_1}{\partial y}$") axes[1,0].imshow(jaco[0,1,0,:,:].detach().numpy(),cmap='gray') axes[1,0].set_title(r"$\frac{\partial f_2}{\partial x}$") axes[1,1].imshow(jaco[0,1,1,:,:].detach().numpy(),cmap='gray') axes[1,1].set_title(r"$\frac{\partial f_2}{\partial y}$") plt.show()
- demeter.utils.torchbox.field_divergence(field, dx_convention='pixel')
make the divergence of a field, for each pixel \(p\) in I
\[div(I(p)) = \sum_{i=1}^C \frac{\partial I(p)_i}{\partial x_i}\]Parameters:
- field: torch.Tensor
of shape (B,H,W,2) or (B,D,H,W,3)
Returns:
- div: torch.Tensor
of shape (B,2,2H,W) or (B,3,3,D,H,W)
Example:
cms = torch.tensor([ # control matrices [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, +1, 0, -1, 0, -1, 0, -1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, +1, 0, -1, 0, +1, 0, +1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, +1, 0, +1, 0, -1, 0, +1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, -1, 0, -1, 0, -1, 0, +1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], ], [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, +1, 0, +1, 0, -1, 0, +1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],#[0, .2, .75, 1, 0], [0, -1, 0, -1, 0, -1, 0, +1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, +1, 0, -1, 0, -1, 0, -1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, +1, 0, -1, 0, +1, 0, +1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]] ],requires_grad=False,dtype=torch.float) field_size = (20,20) field = mbs.field2D_bspline(cms,field_size, degree=(3,3),dim_stack=2).unsqueeze(0) # field_diff = vect_spline_diffeo(cms,field_size) H,W = field_size xx, yy = torch.meshgrid(torch.linspace(-1, 1, H), torch.linspace(-1, 1, W)) div = field_2d_divergence(field) # _,d_ax = plt.subplots() fig,ax = plt.subplots() div_plot = ax.imshow(div[0,0,:,:],origin='lower') ax.quiver(field[0,:,:,0],field[0,:,:,1]) fig.colorbar(div_plot) plt.show()
- demeter.utils.torchbox.find_binary_center(bool_img)
- demeter.utils.torchbox.format_sigmas(sigmas, dim)
- demeter.utils.torchbox.geodesic_3d_slider(mr)
Display a 3d image
exemple: mr = mt.load_optimize_geodesicShooting(‘2D_13_10_2021_m0t_m1_001.pk1’) geodesic_3d_slider(mr)
- demeter.utils.torchbox.get_sobel_kernel_2d()
- demeter.utils.torchbox.get_sobel_kernel_3d()
- demeter.utils.torchbox.grid2im(grid)
Reshape a grid tensor into an image tensor
- -2D
[T,H,W,2] -> [T,2,H,W]
- -3D
[T,D,H,W,3] -> [T,3,D,H,W]
# grid to image T,D,H,W = (4,5,6,7) grid_2D = torch.rand((T,H,W,2)) grid_3D = torch.rand((T,D,H,W,3)) image_2D = torch.rand((T,2,H,W)) image_3D = torch.rand((T,3,D,H,W)) grid_2D_as_image = grid2im(grid_2D) grid_3D_as_image = grid2im(grid_3D) # check if the method works print('
- GRID TO IMAGE’)
print(’ ==== 2D ====
- ‘)
print(‘grid_2D.shape =’,grid_2D.shape) print(‘grid_2D_as_image.shape =’,grid_2D_as_image.shape) print(‘we have indeed the good shape’) count = 0 for i in range(T):
count += (grid_2D[i,…,0] == grid_2D_as_image[i,0,…]).sum() count += (grid_2D[i,…,1] == grid_2D_as_image[i,1,…]).sum()
print(‘count is equal to ‘,count/(T*H*W*2),’and should be equal to 1’)
print(’
==== 3D ==== ‘)
print(‘grid_3D.shape =’,grid_3D.shape) print(‘grid_3D_as_image.shape =’,grid_3D_as_image.shape) print(‘we have indeed the good shape’) count = 0 for i in range(T):
count += (grid_3D[i,…,0] == grid_3D_as_image[i,0,…]).sum() count += (grid_3D[i,…,1] == grid_3D_as_image[i,1,…]).sum() count += (grid_3D[i,…,2] == grid_3D_as_image[i,2,…]).sum()
print(‘count is equal to ‘,count/(T*H*W*D*3),’and should be equal to 1’)
- demeter.utils.torchbox.gridDef_plot(defomation, ax=None, step=2, add_grid=False, check_diffeo=False, title='', color=None, dx_convention='pixel')
- demeter.utils.torchbox.gridDef_plot_2d(deformation: Tensor, ax=None, step: int | tuple[int] = 2, add_grid: bool = False, check_diffeo: bool = False, dx_convention: str = 'pixel', title: str = '', **kwargs)
Plot the deformation field as a grid.
- Parameters:
deformation – torch.Tensor of shape (1,H,W,2)
ax – matplotlib axis object, if None, the plot makes one new (default None)
step – int | Tuple[int], step of the grid (default 2)
add_grid – (bool), to use if ̀defomation` is a field (default False).
If True, add a regular grid to the field. :param check_diffeo: (bool), check if the deformation is a diffeomorphism (default False) :param dx_convention: (str) convention of the deformation field (default ‘pixel’) :param title: (str) title of the plot :param color: (str) color of the grid (default None = black) :param linewidth: (int) width of the grid lines (default None = 2) :param origin: (str) origin of the plot (default ‘lower’)
- Returns:
matplotlib axis object
- demeter.utils.torchbox.im2grid(image)
Reshape an image tensor into a grid tensor
2D case [T,2,H,W] -> [T,H,W,2]
3D case [T,3,D,H,W] -> [T,D,H,W,3]
T,D,H,W = (4,5,6,7) grid_2D = torch.rand((T,H,W,2)) grid_3D = torch.rand((T,D,H,W,3)) image_2D = torch.rand((T,2,H,W)) image_3D = torch.rand((T,3,D,H,W)) # image to grid image_2D_as_grid = im2grid(image_2D) image_3D_as_grid = im2grid(image_3D) print('
- IMAGE TO GRID’)
print(’ ==== 2D ====
- ‘)
print(‘image_2D.shape = ‘,image_2D.shape) print(‘image_2D_as_grid.shape = ‘,image_2D_as_grid.shape)
count = 0 for i in range(T):
count += (image_2D[i,0,…] == image_2D_as_grid[i,…,0]).sum() count += (image_2D[i,1,…] == image_2D_as_grid[i,…,1]).sum()
print(‘count is equal to ‘,count/(T*H*W*2),’and should be equal to 1’)
print(’ ==== 3D ====
- ‘)
print(‘image_3D.shape = ‘,image_3D.shape) print(‘image_3D_as_grid.shape = ‘,image_3D_as_grid.shape)
count = 0 for i in range(T):
count += (image_3D[i,0,…] == image_3D_as_grid[i,…,0]).sum() count += (image_3D[i,1,…] == image_3D_as_grid[i,…,1]).sum() count += (image_3D[i,2,…] == image_3D_as_grid[i,…,2]).sum()
print(‘count is equal to ‘,count/(T*H*W*D*3.0),’and should be equal to 1’)
- demeter.utils.torchbox.imCmp(I1, I2, method=None)
Stack two gray-scales images to compare them. The images must have the same height and width and depth (for 3d). Note: Images can NOT be temporal meaning that they have a time dimension stored in the first dimension. For this usage see temporal_img_cmp.
- Parameters:
I1 (torch.Tensor) – [B,C,H,W] or [B,C,K,H,W] tensor C = 1, B = 1
I2 (torch.Tensor) – [B,C,H,W] or [B,C,K,H,W] tensor C = 1, B = 1
method (str) – method to compare the images, among {‘compose’,’seg’,’segw’,’segh’}
- demeter.utils.torchbox.image_slice(I, coord, dim)
Return a slice of the image I at the given coordinate and dimension
- Parameters:
I – [H,W,D] numpy array or tensor
coord – int coordinate of the slice, if float it will be casted to int
dim – int in {0,1,2} dimension of the slice
- demeter.utils.torchbox.imgDeform(img, deform_grid, dx_convention='2square', clamp=False)
Apply a deformation grid to an image
- Parameters:
img (torch.Tensor of shape [B,C,H,W] or [B,C,D,H,W]) – image to deform
deform_grid (torch.Tensor of shape [B,H,W,2] or [B,D,H,W,3]) – deformation grid
dx_convention (str, optional) – convention of the deformation grid (default ‘2square’)
clamp (bool, optional) – if True, clamp the image between 0 and 1 if the max value is less than 1 else between 0 and 255 (default False)
- Returns:
deformed image of shape [B,C,H,W] or [B,C,D,H,W]
- Return type:
torch.Tensor
- demeter.utils.torchbox.is_tensor(input)
- demeter.utils.torchbox.leviCivita_2Dderivative(v, w)
Perform the opetation \(\nabla_v w\) in 2D
- demeter.utils.torchbox.lieBracket(v, w)
- demeter.utils.torchbox.make_3d_flat(img_3D, slice)
- demeter.utils.torchbox.make_ball_at_shape_center(img, shape_binarization=None, overlap_threshold=0.1, r_min=None, force_r=None, force_center=None, verbose=False)
Create a ball centered at the center of the shape in the image. The shape is defined by the binarisation of the image for the pixels having the value shape_value.
- Parameters:
img (torch.Tensor) – [B,C,H,W] or [B,C,D,H,W] or [H,W] or [D,H,W] The image where the ball will be created.
shape_binarization (torch.Tensor, optional) –
a tensor of the same shape as img, being the binarization of the shape to create the ball. If None, the shape is defined by the pixels having the
max value in the image.
overlap_threshold (float, optional) – The percentage of overlap between the shape and the ball. The default is 0.1.
r_min (int, optional) – The minimum radius of the ball. The default is None.
force_r (int, optional) – The radius of the ball. The default is None.
force_center (tuple, optional) – The center of the ball. The default is None.
verbose (bool, optional) – Print the center, the radius and the overlap between the shape and the ball.
- Returns:
ball (torch.Tensor) – The ball as a bool mask of the same shape as img.
centre (tuple) – The center of the ball and the radius. if 2d (c1,c2,r) if 3d (c1,c2,c3,r)
- demeter.utils.torchbox.make_regular_grid(deformation_shape, dx_convention='pixel', device=device(type='cpu'))
API to create_meshgrid, it is the identity deformation
- Parameters:
deformation_shape (tuple) – tuple such as (H,W) or (n,H,W,2) for 2D grid (D,H,W) or (n,D,H,W,3) for 3D gridim2
device (torch.device) – device for selecting cpu or cuda usage
- Returns:
grid – 2D identity deformation with size (1,H,W,2) or 3D identity deformation with size (1,D,H,W,3)
- Return type:
torch.Tensor
- demeter.utils.torchbox.pad_to_same_size(img_1, img_2)
Pad the two images in order to make images of the same size takes
- Parameters:
img_1 – [T_1,C,D_1,H_1,W_1] or [D_1,H_1,W_1] torch tensor
img_2 – [T_2,C,D_2,H_2,W_2] or [D_2,H_2,W_2] torch tensor
- Returns:
will return both images with of shape
[…,max(D_1,D_2),max(H_1,H_2),max(W_1,W_2)] in a tuple.
- demeter.utils.torchbox.pixel_to_2square_convention(field, is_grid=True)
Convert a field in spatial pixelic convention in one on as [-1,1]^2 square as requested by pytorch’s gridSample
- Parameters:
field (torch.Tensor) – of size [T,H,W,2] or [T,D,H,W,3]
is_grid (bool) – if True field is considered as a deformation (i.e.: field = (id + v)) else field is a vector field (i.e.: field = v) (default is True)
- Returns:
field – of size [T,H,W,2] or [T,D,H,W,3]
- Return type:
torch.Tensor
- demeter.utils.torchbox.pixel_to_square_convention(field, is_grid=True)
convert from the pixel convention to the square one, meaning: \([0,W-1]\times[0,H-1] \mapsto [-1,1]^d\)
- Parameters:
field (torch.Tensor)
[T (2] or)
H
W
[T
D
H
W
3]
is_grid (bool)
function (useless in this)
converters (kept for consistency with others)
- Returns:
field (torch.Tensor)
of size [T,H,W,2] or [T,D,H,W,3]
- demeter.utils.torchbox.quiver_plot(field, ax=None, step=2, title='', check_diffeo=False, color=None, dx_convention='pixel', real_scale=True, remove_grid=False)
Plot the deformation field as a quiver plot.
- Parameters:
field (torch.Tensor) – 2D tensor of shape (1,H,W,2)
ax (matplotlib axis object, optional) – If None, the plot makes one new (default None)
step (int, optional) – Step of the grid (default 2)
title (str, optional) – Title of the plot
check_diffeo (bool, optional) – Check if the deformation is a diffeomorphism (default False) by displaying the sign of the determinant of the Jacobian matrix at each point.
color (str, optional) – Color of the grid (default None = black)
dx_convention (str, optional) – Convention of the deformation field (default ‘pixel’)
real_scale (bool, optional) – If True, plot quiver arrow with axis scale (default True)
remove_grid (bool, optional) – If True, field is considered as a deformortion and the regular grid is removed from field (default False)
- Returns:
ax – Axis object
- Return type:
matplotlib
- demeter.utils.torchbox.reg_open(number, size=None, requires_grad=False, device='cpu')
- demeter.utils.torchbox.resize_image(image: Tensor | list[Tensor], scale_factor: float | int | Iterable = None, to_shape=None)
Resize an image by a scale factor \(s = (s1,s2,s3)\) or set it to shape given by to_shape.
- Parameters:
image – list of tensors [B,C,H,W] or [B,C,D,H,W] torch tensor
scale_factor – float or list or tuple of image dimension size
to_shape – Resize the image to the given shape. Tuple of image dimension size (nD,nH,nW)
Note
Please provide only scale_factor OR to_shape. If to_shape is not None, scale_factor will be ignored.
: return: tensor of size [B,C,s1*H,s2*W] or [B,C,s1*D, s2*H, s3*W] or list containing tensors.
- demeter.utils.torchbox.spatialGradient(image, dx_convention='pixel')
Compute the spatial gradient on 2d and 3d images by applying a sobel kernel. Perform the normalisation of the gradient according to the spatial convention (dx_convention) and make it the closer possible to the theoretical gradient.
- Parameters:
image (Tensor) – [B,C,H,W] or [B,C,D,H,W] tensor.
dx_convention (str or tensor) – If str, it must be in {‘pixel’,’square’,’2square’}. If tensor, it must be of shape [B,2] or [B,3], where B is the batch size and the second dimension is the spatial resolution of the image giving the pixel size. Attention : this last values must be in reverse order of the image shape.
- Returns:
grad_image – [B,C,2,H,W] or [B,C,3,D,H,W] tensor.
- Return type:
Tensor
Examples
H,W = (300,400) rgi = tb.RandomGaussianImage((H, W), 2, 'square', a=[-1, 1], b=[15, 25], c=[[.3*400 , .3*300], [.7*400, .7*300]]) image = rgi.image() theoretical_derivative = rgi.derivative() print(f"image shape : {image.shape}") derivative = tb.spatialGradient(image, dx_convention="square") dx = torch.tensor([[1. / (W - 1), 1. / (H - 1)]], dtype=torch.float64) derivative_2 = tb.spatialGradient(mage, dx_convention=dx)
- demeter.utils.torchbox.spatialGradient_2d(image, dx_convention='pixel')
Compute the spatial gradient on 2d images by applying a sobel kernel
- Parameters:
image – Tensor [B,C,H,W]
dx_convention
- Returns:
[B,C,2,H,W]
- demeter.utils.torchbox.spatialGradient_3d(image, dx_convention='pixel')
Compute the spatial gradient on 3d images by applying a sobel kernel
- Parameters:
image (Tensor) – [B,C,D,H,W] tensor
dx_convention (str or tensor) – If str, it must be in {‘pixel’,’square’,’2square’}.
Example
H,W,D = (50,75,100) image = torch.zeros((H,W,D)) mX,mY,mZ = torch.meshgrid(torch.arange(H), torch.arange(W), torch.arange(D)) mask_rond = ((mX - H//2)**2 + (mY - W//2)**2).sqrt() < H//4 mask_carre = (mX > H//4) & (mX < 3*H//4) & (mZ > D//4) & (mZ < 3*D//4) mask_diamand = ((mY - W//2).abs() + (mZ - D//2).abs()) < W//4 mask = mask_rond & mask_carre & mask_diamand image[mask] = 1 grad_image = spacialGradient_3d(image[None,None]) # grad_image_sum = grad_image.abs().sum(dim=1) # iv3d.imshow_3d_slider(grad_image_sum[0])
- demeter.utils.torchbox.square2_to_pixel_convention(field, is_grid=True)
Convert a field on a square centred and from -1 to 1 convention as requested by pytorch’s gridSample to one in pixelic convention
- Parameters:
field (torch.Tensor) – of size [T,H,W,2] or [T,D,H,W,3]
is_grid (bool) – if True field is considered as a deformation (i.e.: field = (id + v)) else field is a vector field (i.e.: field = v) (default is True)
- Returns:
field – of size [T,H,W,2] or [T,D,H,W,3]
- Return type:
torch.Tensor
- demeter.utils.torchbox.square2_to_square_convention(field, is_grid=True)
convert from the 2square convention to the square one, meaning: \([-1,1]^d \mapsto [0,1]^d\)
- Parameters:
field (torch.Tensor) – of size [T,H,W,2] or [T,D,H,W,3]
is_grid (bool) – Must be True if field is a grid+vector field and False if a vector field only
- Returns:
field (torch.Tensor)
of size [T,H,W,2] or [T,D,H,W,3]
- demeter.utils.torchbox.square_to_2square_convention(field, is_grid=True)
convert from the square convention to the 2square one, meaning: \([0,1]^d \mapsto [-1,1]^d\)
- Parameters:
field (torch.Tensor) – of size [T,H,W,2] or [T,D,H,W,3]
is_grid (bool) – Must be True if field is a grid+vector field and False if a vector field only
- Returns:
field (torch.Tensor)
of size [T,H,W,2] or [T,D,H,W,3]
- demeter.utils.torchbox.square_to_pixel_convention(field, is_grid=True)
convert from the square convention to the pixel one, meaning: \([-1,1]^d \mapsto [0,W-1]\times[0,H-1]\)
- Parameters:
field (torch.Tensor)
[T (2] or)
H
W
[T
D
H
W
3]
is_grid (bool)
function (useless in this)
converters (kept for consistency with others)
- Returns:
field (torch.Tensor)
of size [T,H,W,2] or [T,D,H,W,3]
- demeter.utils.torchbox.temporal_img_cmp(img_1, img2, method='compose')
Stack two gray-scales images to compare them. The images must have the same height and width and depth (for 3d). Images can be temporal meaning that they have a time dimension stored in the first dimension.
- Parameters:
img_1 (torch.Tensor) – [T_1,C,H,W] or [T_1,C,D,H,W] tensor C = 1
img2 (torch.Tensor) – [T_2,C,H,W] or [T_2,C,D,H,W] tensor C = 1
note (..) – T_1 = 1 and T_2 > 1 or T_1 > 1 and T_2 = 1 or T_1 = T_2 > 1 works, any other case will raise an error.
method (str) – method to compare the images, among {‘compose’,’seg’,’segw’,’segh’}
- demeter.utils.torchbox.thresholding(image, bounds=(0, 1))
- demeter.utils.torchbox.vectField_show(field, step=2, check_diffeo=False, title='', dx_convention='pixel')
- Parameters:
field – (1,H,W,2) tensor object
step
check_diffeo – (bool)
- Returns:
Example :
>>>cms = mbs.getCMS_allcombinaision() >>> >>>H,W = 100,150 >>># vector defomation generation >>>v = mbs.field2D_bspline(cms,(H,W),dim_stack=2).unsqueeze(0) >>>v *= 0.5 >>> >>>vectField_show(v,step=4,check_diffeo=True)
- demeter.utils.torchbox.vect_spline_diffeo(control_matrix, field_size, N=None, forward=True)
demeter.utils.vector_field_to_flow module
- class demeter.utils.vector_field_to_flow.FieldIntegrator(method, save=False, N=None, dx_convention='pixel')
Bases:
object