U Ph8o @sZddlmZddlZddlmZddlmZddlZddlm m Z ddlm Z ddl m Z ddlmZddlmZdd lmZdd lmZmZmZmZmZmZmZmZed \ZZed \ZZd dddddddddddg Z Gdd d e j!Z"Gddde j!Z#Gddde j!Z$Gddde j!Z%dddd d d!d dd"d#d$Z&dDddddd&d'dZ'dddd(d)dZ(Gd*dde j!Z)Gd+dde j!Z*ej+dfd,dd-d.d/Z,dEdd,d d2dd3d4dZ-Gd5dde j!Z.Gd6dde j!Z/Gd7d8d8e Z0Gd9dde j!Z1Gd:d;d;e j!Z2Gdd?d?e2Z4Gd@dAdAe2Z5GdBdCdCe5Z6dS)F) annotationsNdeepcopy)Sequence)nn)Function)NdarrayOrTensor) gaussian_1d)Conv)ChannelMatchingSkipModeconvert_to_tensorensure_tuple_repissequenceiterablelook_up_optionoptional_import pytorch_afterzmonai._Cz torch.fft ChannelPadFlattenGaussianFilterHilbertTransformLLTM MedianFilterReshapeSavitzkyGolayFilterSkipConnection apply_filter median_filterseparable_filteringcsBeZdZdZejfdddddfdd Zdddd d ZZS) rz Expand the input tensor's channel dimension from length `in_channels` to `out_channels`, by padding or a projection. intzChannelMatching | str) spatial_dims in_channels out_channelsmodec std|_d|_||kr"dSt|t}|tjkrXttj|f}|||dd|_dS|tj kr||krrt d||d}|||}ddg|||gddg}t ||_dSdS)a Args: spatial_dims: number of spatial dimensions of the input image. in_channels: number of input channels. out_channels: number of output channels. mode: {``"pad"``, ``"project"``} Specifies handling residual branch and conv branch channel mismatches. Defaults to ``"pad"``. - ``"pad"``: with zero padding. - ``"project"``: with a trainable conv with kernel size one. N) kernel_sizezKIncompatible values: channel_matching="pad" and in_channels > out_channels.r) super__init__projectpadrr PROJECTr ZCONVPAD ValueErrortuple) selfr r!r"r# conv_typeZpad_1Zpad_2r* __class__W/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/networks/layers/simplelayers.pyr(>s$       zChannelPad.__init__ torch.TensorxreturncCs6|jdk rt||S|jdk r2t||jS|SN)r)torch as_tensorr*Fr/r7r3r3r4forward`s   zChannelPad.forward) __name__ __module__ __qualname____doc__r r,r(r> __classcell__r3r3r1r4r8s"cs<eZdZdZdddddfdd Zd d d d d ZZS)rz Combine the forward pass input with the result from the given submodule:: --+--submodule--o-- |_____________| The available modes are ``"cat"``, ``"add"``, ``"mul"``. r$catrzstr | SkipModeNone)dimr#r8cs(t||_||_t|tj|_dS)a Args: submodule: the module defines the trainable branch. dim: the dimension over which the tensors are concatenated. Used when mode is ``"cat"``. mode: ``"cat"``, ``"add"``, ``"mul"``. defaults to ``"cat"``. N)r'r( submodulerFrr valuer#)r/rGrFr#r1r3r4r(rs zSkipConnection.__init__r5r6cCsj||}|jdkr(tj||g|jdS|jdkr>t||S|jdkrTt||Std|jddS)NrDrFaddmulzUnsupported mode .)rGr#r:rDrFrJrKNotImplementedError)r/r7yr3r3r4r>s      zSkipConnection.forward)r$rDr?r@rArBr(r>rCr3r3r1r4rhs c@s eZdZdZdddddZdS)rzM Flattens the given input in the forward pass to be [B,-1] in shape. r5r6cCs||ddS)Nr)viewsizer=r3r3r4r>szFlatten.forwardN)r?r@rArBr>r3r3r3r4rscs8eZdZdZdddfdd Zdddd d ZZS) rzk Reshapes input tensors to the given shape (minus batch dimension), retaining original batch size. rrE)shaper8cstdt||_dS)a Given a shape list/tuple `shape` of integers (s0, s1, ... , sn), this layer will reshape input tensors of shape (batch, s0 * s1 * ... * sn) to shape (batch, s0, s1, ... , sn). Args: shape: list/tuple of integer shape dimensions )r$N)r'r(r.rS)r/rSr1r3r4r(s zReshape.__init__r5r6cCs"t|j}|jd|d<||S)Nr)listrSreshape)r/r7rSr3r3r4r>s zReshape.forwardrOr3r3r1r4rs r5zlist[torch.Tensor]strrz list[int])input_kernelspad_modedr paddings num_channelsr8c Cs|dkr |Sdgt|j}d||d<|||}|dkrf|ddkrft||||d|||S||dgdg|}dg|} ||| |<tjtjtj g|d} ddt | D} t | g} tj || |d} | t| |||d|||||dS) Nrr$rPr&cSsg|] }||gqSr3r3).0pr3r3r4 sz-_separable_filtering_conv..r#)inputweightgroups) lenrSrUnumel_separable_filtering_convrepeatr<conv1dconv2dconv3dreversedsumr*)rWrXrYrZr r[r\s_kernel_paddingr0 _reversed_padding_repeated_twiceZ$_sum_reversed_padding_repeated_twice padded_inputr3r3r4rfs&     rfzeros)r7rXr#r8csttjs"tdtjdtjd}t|tjrF|g|}fdd|D}dd|D}jd}|dkr|d n|}t|||d|||S) a1 Apply 1-D convolutions along each spatial dimension of `x`. Args: x: the input image. must have shape (batch, channels, H[, W, ...]). kernels: kernel along each spatial dimension. could be a single kernel (duplicated for all spatial dimensions), or a list of `spatial_dims` number of kernels. mode (string, optional): padding mode passed to convolution class. ``'zeros'``, ``'reflect'``, ``'replicate'`` or ``'circular'``. Default: ``'zeros'``. See ``torch.nn.Conv1d()`` for more information. Raises: TypeError: When ``x`` is not a ``torch.Tensor``. Examples: .. code-block:: python >>> import torch >>> from monai.networks.layers import separable_filtering >>> img = torch.randn(2, 4, 32, 32) # batch_size 2, channels 4, 32x32 2D images # applying a [-1, 0, 1] filter along each of the spatial dimensions. # the output shape is the same as the input shape. >>> out = separable_filtering(img, torch.tensor((-1., 0., 1.))) # applying `[-1, 0, 1]`, `[1, 0, -1]` filters along two spatial dimensions respectively. # the output shape is the same as the input shape. >>> out = separable_filtering(img, [torch.tensor((-1., 0., 1.)), torch.tensor((1., 0., -1.))]) x must be a torch.Tensor but is rLr&csg|]}|qSr3)tor]rmr7r3r4r_sz'separable_filtering..cSsg|]}|jdddqS)rr$r&)rSr]kr3r3r4r_sr$rrconstant) isinstancer:Tensor TypeErrortyper?rdrSrf)r7rXr#r _kernelsZ _paddingsZn_chsrYr3rvr4rs    )r7kernelr8c Kst|tjs"tdt|jd|j^}}}t|}|dkrNtd|dt|j}||ksl||dkrt d|d|dd|jd| |}|j ||f|j||d }|j d|jdd }|j d |jd f|}tjtjtjg|d }d |kr>td dr d|d <ndd|jdd D|d <n6|d dkrttd dstdd|jdd D|d <d|krd |d<|||f|jd d d|} | j ||f| jdd S)a Filtering `x` with `kernel` independently for each batch and channel respectively. Args: x: the input image, must have shape (batch, channels, H[, W, D]). kernel: `kernel` must at least have the spatial shape (H_k[, W_k, D_k]). `kernel` shape must be broadcastable to the `batch` and `channels` dimensions of `x`. kwargs: keyword arguments passed to `conv*d()` functions. Returns: The filtered `x`. Examples: .. code-block:: python >>> import torch >>> from monai.networks.layers import apply_filter >>> img = torch.rand(2, 5, 10, 10) # batch_size 2, channels 5, 10x10 2D images >>> out = apply_filter(img, torch.rand(3, 3)) # spatial kernel >>> out = apply_filter(img, torch.rand(5, 3, 3)) # channel-wise kernels >>> out = apply_filter(img, torch.rand(2, 5, 3, 3)) # batch-, channel-wise kernels rsrLz6Only spatial dimensions up to 3 are supported but got r&zkernel must have z ~ z% dimensions to match the input shape NrPr$rpadding samecSsg|]}|ddqSr$r&r3rwr3r3r4r_,sz apply_filter..cSsg|]}|ddqSrr3rwr3r3r4r_/sstride)rcbias)rPr$)rzr:r{r|r}r?rSrdrMr-rtexpandrUrQr<rhrirjr) r7rkwargsbatchZchnsZspatialsZ n_spatialZk_sizeconvoutputr3r3r4rs4         csJeZdZdZddddddfdd Zd d d d d Zed dZZS)raR Convolve a Tensor along a particular axis with a Savitzky-Golay kernel. Args: window_length: Length of the filter window, must be a positive odd integer. order: Order of the polynomial to fit to each window, must be less than ``window_length``. axis (optional): Axis along which to apply the filter kernel. Default 2 (first spatial dimension). mode (string, optional): padding mode passed to convolution class. ``'zeros'``, ``'reflect'``, ``'replicate'`` or ``'circular'``. Default: ``'zeros'``. See torch.nn.Conv1d() for more information. r&rrrrV) window_lengthorderaxisr#cs8t||krtd||_||_||||_dS)Nz&order must be less than window_length.)r'r(r-rr# _make_coeffscoeffs)r/rrrr#r1r3r4r(Cs  zSavitzkyGolayFilter.__init__r5r6c Cstj|t|tjr|jndd}t|r2td|jtjd}|j dks^|j t |j dkrxtd|j d|j d t |j d }|j d }|}||d}|j j|j|j d g}t|D] }|dtjd|j|j d qt|D]}|tjd|j|j d qt|||jd S) a Args: x: Tensor or array-like to filter. Must be real, in shape ``[Batch, chns, spatial1, spatial2, ...]`` and have a device type of ``'cpu'``. Returns: torch.Tensor: ``x`` filtered by Savitzky-Golay kernel with window length ``self.window_length`` using polynomials of order ``self.order``, along axis specified in ``self.axis``. Ndevicex must be real.dtyperr$&Invalid axis for shape of x, got axis and shape rLr&rrr`)r:r;rzr{r is_complexr-rtfloatrrdrSrrrangeinsertonesappendrr#)r/r7Zn_spatial_dimsZspatial_processing_axisnew_dims_beforenew_dims_after kernel_list_r3r3r4r>Ls      zSavitzkyGolayFilter.forwardcCst|d\}}|dkrtdtj||d| ddtjdd}|tj|dtjdddd}tj|dtjdd}d|d<tdd st||j Stj ||j S) Nr&rzwindow_length must be odd.r$rPcpurr? ) divmodr-r:arangerrUrrrlstsqsolutionsqueezelinalg)rrZ half_lengthremidxarNr3r3r4rms$"z SavitzkyGolayFilter._make_coeffs)r&rr) r?r@rArBr(r> staticmethodrrCr3r3r1r4r7s   !cs<eZdZdZdddddfdd Zd d d d d ZZS)ra Determine the analytical signal of a Tensor along a particular axis. Args: axis: Axis along which to apply Hilbert transform. Default 2 (first spatial dimension). n: Number of Fourier components (i.e. FFT size). Default: ``x.shape[axis]``. r&Nrz int | NonerE)rnr8cst||_||_dSr9)r'r(rr)r/rrr1r3r4r(s zHilbertTransform.__init__r5r6c Cstj|t|tjr|jndd}t|r2td|jtjd}|j dks^|j t |j dkrxtd|j d|j d |j dkr|j |j n|j }|dkrtd tj|tj d}tttjd|dd d|jdt|ttj|d  d|jdt|g}tj|||j d }t|tjd g|jd}tj||j|jd}|j }t |j |j d}t|D]}|dqjt|D]}|dqtj|d ||j d} tj| | j| jdS)a Args: x: Tensor or array-like to transform. Must be real and in shape ``[Batch, chns, spatial1, spatial2, ...]``. Returns: torch.Tensor: Analytical signal of ``x``, transformed along axis specified in ``self.axis`` using FFT of size ``self.N``. The absolute value of ``x_ht`` relates to the envelope of ``x`` along axis ``self.axis``. Nrrrrr$rrrLzN must be positive.r&)rrFg?rrPrIr)r:r;rzr{rrr-rtrrrdrSr complex64rD true_dividerfft heavisidetensorrr unsqueeze_ifft) r/r7rfxfurrrhtr3r3r4r>s4  ("  zHilbertTransform.forward)r&NrOr3r3r1r4r~sz Sequence[int]) window_sizer8cCs@t|tdd}t|}|df|}ttj|||d|S)zv Create a binary kernel to extract the patches. The window size HxWxD will create a (H*W*D)xHxWxD kernel. T wrap_sequencer$r)r rr:proddiagrrQ)rrrwin_sizerrmr3r3r4get_binary_kernels  rrrrrztorch.Tensor | None) in_tensorr%r rr8cKs*t|tjstdt||j}|dt|||| d}}tt|t dd}|dkrt ||}t ||j |j }n ||}tjtjtjg|d} |j|df|} ddt|jddD} tj| | d d } | | |fd dd |} | j|d f|} tj| ddd }||}|S)a Apply median filter to an image. Args: in_tensor: input tensor; median filtering will be applied to the last `spatial_dims` dimensions. kernel_size: the convolution kernel size. spatial_dims: number of spatial dimensions to apply median filtering. kernel: an optional customized kernel. kwargs: additional parameters to the `conv`. Returns: the filtered input tensor, shape remains the same as ``in_tensor`` Example:: >>> from monai.networks.layers import median_filter >>> import torch >>> x = torch.rand(4, 5, 7, 6) >>> output = median_filter(x, (3, 3, 3)) >>> output.shape torch.Size([4, 5, 7, 6]) z&Input type is not a torch.Tensor. Got NTrr$cSs&g|]}tdD]}|ddqqS)r&r$)r)r]rxrr3r3r4r_s z!median_filter..r& replicate)r*r#r)rrrPrI)rzr:r{r|r}rSrdrr rrrrrrtr<rhrirjrUrkr*rQmedian)rr%r rroriginal_shapeZoshapeZsshapeZoprodrZreshaped_inputrrqfeaturesrr3r3r4rs$ $   cs>eZdZdZdddddfdd Zdd d d d dZZS)ra Apply median filter to an image. Args: radius: the blurring kernel radius (radius of 1 corresponds to 3x3x3 kernel when spatial_dims=3). Returns: filtered input tensor. Example:: >>> from monai.networks.layers import MedianFilter >>> import torch >>> in_tensor = torch.rand(4, 5, 7, 6) >>> blur = MedianFilter([1, 1, 1]) # 3x3x3 kernel >>> output = blur(in_tensor) >>> output.shape torch.Size([4, 5, 7, 6]) rrzSequence[int] | intrrE)radiusr r8csBt||_t|||_dd|jD|_t|j|d|_dS)NcSsg|]}ddt|qSrr)r]rr3r3r4r_sz)MedianFilter.__init__..r)r'r(r rrwindowrr)r/rr rr1r3r4r(s   zMedianFilter.__init__r$r5)rr8cCs(|}t|D]}t||j|jd}q |S)z Args: in_tensor: input tensor, median filtering will be applied to the last `spatial_dims` dimensions. number_of_passes: median filtering will be repeated this many times )rr )rrrr )r/rZnumber_of_passesr7rr3r3r4r>s zMedianFilter.forward)rr)r$rOr3r3r1r4rscs>eZdZddddddd d fd d Zd d dddZZS)r@erfFrz?Sequence[float] | float | Sequence[torch.Tensor] | torch.TensorrrVboolrE)r sigma truncatedapprox requires_gradr8cstrt|kr0tnfddt|DtfddD|_||_||_t |jD]\}}| d||qddS)a> Args: spatial_dims: number of spatial dimensions of the input image. must have shape (Batch, channels, H[, W, ...]). sigma: std. could be a single value, or `spatial_dims` number of values. truncated: spreads how many stds. approx: discrete Gaussian kernel type, available options are "erf", "sampled", and "scalespace". - ``erf`` approximation interpolates the error function; - ``sampled`` uses a sampled Gaussian kernel; - ``scalespace`` corresponds to https://en.wikipedia.org/wiki/Scale_space_implementation#The_discrete_Gaussian_kernel based on the modified Bessel functions. requires_grad: whether to store the gradients for sigma. if True, `sigma` will be the initial value of the parameters of this module (for example `parameters()` iterator could be used to get the parameters); otherwise this module will fix the kernels using `sigma` as the std. csg|] }tqSr3rr]r)rr3r4r_Ksz+GaussianFilter.__init__..c s<g|]4}tjjtj|tjt|tjr*|jndddqS)Nrr)r:r Parameterr;rrzr{rrurr3r4r_Ms "Z kernel_sigma_N) rrdr-rr'r(rrr enumerateregister_parameter)r/r rrrrrparamr1)rrr4r(,s   zGaussianFilter.__init__r5r6cs fddjD}t||dS)zG Args: x: in shape [Batch, chns, H, W, D]. csg|]}t|jjdqS))rr)r rrrur/r3r4r_^sz*GaussianFilter.forward..)r7rX)rr)r/r7rnr3rr4r>YszGaussianFilter.forward)rrF)r?r@rAr(r>rCr3r3r1r4r*s -c@s$eZdZeddZeddZdS) LLTMFunctionc CsFt|||||}|dd\}}|dd|g} |j| ||fS)Nr&r$)_CZ lltm_forwardsave_for_backward) ctxraweightsrZold_hZold_celloutputsZnew_hZnew_cell variablesr3r3r4r>ds  zLLTMFunction.forwardc Cs@tj||f|j}|dd\}}}}}|||||fS)N)rZ lltm_backward contiguous saved_tensors) rZgrad_hZ grad_cellrZd_old_hd_inputZ d_weightsd_biasZ d_old_cellr3r3r4backwardmszLLTMFunction.backwardN)r?r@rArr>rr3r3r3r4rbs rcs8eZdZdZdddfdd ZddZdd ZZS) raF This recurrent unit is similar to an LSTM, but differs in that it lacks a forget gate and uses an Exponential Linear Unit (ELU) as its internal activation function. Because this unit never forgets, call it LLTM, or Long-Long-Term-Memory unit. It has both C++ and CUDA implementation, automatically switch according to the target device where put this module to. Args: input_features: size of input feature data state_size: size of the state of recurrent unit Referring to: https://pytorch.org/tutorials/advanced/cpp_extension.html r)input_features state_sizecsVt||_||_ttd||||_ttdd||_ | dS)Nrr$) r'r(rrrrr:emptyrrreset_parameters)r/rrr1r3r4r(s  z LLTM.__init__cCs4dt|j}|D]}|j| | qdS)Nr)mathsqrtr parametersdatauniform_)r/stdvrbr3r3r4rs zLLTM.reset_parameterscCstj||j|jf|Sr9)rapplyrr)r/rastater3r3r4r>sz LLTM.forward)r?r@rArBr(rr>rCr3r3r1r4ruscs8eZdZdZdddfdd Zdddd d ZZS) ApplyFilterz,Wrapper class to apply a filter to an image.rrE)filterr8cstt|tjd|_dS)Nr)r'r(r r:float32r)r/rr1r3r4r(s zApplyFilter.__init__r5r6cCs t||jSr9)rrr=r3r3r4r>szApplyFilter.forwardrOr3r3r1r4rsrcs*eZdZdZddddfdd ZZS) MeanFilterz Mean filtering can smooth edges and remove aliasing artifacts in an segmentation image. The mean filter used, is a `torch.Tensor` of all ones. rrEr rRr8cs&t|g|}|}tj|ddS) Args: spatial_dims: `int` of either 2 for 2D images and 3 for 3D images size: edge length of the filter rN)r:rr'r()r/r rRrr1r3r4r(szMeanFilter.__init__r?r@rArBr(rCr3r3r1r4rsrcs*eZdZdZddddfdd ZZS) LaplaceFilterz Laplacian filtering for outline detection in images. Can be used to transform labels to contours. The laplace filter used, is a `torch.Tensor` where all values are -1, except the center value which is `size` ** `spatial_dims` rrErcsLt|g|d}t|dg|}||d||<tj|ddS)rr$r&rN)r:rrrr.r'r()r/r rRr center_pointr1r3r4r(szLaplaceFilter.__init__rr3r3r1r4rsrcs*eZdZdZddddfdd ZZS)EllipticalFilterz Elliptical filter, can be used to dilate labels or label-contours. The elliptical filter used here, is a `torch.Tensor` with shape (size, ) * ndim containing a circle/sphere of `1` rrErcsbdtjfddt|D}tfdd|Ddd}|dk}tj|ddS)rr&csg|]}tdqS)r)r:rr)rRr3r4r_sz-EllipticalFilter.__init__..csg|]}|dqS)r&r3)r]r)rr3r4r_srrN)r:meshgridrstackrlr'r()r/r rRgridZsquared_distancesrr1)rrRr4r(s   zEllipticalFilter.__init__rr3r3r1r4rsrcs*eZdZdZddddfdd ZZS) SharpenFilterz Convolutional filter to sharpen a 2D or 3D image. The filter used contains a circle/sphere of `-1`, with the center value being the absolute sum of all non-zero elements in the kernel rrErcsHtj||dt|dg|}|j}|jd9_||j|<dS)r)r rRr&rPN)r'r(r.rrl)r/r rRrZ center_valuer1r3r4r(s  zSharpenFilter.__init__rr3r3r1r4rsr)rr)rrN)7 __future__rrcopyrtypingrr:torch.nn.functionalr functionalr<Ztorch.autogradrmonai.config.type_definitionsrZmonai.networks.layers.convutilsr Zmonai.networks.layers.factoriesr monai.utilsr r r rrrrrrrr__all__Modulerrrrrfrrrrrrrrrrrrrrrrr3r3r3r4 sb        (  0$ %-:G< <)8