Source code for ants.registration.build_template

__all__ = ["build_template"]

import numpy as np
import os
from tempfile import mktemp

from .reflect_image import reflect_image
from .interface import registration
from .apply_transforms import apply_transforms
from .resample_image import resample_image_to_target
from ..core import ants_image_io as iio
from ..core import ants_transform_io as tio
from .. import utils

[docs]def build_template( initial_template=None, image_list=None, iterations=3, gradient_step=0.2, blending_weight=0.75, weights=None, useNoRigid=True, **kwargs ): """ Estimate an optimal template from an input image_list ANTsR function: N/A Arguments --------- initial_template : ANTsImage initialization for the template building image_list : ANTsImages images from which to estimate template iterations : integer number of template building iterations gradient_step : scalar for shape update gradient blending_weight : scalar weight for image blending weights : vector weight for each input image useNoRigid : boolean equivalent of -y in the script. Template update step will not use the rigid component if this is True. kwargs : keyword args extra arguments passed to ants registration Returns ------- ANTsImage Example ------- >>> import ants >>> image = ants.image_read( ants.get_ants_data('r16') ) >>> image2 = ants.image_read( ants.get_ants_data('r27') ) >>> image3 = ants.image_read( ants.get_ants_data('r85') ) >>> timage = ants.build_template( image_list = ( image, image2, image3 ) ).resample_image( (45,45)) >>> timagew = ants.build_template( image_list = ( image, image2, image3 ), weights = (5,1,1) ) """ if "type_of_transform" not in kwargs: type_of_transform = "SyN" else: type_of_transform = kwargs.pop("type_of_transform") if weights is None: weights = np.repeat(1.0 / len(image_list), len(image_list)) weights = [x / sum(weights) for x in weights] if initial_template is None: initial_template = image_list[0] * 0 for i in range(len(image_list)): temp = image_list[i] * weights[i] temp = resample_image_to_target(temp, initial_template) initial_template = initial_template + temp xavg = initial_template.clone() for i in range(iterations): affinelist = [] for k in range(len(image_list)): w1 = registration( xavg, image_list[k], type_of_transform=type_of_transform, **kwargs ) L = len(w1["fwdtransforms"]) # affine is the last one affinelist.append(w1["fwdtransforms"][L-1]) if k == 0: if L == 2: wavg = iio.image_read(w1["fwdtransforms"][0]) * weights[k] xavgNew = w1["warpedmovout"] * weights[k] else: if L == 2: wavg = wavg + iio.image_read(w1["fwdtransforms"][0]) * weights[k] xavgNew = xavgNew + w1["warpedmovout"] * weights[k] if useNoRigid: avgaffine = utils.average_affine_transform_no_rigid(affinelist) else: avgaffine = utils.average_affine_transform(affinelist) afffn = mktemp(suffix=".mat") tio.write_transform(avgaffine, afffn) if L == 2: print(wavg.abs().mean()) wscl = (-1.0) * gradient_step wavg = wavg * wscl # apply affine to the nonlinear? # need to save the average wavgA = apply_transforms(fixed = xavgNew, moving = wavg, imagetype=1, transformlist=afffn, whichtoinvert=[1]) wavgfn = mktemp(suffix=".nii.gz") iio.image_write(wavgA, wavgfn) xavg = apply_transforms(fixed=xavgNew, moving=xavgNew, transformlist=[wavgfn, afffn], whichtoinvert=[0, 1]) else: xavg = apply_transforms(fixed=xavgNew, moving=xavgNew, transformlist=[afffn], whichtoinvert=[1]) os.remove(afffn) if blending_weight is not None: xavg = xavg * blending_weight + utils.iMath(xavg, "Sharpen") * ( 1.0 - blending_weight ) return xavg