o
    iHe                     @  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!g dZ"G dd deZ#G dd deZ$G dd deZ%G dd deZ&G dd deZ'G dd deZ(G dd deZ)G dd deZ*G dd deZ+G dd  d eZ,G d!d" 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 )#    )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                      s@   e Zd ZdZejZdddejdfd fddZ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   Fkeysr   mask_key
str | Nonemarkers_keyconnectivity
int | Nonedtyper   allow_missing_keysboolreturnNonec                   s,   t  || || _|| _t||d| _d S )N)rA   rC   )super__init__r>   r@   r   	transform)selfr=   r>   r@   rA   rC   rD   	__class__ q/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/apps/pathology/transforms/post/dictionary.pyrI   f   s   	zWatershedd.__init__data"Mapping[Hashable, NdarrayOrTensor]dict[Hashable, NdarrayOrTensor]c                 C  sZ   t |}| jr|| j nd }| jr|| j nd }| |D ]}| || ||||< q|S N)dictr@   r>   key_iteratorrJ   )rK   rP   dmarkersr;   keyrN   rN   rO   __call__t   s   zWatershedd.__call__)r=   r   r>   r?   r@   r?   rA   rB   rC   r   rD   rE   rF   rG   rP   rQ   rF   rR   )__name__
__module____qualname____doc__r   backendnpuint8rI   rY   __classcell__rN   rN   rL   rO   r   L   s    r   c                      sB   e Zd ZdZejZddddejdfd fddZ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=   r   r>   str
activationstr | Callable	thresholdfloat | Nonemin_object_sizeintrC   r   rD   rE   rF   rG   c                   s*   t  || || _t||||d| _d S )N)rf   rh   rj   rC   )rH   rI   r>   r   rJ   )rK   r=   r>   rf   rh   rj   rC   rD   rL   rN   rO   rI      s
   
zGenerateWatershedMaskd.__init__rP   rQ   rR   c                 C  sP   t |}| |D ]}| || }| j|v r td| j d||| j< q	|S )NzMask with key  already exists.)rT   rU   rJ   r>   KeyError)rK   rP   rV   rX   r;   rN   rN   rO   rY      s   
zGenerateWatershedMaskd.__call__)r=   r   r>   re   rf   rg   rh   ri   rj   rk   rC   r   rD   rE   rF   rG   rZ   )r[   r\   r]   r^   r   r_   r`   ra   rI   rY   rb   rN   rN   rL   rO   r      s    r   c                   @  s8   e Zd ZdZejZddddejfdddZ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   r>   re   hover_map_key
border_keykernel_sizerk   rC   r   rF   rG   c                 C  $   || _ || _|| _t||d| _d S )N)rs   rC   )r>   rq   rr   r   rJ   )rK   r>   rq   rr   rs   rC   rN   rN   rO   rI         z GenerateInstanceBorderd.__init__rP   rQ   rR   c                 C  F   t |}| j|v rtd| j d| || j || j || j< |S )N	The key 'z)' for instance border map already exists.)rT   rr   rm   rJ   r>   rq   rK   rP   rV   rN   rN   rO   rY      
   
z GenerateInstanceBorderd.__call__N)r>   re   rq   re   rr   re   rs   rk   rC   r   rF   rG   rZ   )
r[   r\   r]   r^   r   r_   r`   float32rI   rY   rN   rN   rN   rO   r"      s    r"   c                   @  s8   e Zd ZdZejZddddejfdddZ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_mapNr>   re   rr   dist_map_key	smooth_fnCallable | NonerC   r   rF   rG   c                 C  rt   )N)r|   rC   )r>   rr   r{   r   rJ   )rK   r>   rr   r{   r|   rC   rN   rN   rO   rI      ru   zGenerateDistanceMapd.__init__rP   rQ   rR   c                 C  rv   )Nrw   z"' for distance map already exists.)rT   r{   rm   rJ   r>   rr   rx   rN   rN   rO   rY      ry   zGenerateDistanceMapd.__call__)r>   re   rr   re   r{   re   r|   r}   rC   r   rF   rG   rZ   )
r[   r\   r]   r^   r   r_   r`   rz   rI   rY   rN   rN   rN   rO   r%      s    r%   c                   @  s>   e Zd ZdZejZdddddddejfdddZ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   rW   皙?   rd   Nr>   re   rr   r@   rh   floatradiusrk   rj   postprocess_fnr}   rC   r   rF   rG   c	           	      C  s*   || _ || _|| _t|||||d| _d S )N)rh   r   rj   r   rC   )r>   rr   r@   r   rJ   )	rK   r>   rr   r@   rh   r   rj   r   rC   rN   rN   rO   rI     s   z"GenerateWatershedMarkersd.__init__rP   rQ   rR   c                 C  rv   )Nrw   z' for markers already exists.)rT   r@   rm   rJ   r>   rr   rx   rN   rN   rO   rY   !  ry   z"GenerateWatershedMarkersd.__call__)r>   re   rr   re   r@   re   rh   r   r   rk   rj   rk   r   r}   rC   r   rF   rG   rZ   )
r[   r\   r]   r^   r   r_   r`   ra   rI   rY   rN   rN   rN   rO   r(      s    r(   c                      s2   e Zd ZdZejZ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=   r   heightrk   widthrD   rE   rF   rG   c                   s    t  || t||d| _d S )N)r   r   )rH   rI   r   	converter)rK   r=   r   r   rD   rL   rN   rO   rI   9  s   z!GenerateSuccinctContourd.__init__c                 C  s.   t |}| |D ]}| || ||< q	|S rS   )rT   rU   r   )rK   rP   rV   rX   rN   rN   rO   rY   =  s   z!GenerateSuccinctContourd.__call__)F)
r=   r   r   rk   r   rk   rD   rE   rF   rG   )	r[   r\   r]   r^   r   r_   rI   rY   rb   rN   rN   rL   rO   r+   )  s
    r+   c                      s<   e Zd ZdZejZ					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=   r   contour_key_postfixre   
offset_keyr?   min_num_pointsrk   levelri   rD   rE   rF   rG   c                   s,   t  || t||d| _|| _|| _d S )N)r   contour_level)rH   rI   r	   r   r   r   )rK   r=   r   r   r   r   rD   rL   rN   rO   rI   Z  s   	
z!GenerateInstanceContourd.__init__c                 C  p   t |}| |D ],}| jr|| j nd }| || |}| d| j }||v r1td| d|||< q	|S )N_zContour with key rl   )rT   rU   r   r   r   rm   )rK   rP   rV   rX   offsetr   
key_to_addrN   rN   rO   rY   h     
z!GenerateInstanceContourd.__call__)r   Nr   NF)r=   r   r   re   r   r?   r   rk   r   ri   rD   rE   rF   rG   )	r[   r\   r]   r^   r	   r_   rI   rY   rb   rN   rN   rL   rO   r.   E  s    r.   c                      s:   e Zd ZdZejZddedf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=   r   centroid_key_postfixre   r   r?   rC   DtypeLike | NonerD   rE   rF   rG   c                   s*   t  || t|d| _|| _|| _d S )N)rC   )rH   rI   r   r   r   r   )rK   r=   r   r   rC   rD   rL   rN   rO   rI     s   
z"GenerateInstanceCentroidd.__init__c                 C  r   )Nr   zCentroid with key rl   )rT   rU   r   r   r   rm   )rK   rP   rV   rX   r   r   r   rN   rN   rO   rY     r   z"GenerateInstanceCentroidd.__call__)r=   r   r   re   r   r?   rC   r   rD   rE   rF   rG   )
r[   r\   r]   r^   r   r_   rk   rI   rY   rb   rN   rN   rL   rO   r1   t  s    r1   c                      s<   e Zd ZdZejZ					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=   r   type_info_keyre   bbox_keyseg_pred_keyinstance_id_keyrD   rE   rF   rG   c                   s2   t  || t | _|| _|| _|| _|| _d S rS   )rH   rI   r
   r   r   r   r   r   )rK   r=   r   r   r   r   rD   rL   rN   rO   rI     s   	
zGenerateInstanceTyped.__init__c           
      C  s   t |}| |D ]4}|| j }|| j }|| j }| || |||\}}| j }	|	|v r6td|	 d||d||	< q	|S )NzType information with key rl   )	inst_type	type_prob)rT   rU   r   r   r   r   r   rm   )
rK   rP   rV   rX   r   r   r   instance_typer   r   rN   rN   rO   rY     s   


zGenerateInstanceTyped.__call__)r   r   r   r   F)r=   r   r   re   r   re   r   re   r   re   rD   rE   rF   rG   )	r[   r\   r]   r^   r
   r_   rI   rY   rb   rN   rN   rL   rO   r4     s    r4   c                      sT   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* 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      r~   r   r<   r   nuclear_prediction_keyre   rq   instance_info_keyinstance_map_keyrf   rg   mask_thresholdri   rj   rk   sobel_kernel_sizedistance_smooth_fnr}   marker_thresholdr   marker_radiusmarker_postprocess_fnwatershed_connectivityrB   r   r   devicestr | torch.device | NonerF   rG   c                   sH   t    t|||||	|
||||||d| _|| _|| _|| _|| _d S )N)rf   r   rj   r   r   r   r   r   r   r   r   r   )rH   rI   r   instance_map_post_processr   rq   r   r   )rK   r   rq   r   r   rf   r   rj   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 ]
}||v rtdq
| || j || j \|| j< || j< |S )Nz>The output key ['{k}'] already exists in the input dictionary!)rT   r   r   
ValueErrorr   r   rq   )rK   rP   rV   krN   rN   rO   rY     s   z+HoVerNetInstanceMapPostProcessingd.__call__)"r   re   rq   re   r   re   r   re   rf   rg   r   ri   rj   rk   r   rk   r   r}   r   r   r   rk   r   r}   r   rB   r   rk   r   ri   r   r   rF   rG   )r[   r\   r]   r^   r   NPvalueHVrI   rY   rb   rN   rN   rL   rO   r7     s(    !'r7   c                      s@   e Zd ZdZejjdddddddf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   NTtype_prediction_keyre   r   r   type_map_keyrf   rg   rh   ri   return_type_maprE   r   r   rF   rG   c	           	        s>   t    t||||d| _|| _|| _|| _|| _|| _d S )N)rf   rh   r   r   )	rH   rI   r   type_post_processr   r   r   r   r   )	rK   r   r   r   r   rf   rh   r   r   rL   rN   rO   rI   3  s   

z+HoVerNetNuclearTypePostProcessingd.__init__c                 C  sX   t |}| || j || j || j \|| j< }| jr*| j|v r%td||| j< |S )NzNThe output key ['{self.type_map_key}'] already exists in the input dictionary!)rT   r   r   r   r   r   r   r   )rK   rP   rV   r   rN   rN   rO   rY   H  s   

z+HoVerNetNuclearTypePostProcessingd.__call__)r   re   r   re   r   re   r   re   rf   rg   rh   ri   r   rE   r   r   rF   rG   )
r[   r\   r]   r^   r   NCr   rI   rY   rb   rN   rN   rL   rO   r:   #  s    r:   )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>   sB   4%3,)$1/*0U3