U PhE@sdZddlmZddlmZddlmZddlZddl Z ddl m Z m Z ddl mZddlmZdd lmZdd lmZmZdd lmZdd lmZmZmZdd lmZddlmZddl m!Z!m"Z"ddddgZ#GdddeZ$GdddeZ%GdddeZ&GdddeZ'dS)zbTransforms using a smooth spatial field generated by interpolating from smaller randomized fields.) annotations)Sequence)AnyN) grid_sample interpolate)NdarrayOrTensor)get_track_meta) meshgrid_ij) RandomizableRandomizableTransform)moveaxis)GridSampleModeGridSamplePadModeInterpolateMode)TransformBackends)look_up_option)convert_to_dst_typeconvert_to_tensor SmoothFieldRandSmoothFieldAdjustContrastRandSmoothFieldAdjustIntensityRandSmoothDeformc @seZdZdZejgZddddddejddf ddd d d dd d d d d ddZ d!dddddZ d ddddZ d ddddZ d"dddd Z dS)#ra Generate a smooth field array by defining a smaller randomized field and then reinterpolating to the desired size. This exploits interpolation to create a smoothly varying field used for other applications. An initial randomized field is defined with `rand_size` dimensions with `pad` number of values padding it along each dimension using `pad_val` as the value. If `spatial_size` is given this is interpolated to that size, otherwise if None the random array is produced uninterpolated. The output is always a Pytorch tensor allocated on the specified device. Args: rand_size: size of the randomized field to start from pad: number of pixels/voxels along the edges of the field to pad with `pad_val` pad_val: value with which to pad field edges low: low value for randomized field high: high value for randomized field channels: number of channels of final output spatial_size: final output size of the array, None to produce original uninterpolated field mode: interpolation mode for resizing the field align_corners: if True align the corners when upsampling field device: Pytorch device to define field on rg?N Sequence[int]intfloatzSequence[int] | Nonestr bool | Nonetorch.device | None rand_sizepadpad_vallowhighchannels spatial_sizemode align_cornersdevicec st|_|_|_|_|_|_| _| _d_ d_ ||krPt dtfddjD_ t jdjfj jd|_jfj_jdkrtdntjj } dtdf| ftj_|dS)NzFValue for `low` must be less than `high` otherwise field will be zerosc3s|]}|jdVqdS)N)r").0rsselfX/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/transforms/smooth_field/array.py Wsz'SmoothField.__init__..r)r*r)tupler!r"r$r%r&r(r)r*r' spatial_zoom ValueErrortotal_rand_sizetorchonesfield crand_sizeslicelen rand_slicesset_spatial_size) r/r!r"r#r$r%r&r'r(r)r*Z pad_slicer0r.r1__init__;s$ ""zSmoothField.__init__ Any | NoneNonedatareturncCs(t|j|j|j|j|j|j<dSN) r7 from_numpyRuniformr$r%r:r9r=r/rCr0r0r1 randomizebszSmoothField.randomize)r'rDcCsB|dkrd|_d|_n(t||_tddt|j|jD|_dS)a  Set the `spatial_size` and `spatial_zoom` attributes used for interpolating the field to the given dimension, or not interpolate at all if None. Args: spatial_size: new size to interpolate to, or None to not interpolate Ncss|]\}}||VqdSrEr0)r,sfr0r0r1r2rsz/SmoothField.set_spatial_size..)r'r4r3zipr6)r/r'r0r0r1r>es  zSmoothField.set_spatial_sizer(rDcCs ||_dSrE)r(r/r(r0r0r1set_modetszSmoothField.set_modeFz torch.Tensor)rDc Cs|r ||j}|jdk rt||jt|jt|jdd}| }| }|j }|j }| d| ||}| |||}|S)NF)input scale_factorr(r)recompute_scale_factorr)rJr9cloner4rrr(rr)minmaxsqueezediv_mul_add_) r/rJr9Z resized_fieldminamaxaminvmaxvZ norm_fieldr0r0r1__call__ws$     zSmoothField.__call__)N)F)__name__ __module__ __qualname____doc__rTORCHbackendrAREAr?rJr>rPr_r0r0r0r1r#s "'c seZdZdZejgZdejddddfddddd d d d d fdd Z d#ddddfdd Z d$dddfdd Z dddddZ d%dddd d!d"Z ZS)&ra Randomly adjust the contrast of input images by calculating a randomized smooth field for each invocation. This uses SmoothField internally to define the adjustment over the image. If `pad` is greater than 0 the edges of the input volume of that width will be mostly unchanged. Contrast is changed by raising input values by the power of the smooth field so the range of values given by `gamma` should be chosen with this in mind. For example, a minimum value of 0 in `gamma` will produce white areas so this should be avoided. After the contrast is adjusted the values of the result are rescaled to the range of the original input. Args: spatial_size: size of input array's spatial dimensions rand_size: size of the randomized field to start from pad: number of pixels/voxels along the edges of the field to pad with 1 mode: interpolation mode to use when upsampling align_corners: if True align the corners when upsampling field prob: probability transform is applied gamma: (min, max) range for exponential field device: Pytorch device to define field on rN皙?)?g@rrrrrSequence[float] | floatrr'r!r"r(r)probgammar*c szt|t|ttfr&d|f|_n&t|dkr:tdt|t |f|_t ||d|jd|jdd||||d |_ dSNrhr+z7Argument `gamma` should be a number or pair of numbers.rrr superr? isinstancerrrlr<r5rUrVrsfield r/r'r!r"r(r)rkrlr* __class__r0r1r?s$   z&RandSmoothFieldAdjustContrast.__init__ int | Nonenp.random.RandomState | NoneseedstaterDcs t|||j|||SrEroset_random_staterqr/rxryrsr0r1r{sz.RandSmoothFieldAdjustContrast.set_random_stater@rArBcs td|jr|jdSrErorJ _do_transformrqrIrsr0r1rJs z'RandSmoothFieldAdjustContrast.randomizerNcCs|j|dSrErqrPrOr0r0r1rPsz&RandSmoothFieldAdjustContrast.set_modeTrboolimgrJrDc Cszt|td}|r||js$|S|}|}||}|}t||^}}|||d}||}|||} | S){ Apply the transform to `img`, if `randomize` randomizing the smooth field otherwise reusing the previous.  track_metag|=)rrrJr~rUrVrqr) r/rrJimg_minimg_maxZimg_rngr9rfield_outr0r0r1r_s z&RandSmoothFieldAdjustContrast.__call__)NN)N)Tr`rarbrcrrdrerrfr?r{rJrPr_ __classcell__r0r0rsr1rs"#c seZdZdZejgZdejddddfddddd d d d d fdd Z d#ddddfdd Z d$dddfdd Z dddddZ d%dddd d!d"Z ZS)&ra+ Randomly adjust the intensity of input images by calculating a randomized smooth field for each invocation. This uses SmoothField internally to define the adjustment over the image. If `pad` is greater than 0 the edges of the input volume of that width will be mostly unchanged. Intensity is changed by multiplying the inputs by the smooth field, so the values of `gamma` should be chosen with this in mind. The default values of `(0.1, 1.0)` are sensible in that values will not be zeroed out by the field nor multiplied greater than the original value range. Args: spatial_size: size of input array rand_size: size of the randomized field to start from pad: number of pixels/voxels along the edges of the field to pad with 1 mode: interpolation mode to use when upsampling align_corners: if True align the corners when upsampling field prob: probability transform is applied gamma: (min, max) range of intensity multipliers device: Pytorch device to define field on rNrg)rgrrrrrrrirrjc szt|t|ttfr&d|f|_n&t|dkr:tdt|t |f|_t ||d|jd|jdd||||d |_ dSrmrnrrrsr0r1r?s$   z'RandSmoothFieldAdjustIntensity.__init__rurvrwcs t|||j|||SrErzr|rsr0r1r{0sz/RandSmoothFieldAdjustIntensity.set_random_stater@rArBcs td|jr|jdSrEr}rIrsr0r1rJ7s z(RandSmoothFieldAdjustIntensity.randomizerNcCs|j|dSrErrOr0r0r1rP=sz'RandSmoothFieldAdjustIntensity.set_modeTrrrcCsFt|td}|r||js$|S|}t||^}}||}|S)rr)rrrJr~rqr)r/rrJr9rrrr0r0r1r_@sz'RandSmoothFieldAdjustIntensity.__call__)NN)N)Trr0r0rsr1rs"#c seZdZdZejgZdejddde j e j e jddf dddd d d d d d d d d fdd Zd'ddddfdd Zd(dddfdd Zd ddddZd dddd Zd)d"d#d d"d$d%d&ZZS)*ra` Deform an image using a random smooth field and Pytorch's grid_sample. The amount of deformation is given by `def_range` in fractions of the size of the image. The size of each dimension of the input image is always defined as 2 regardless of actual image voxel dimensions, that is the coordinates in every dimension range from -1 to 1. A value of 0.1 means pixels/voxels can be moved by up to 5% of the image's size. Args: spatial_size: input array size to which deformation grid is interpolated rand_size: size of the randomized field to start from pad: number of pixels/voxels along the edges of the field to pad with 0 field_mode: interpolation mode to use when upsampling the deformation field align_corners: if True align the corners when upsampling field prob: probability transform is applied def_range: value of the deformation range in image size fractions, single min/max value or min/max pair grid_dtype: type for the deformation grid calculated from the field grid_mode: interpolation mode used for sampling input using deformation grid grid_padding_mode: padding mode used for sampling input using deformation grid grid_align_corners: if True align the corners when sampling the deformation grid device: Pytorch device to define field on rNrgrFrrrrrrir) r'r!r" field_moder)rk def_range grid_modegrid_padding_modegrid_align_cornersr*c  st|||_| |_||_| |_| |_| |_t|t t frL| |f|_n&t |dkr`t dt |t|f|_t||||jd|jdt |||| d |_|dk rt|n|jjjdd} dd| D}t|}t|d|j|j|_dS)Nr+z;Argument `def_range` should be a number or pair of numbers.rr) r'r!r"r$r%r&r(r)r*cSsg|]}tdd|qS)r)r7linspace)r,dr0r0r1 sz-RandSmoothDeform.__init__..)ror? grid_dtyperrr*rrrprrr<r5rUrVrrqr3r9shaper r7stack unsqueezetogrid)r/r'r!r"rr)rkrrrrrr*Z grid_spaceZ grid_rangesrrsr0r1r?os6   "zRandSmoothDeform.__init__rurvr rwcs t|||j|||SrErzr|rsr0r1r{sz!RandSmoothDeform.set_random_stater@rArBcs td|jr|jdSrEr}rIrsr0r1rJs zRandSmoothDeform.randomizerNcCs|j|dSrErrOr0r0r1set_field_modeszRandSmoothDeform.set_field_modecCs ||_dSrE)rrOr0r0r1 set_grid_modeszRandSmoothDeform.set_grid_modeTrr)rrJr*rDc Cst|td}|r||js$|S|dk r0|n|j}|}|j||j}t |dd}|dt t |j ddddf}t|dt j|}t||t|jt|jt|jtd}t|d|^}} |S)Nrrr.)rQrr(r) padding_moder)rrrJr~r*rqrrrr listrangerr7float32rrrr rrrrrW) r/rrJr*r9Zdgridimg_trout_trr0r0r1r_s( "  zRandSmoothDeform.__call__)NN)N)TN)r`rarbrcrrdrerrfr7rr NEARESTrBORDERr?r{rJrrr_rr0r0rsr1rVs((3)(rc __future__rcollections.abcrtypingrnumpynpr7torch.nn.functionalrrmonai.config.type_definitionsrmonai.data.meta_objrmonai.networks.utilsr monai.transforms.transformr r 0monai.transforms.utils_pytorch_numpy_unificationr monai.utilsr rrmonai.utils.enumsrmonai.utils.modulermonai.utils.type_conversionrr__all__rrrrr0r0r0r1 s(          oe_