U
    PhHe                  !   @  s  d dl mZ d dlmZmZmZ d dlZd dlZd dl	m
Z
mZmZmZmZmZmZmZmZmZmZ d dlmZmZmZ d dlmZmZ d dlmZ d dlmZ ed	d
d\Z Z!ddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,g!Z"G d-d deZ#G d.d deZ$G d/d deZ%G d0d deZ&G d1d deZ'G d2d deZ(G d3d  d eZ)G d4d# d#eZ*G d5d& d&eZ+G d6d) d)eZ,G d7d, d,eZ-e# Z.Z/e$ Z0Z1e% Z2Z3e& Z4Z5e' Z6Z7e( Z8Z9e) Z:Z;e* Z<Z=e+ Z>Z?e, Z@ZAe- ZBZCdS )8    )annotations)CallableHashableMappingN)GenerateDistanceMapGenerateInstanceBorderGenerateInstanceCentroidGenerateInstanceContourGenerateInstanceTypeGenerateSuccinctContourGenerateWatershedMarkersGenerateWatershedMask!HoVerNetInstanceMapPostProcessing!HoVerNetNuclearTypePostProcessing	Watershed)	DtypeLikeKeysCollectionNdarrayOrTensor)MapTransform	Transform)optional_import)HoVerNetBranchzskimage.measurefind_contours)name
WatershedDWatershedDict
WatersheddGenerateWatershedMaskDGenerateWatershedMaskDictGenerateWatershedMaskdGenerateInstanceBorderDGenerateInstanceBorderDictGenerateInstanceBorderdGenerateDistanceMapDGenerateDistanceMapDictGenerateDistanceMapdGenerateWatershedMarkersDGenerateWatershedMarkersDictGenerateWatershedMarkersdGenerateSuccinctContourDictGenerateSuccinctContourDGenerateSuccinctContourdGenerateInstanceContourDictGenerateInstanceContourDGenerateInstanceContourdGenerateInstanceCentroidDictGenerateInstanceCentroidDGenerateInstanceCentroiddGenerateInstanceTypeDictGenerateInstanceTypeDGenerateInstanceTyped%HoVerNetInstanceMapPostProcessingDict"HoVerNetInstanceMapPostProcessingD"HoVerNetInstanceMapPostProcessingd%HoVerNetNuclearTypePostProcessingDict"HoVerNetNuclearTypePostProcessingD"HoVerNetNuclearTypePostProcessingdc                	      sV   e Zd ZdZejZdddejdfddddd	d
dd fddZdddddZ	  Z
S )r   a  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.array.Watershed`.
    Use `skimage.segmentation.watershed` to get instance segmentation results from images.
    See: https://scikit-image.org/docs/stable/api/skimage.segmentation.html#skimage.segmentation.watershed.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: monai.transforms.MapTransform
        mask_key: keys of mask used in watershed. Only points at which mask == True will be labeled.
        markers_key: keys of markers used in watershed. If None (no markers given), the local minima of the image are
            used as markers.
        connectivity: An array with the same number of dimensions as image whose non-zero elements indicate neighbors
            for connection. Following the scipy convention, default is a one-connected array of the dimension of the
            image.
        dtype: target data content type to convert. Defaults to np.uint8.
        allow_missing_keys: don't raise exception if key is missing.

    Raises:
        ValueError: when the `image` shape is not [1, H, W].
        ValueError: when the `mask` shape is not [1, H, W].

    maskN   Fr   
str | None
int | Noner   boolNone)keysmask_keymarkers_keyconnectivitydtypeallow_missing_keysreturnc                   s,   t  || || _|| _t||d| _d S )N)rD   rE   )super__init__rB   rC   r   	transform)selfrA   rB   rC   rD   rE   rF   	__class__ d/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/apps/pathology/transforms/post/dictionary.pyrI   f   s    	zWatershedd.__init__"Mapping[Hashable, NdarrayOrTensor]dict[Hashable, NdarrayOrTensor]datarG   c                 C  sZ   t |}| jr|| j nd }| jr,|| j nd }| |D ]}| || ||||< q:|S N)dictrC   rB   key_iteratorrJ   )rK   rS   dmarkersr;   keyrN   rN   rO   __call__t   s    zWatershedd.__call__)__name__
__module____qualname____doc__r   backendnpuint8rI   rZ   __classcell__rN   rN   rL   rO   r   L   s    c                
      sZ   e Zd ZdZejZddddejdfddd	d
ddddd fddZdddddZ	  Z
S )r   a  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.array.GenerateWatershedMask`.

    Args:
        keys: keys of the corresponding items to be transformed.
        mask_key: the mask will be written to the value of `{mask_key}`.
        activation: the activation layer to be applied on nuclear type branch. It can be "softmax" or "sigmoid" string,
            or any callable. Defaults to "softmax".
        threshold: if not None, threshold the float values to int number 0 or 1 with specified threshold.
        min_object_size: objects smaller than this size are removed. Defaults to 10.
        dtype: target data content type to convert, default is np.uint8.
        allow_missing_keys: don't raise exception if key is missing.

    r;   softmaxN
   Fr   strstr | Callablefloat | Noneintr   r?   r@   )rA   rB   
activation	thresholdmin_object_sizerE   rF   rG   c                   s*   t  || || _t||||d| _d S )N)ri   rj   rk   rE   )rH   rI   rB   r   rJ   )rK   rA   rB   ri   rj   rk   rE   rF   rL   rN   rO   rI      s    
   zGenerateWatershedMaskd.__init__rP   rQ   rR   c                 C  sP   t |}| |D ]8}| || }| j|kr@td| j d||| j< q|S )NzMask with key  already exists.)rU   rV   rJ   rB   KeyError)rK   rS   rW   rY   r;   rN   rN   rO   rZ      s    
zGenerateWatershedMaskd.__call__)r[   r\   r]   r^   r   r_   r`   ra   rI   rZ   rb   rN   rN   rL   rO   r      s   "c                   @  sL   e Zd ZdZejZddddejfdddddd	d
ddZdddddZ	dS )r"   a  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.array.GenerateInstanceBorder`.

    Args:
        mask_key: the input key where the watershed mask is stored. Defaults to `"mask"`.
        hover_map_key: the input key where hover map is stored. Defaults to `"hover_map"`.
        border_key: the output key where instance border map is written. Defaults to `"border"`.
        kernel_size: the size of the Sobel kernel. Defaults to 21.
        dtype: target data content type to convert, default is np.float32.
        allow_missing_keys: don't raise exception if key is missing.

    Raises:
        ValueError: when the `hover_map` has only one value.
        ValueError: when the `sobel gradient map` has only one value.

    r;   	hover_mapborder   re   rh   r   r@   )rB   hover_map_key
border_keykernel_sizerE   rG   c                 C  s$   || _ || _|| _t||d| _d S )N)rs   rE   )rB   rq   rr   r   rJ   )rK   rB   rq   rr   rs   rE   rN   rN   rO   rI      s    z GenerateInstanceBorderd.__init__rP   rQ   rR   c                 C  sF   t |}| j|kr$td| j d| || j || j || j< |S )N	The key 'z)' for instance border map already exists.)rU   rr   rm   rJ   rB   rq   rK   rS   rW   rN   rN   rO   rZ      s
    
z GenerateInstanceBorderd.__call__N)
r[   r\   r]   r^   r   r_   r`   float32rI   rZ   rN   rN   rN   rO   r"      s   c                   @  sL   e Zd ZdZejZddddejfdddddd	d
ddZdddddZ	dS )r%   a  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.array.GenerateDistanceMap`.

    Args:
        mask_key: the input key where the watershed mask is stored. Defaults to `"mask"`.
        border_key: the input key where instance border map is stored. Defaults to `"border"`.
        dist_map_key: the output key where distance map is written. Defaults to `"dist_map"`.
        smooth_fn: smoothing function for distance map, which can be any callable object.
            If not provided :py:class:`monai.transforms.GaussianSmooth()` is used.
        dtype: target data content type to convert, default is np.float32.
    r;   ro   Zdist_mapNre   Callable | Noner   r@   )rB   rr   dist_map_key	smooth_fnrE   rG   c                 C  s$   || _ || _|| _t||d| _d S )N)ry   rE   )rB   rr   rx   r   rJ   )rK   rB   rr   rx   ry   rE   rN   rN   rO   rI      s    zGenerateDistanceMapd.__init__rP   rQ   rR   c                 C  sF   t |}| j|kr$td| j d| || j || j || j< |S )Nrt   z"' for distance map already exists.)rU   rx   rm   rJ   rB   rr   ru   rN   rN   rO   rZ      s
    
zGenerateDistanceMapd.__call__)
r[   r\   r]   r^   r   r_   r`   rv   rI   rZ   rN   rN   rN   rO   r%      s   c                   @  sX   e Zd ZdZejZdddddddejfd	d	d	d
dddddd	ddZdddddZ	dS )r(   a  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.array.GenerateWatershedMarkers`.

    Args:
        mask_key: the input key where the watershed mask is stored. Defaults to `"mask"`.
        border_key: the input key where instance border map is stored. Defaults to `"border"`.
        markers_key: the output key where markers is written. Defaults to `"markers"`.
        threshold: threshold the float values of instance border map to int 0 or 1 with specified threshold.
            It turns uncertain area to 1 and other area to 0. Defaults to 0.4.
        radius: the radius of the disk-shaped footprint used in `opening`. Defaults to 2.
        min_object_size: objects smaller than this size are removed. Defaults to 10.
        postprocess_fn: execute additional post transformation on marker. Defaults to None.
        dtype: target data content type to convert, default is np.uint8.
        allow_missing_keys: don't raise exception if key is missing.
    r;   ro   rX   皙?   rd   Nre   floatrh   rw   r   r@   )	rB   rr   rC   rj   radiusrk   postprocess_fnrE   rG   c	           	      C  s*   || _ || _|| _t|||||d| _d S )N)rj   r}   rk   r~   rE   )rB   rr   rC   r   rJ   )	rK   rB   rr   rC   rj   r}   rk   r~   rE   rN   rN   rO   rI     s    z"GenerateWatershedMarkersd.__init__rP   rQ   rR   c                 C  sF   t |}| j|kr$td| j d| || j || j || j< |S )Nrt   z' for markers already exists.)rU   rC   rm   rJ   rB   rr   ru   rN   rN   rO   rZ   !  s
    
z"GenerateWatershedMarkersd.__call__)
r[   r\   r]   r^   r   r_   r`   ra   rI   rZ   rN   rN   rN   rO   r(      s    c                      s>   e Zd ZdZejZddddddd fdd	Zd
d Z  ZS )r+   a  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.post.array.GenerateSuccinctContour`.
    Converts SciPy-style contours (generated by skimage.measure.find_contours) to a more succinct version which
    only includes the pixels to which lines need to be drawn (i.e. not the intervening pixels along each line).

    Args:
        keys: keys of the corresponding items to be transformed.
        height: height of bounding box, used to detect direction of line segment.
        width: width of bounding box, used to detect direction of line segment.
        allow_missing_keys: don't raise exception if key is missing.

    Fr   rh   r?   r@   )rA   heightwidthrF   rG   c                   s    t  || t||d| _d S )N)r   r   )rH   rI   r   	converter)rK   rA   r   r   rF   rL   rN   rO   rI   9  s    z!GenerateSuccinctContourd.__init__c                 C  s.   t |}| |D ]}| || ||< q|S rT   )rU   rV   r   )rK   rS   rW   rY   rN   rN   rO   rZ   =  s    z!GenerateSuccinctContourd.__call__)F)	r[   r\   r]   r^   r   r_   rI   rZ   rb   rN   rN   rL   rO   r+   )  s   c                	      sB   e Zd ZdZejZddddd	d
ddd fddZdd Z  ZS )r.   a  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.post.array.GenerateInstanceContour`.
    Generate contour for each instance in a 2D array. Use `GenerateSuccinctContour` to only include the pixels
    to which lines need to be drawn

    Args:
        keys: keys of the corresponding items to be transformed.
        contour_key_postfix: the output contour coordinates will be written to the value of
            `{key}_{contour_key_postfix}`.
        offset_key: keys of offset used in `GenerateInstanceContour`.
        min_num_points: assumed that the created contour does not form a contour if it does not contain more points
            than the specified value. Defaults to 3.
        level: optional. Value along which to find contours in the array. By default, the level is set
            to (max(image) + min(image)) / 2.
        allow_missing_keys: don't raise exception if key is missing.

    contourN   Fr   re   r=   rh   rg   r?   r@   )rA   contour_key_postfix
offset_keymin_num_pointslevelrF   rG   c                   s,   t  || t||d| _|| _|| _d S )N)r   contour_level)rH   rI   r	   r   r   r   )rK   rA   r   r   r   r   rF   rL   rN   rO   rI   Z  s    	z!GenerateInstanceContourd.__init__c                 C  sp   t |}| |D ]X}| jr&|| j nd }| || |}| d| j }||krbtd| d|||< q|S )N_zContour with key rl   )rU   rV   r   r   r   rm   )rK   rS   rW   rY   offsetr   
key_to_addrN   rN   rO   rZ   h  s    
z!GenerateInstanceContourd.__call__)r   Nr   NF)	r[   r\   r]   r^   r	   r_   rI   rZ   rb   rN   rN   rL   rO   r.   E  s         c                      sH   e Zd ZdZejZddedfddddd	d
d fddZdd Z  Z	S )r1   aK  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.post.array.GenerateInstanceCentroid`.
    Generate instance centroid using `skimage.measure.centroid`.

    Args:
        keys: keys of the corresponding items to be transformed.
        centroid_key_postfix: the output centroid coordinates will be written to the value of
            `{key}_{centroid_key_postfix}`.
        offset_key: keys of offset used in `GenerateInstanceCentroid`.
        dtype: the data type of output centroid.
        allow_missing_keys: don't raise exception if key is missing.

    centroidNFr   re   r=   zDtypeLike | Noner?   r@   )rA   centroid_key_postfixr   rE   rF   rG   c                   s*   t  || t|d| _|| _|| _d S )N)rE   )rH   rI   r   r   r   r   )rK   rA   r   r   rE   rF   rL   rN   rO   rI     s    z"GenerateInstanceCentroidd.__init__c                 C  sp   t |}| |D ]X}| jr&|| j nd }| || |}| d| j }||krbtd| d|||< q|S )Nr   zCentroid with key rl   )rU   rV   r   r   r   rm   )rK   rS   rW   rY   r   r   r   rN   rN   rO   rZ     s    
z"GenerateInstanceCentroidd.__call__)
r[   r\   r]   r^   r   r_   rh   rI   rZ   rb   rN   rN   rL   rO   r1   t  s   c                	      sB   e Zd ZdZejZddddddd	d
d fddZdd Z  ZS )r4   aR  
    Dictionary-based wrapper of :py:class:`monai.apps.pathology.transforms.post.array.GenerateInstanceType`.
    Generate instance type and probability for each instance.

    Args:
        keys: keys of the corresponding items to be transformed.
        type_info_key: the output instance type and probability will be written to the value of
            `{type_info_key}`.
        bbox_key: keys of bounding box.
        seg_pred_key: keys of segmentation prediction map.
        instance_id_key: keys of instance id.
        allow_missing_keys: don't raise exception if key is missing.

    	type_infobboxsegidFr   re   r?   r@   )rA   type_info_keybbox_keyseg_pred_keyinstance_id_keyrF   rG   c                   s2   t  || t | _|| _|| _|| _|| _d S rT   )rH   rI   r
   r   r   r   r   r   )rK   rA   r   r   r   r   rF   rL   rN   rO   rI     s    	zGenerateInstanceTyped.__init__c           
      C  s   t |}| |D ]h}|| j }|| j }|| j }| || |||\}}| j }	|	|krltd|	 d||d||	< q|S )NzType information with key rl   )	inst_type	type_prob)rU   rV   r   r   r   r   r   rm   )
rK   rS   rW   rY   r   r   r   instance_typer   r   rN   rN   rO   rZ     s    


zGenerateInstanceTyped.__call__)r   r   r   r   F)	r[   r\   r]   r^   r
   r_   rI   rZ   rb   rN   rN   rL   rO   r4     s         c                      sx   e Zd ZdZejjejjddddddddd	dd
dddfdddddddddddddddddd fddZdd Z	  Z
S )r7   a]	  
    Dictionary-based wrapper for :py:class:`monai.apps.pathology.transforms.post.array.HoVerNetInstanceMapPostProcessing`.
    The post-processing transform for HoVerNet model to generate instance segmentation map.
    It generates an instance segmentation map as well as a dictionary containing centroids, bounding boxes, and contours
    for each instance.

    Args:
        nuclear_prediction_key: the key for HoVerNet NP (nuclear prediction) branch. Defaults to `HoVerNetBranch.NP`.
        hover_map_key: the key for HoVerNet NC (nuclear prediction) branch. Defaults to `HoVerNetBranch.HV`.
        instance_info_key: the output key where instance information (contour, bounding boxes, and centroids)
            is written. Defaults to `"instance_info"`.
        instance_map_key: the output key where instance map is written. Defaults to `"instance_map"`.
        activation: the activation layer to be applied on the input probability map.
            It can be "softmax" or "sigmoid" string, or any callable. Defaults to "softmax".
        mask_threshold: a float value to threshold to binarize probability map to generate mask.
        min_object_size: objects smaller than this size are removed. Defaults to 10.
        sobel_kernel_size: the size of the Sobel kernel used in :py:class:`GenerateInstanceBorder`. Defaults to 5.
        distance_smooth_fn: smoothing function for distance map.
            If not provided, :py:class:`monai.transforms.intensity.GaussianSmooth()` will be used.
        marker_threshold: a float value to threshold to binarize instance border map for markers.
            It turns uncertain area to 1 and other area to 0. Defaults to 0.4.
        marker_radius: the radius of the disk-shaped footprint used in `opening` of markers. Defaults to 2.
        marker_postprocess_fn: post-process function for watershed markers.
            If not provided, :py:class:`monai.transforms.post.FillHoles()` will be used.
        watershed_connectivity: `connectivity` argument of `skimage.segmentation.watershed`.
        min_num_points: minimum number of points to be considered as a contour. Defaults to 3.
        contour_level: an optional value for `skimage.measure.find_contours` to find contours in the array.
            If not provided, the level is set to `(max(image) + min(image)) / 2`.
        device: target device to put the output Tensor data.
    instance_infoinstance_maprc   Nrd      rz   r{   r<   r   re   rf   rg   rh   rw   r|   r>   str | torch.device | Noner@   )nuclear_prediction_keyrq   instance_info_keyinstance_map_keyri   mask_thresholdrk   sobel_kernel_sizedistance_smooth_fnmarker_thresholdmarker_radiusmarker_postprocess_fnwatershed_connectivityr   r   devicerG   c                   sH   t    t|||||	|
||||||d| _|| _|| _|| _|| _d S )N)ri   r   rk   r   r   r   r   r   r   r   r   r   )rH   rI   r   instance_map_post_processr   rq   r   r   )rK   r   rq   r   r   ri   r   rk   r   r   r   r   r   r   r   r   r   rL   rN   rO   rI     s&    
z+HoVerNetInstanceMapPostProcessingd.__init__c                 C  sV   t |}| j| jfD ]}||krtdq| || j || j \|| j< || j< |S )Nz>The output key ['{k}'] already exists in the input dictionary!)rU   r   r   
ValueErrorr   r   rq   )rK   rS   rW   krN   rN   rO   rZ     s    
 z+HoVerNetInstanceMapPostProcessingd.__call__)r[   r\   r]   r^   r   NPvalueHVrI   rZ   rb   rN   rN   rL   rO   r7     s&   !4'c                      sT   e Zd ZdZejjdddddddfddddd	d
dddd	 fddZdd Z  Z	S )r:   aY  
    Dictionary-based wrapper for :py:class:`monai.apps.pathology.transforms.post.array.HoVerNetNuclearTypePostProcessing`.
    It updates the input instance info dictionary with information about types of the nuclei (value and probability).
    Also if requested (`return_type_map=True`), it generates a pixel-level type map.

    Args:
        type_prediction_key: the key for HoVerNet NC (type prediction) branch. Defaults to `HoVerNetBranch.NC`.
        instance_info_key: the key where instance information (contour, bounding boxes, and centroids) is stored.
            Defaults to `"instance_info"`.
        instance_map_key: the key where instance map is stored. Defaults to `"instance_map"`.
        type_map_key: the output key where type map is written. Defaults to `"type_map"`.
        device: target device to put the output Tensor data.

    r   r   type_maprc   NTre   rf   rg   r?   r   r@   )	type_prediction_keyr   r   type_map_keyri   rj   return_type_mapr   rG   c	           	        s>   t    t||||d| _|| _|| _|| _|| _|| _d S )N)ri   rj   r   r   )	rH   rI   r   type_post_processr   r   r   r   r   )	rK   r   r   r   r   ri   rj   r   r   rL   rN   rO   rI   3  s    
   z+HoVerNetNuclearTypePostProcessingd.__init__c                 C  sX   t |}| || j || j || j \|| j< }| jrT| j|krJtd||| j< |S )NzNThe output key ['{self.type_map_key}'] already exists in the input dictionary!)rU   r   r   r   r   r   r   r   )rK   rS   rW   r   rN   rN   rO   rZ   H  s      

z+HoVerNetNuclearTypePostProcessingd.__call__)
r[   r\   r]   r^   r   NCr   rI   rZ   rb   rN   rN   rL   rO   r:   #  s   $)D
__future__r   collections.abcr   r   r   numpyr`   torchZ*monai.apps.pathology.transforms.post.arrayr   r   r   r	   r
   r   r   r   r   r   r   monai.config.type_definitionsr   r   r   monai.transforms.transformr   r   monai.utilsr   monai.utils.enumsr   r   r   __all__r   r   r"   r%   r(   r+   r.   r1   r4   r7   r:   r   r   r   r   r    r!   r#   r$   r&   r'   r)   r*   r,   r-   r/   r0   r2   r3   r5   r6   r8   r9   rN   rN   rN   rO   <module>   s   4%3,)$1/*0U3