U PhH@sddlmZddlZddlZddlmZmZddlZddl Z ddl m Z ddl m Z ddlmZddlmZmZddlmZmZmZdd lmZmZdd lmZmZmZd d d gZGdd d e ZGdd d eeZ Gdd d eZ!dS)) annotationsN)CallableSequence)Dataset) MetaTensor)iter_patch_position) BaseWSIReader WSIReader)ForegroundMask Randomizableapply_transform)convert_to_dst_typeensure_tuple_rep) CommonKeys ProbMapKeys WSIPatchKeysPatchWSIDatasetSlidingPatchWSIDatasetMaskedPatchWSIDatasetc seZdZdZd ddddd d d d fd d ZddddZddddZddddZddddZddddZ ddddZ ddddZ Z S)!ra' This dataset extracts patches from whole slide images (without loading the whole image) It also reads labels for each patch and provides each patch with its associated class labels. Args: data: the list of input samples including image, location, and label (see the note below for more details). patch_size: the size of patch to be extracted from the whole slide image. patch_level: the level at which the patches to be extracted (default to 0). transform: transforms to be executed on input data. include_label: whether to load and include labels in the output center_location: whether the input location information is the position of the center of the patch additional_meta_keys: the list of keys for items to be copied to the output metadata from the input data reader: the module to be used for loading whole slide imaging. If `reader` is - a string, it defines the backend of `monai.data.WSIReader`. Defaults to cuCIM. - a class (inherited from `BaseWSIReader`), it is initialized and set as wsi_reader. - an instance of a class inherited from `BaseWSIReader`, it is set as the wsi_reader. kwargs: additional arguments to pass to `WSIReader` or provided whole slide reader class Returns: dict: a dictionary of loaded image (in MetaTensor format) along with the labels (if requested). {"image": MetaTensor, "label": torch.Tensor} Note: The input data has the following form as an example: .. code-block:: python [ {"image": "path/to/image1.tiff", "location": [200, 500], "label": 0}, {"image": "path/to/image2.tiff", "location": [100, 700], "patch_size": [20, 20], "patch_level": 2, "label": 1} ] NTcuCIMrint | tuple[int, int] | None int | NoneCallable | NoneboolzSequence[str] | None)data patch_size patch_level transform include_labelcenter_locationadditional_meta_keysc  st|||dkrd|_n t|d|_||_|dkr~sz1PatchWSIDataset._get_location..)r _get_sizerangelenrrErCr4rHr5 _get_location{s zPatchWSIDataset._get_locationcCs|jdkr|tjdS|jS)Nr)rgetrLEVELrCr4r4r5 _get_levels zPatchWSIDataset._get_levelcCs"|jdkrt|tjdS|jS)Nr!)rrrOrSIZErCr4r4r5rKs zPatchWSIDataset._get_sizecCsL|jdkri|_||}||}||}||}|jj||||dS)NZ openslide)wsilocationrIr#)r"r.r=rNrQrKr)get_data)r/r8wsi_objrTr#rIr4r4r5 _get_datas     zPatchWSIDataset._get_dataint)indexcCsn|j|}||\}}|jD]}||||<qtjt||di}|jrX|||tj<|j rjt |j |S|S)N)meta) rrWr rr:rrrDrArr )r/rYr8imagemetadatakeyoutputr4r4r5 _transforms  zPatchWSIDataset._transform)NNNTTNr) __name__ __module__ __qualname____doc__r&r=rDrNrQrKrWr_ __classcell__r4r4r2r5r s ' - csreZdZdZdddddddddejejejfddf dd d d d d dddddd d fdd ZddZ ddZ Z S)rav This dataset extracts patches in sliding-window manner from whole slide images (without loading the whole image). It also reads labels for each patch and provides each patch with its associated class labels. Args: data: the list of input samples including image, location, and label (see the note below for more details). patch_size: the size of patch to be extracted from the whole slide image. patch_level: the level at which the patches to be extracted (default to 0). mask_level: the resolution level at which the mask/map is created (for `ProbMapProducer` for instance). overlap: the amount of overlap of neighboring patches in each dimension (a value between 0.0 and 1.0). If only one float number is given, it will be applied to all dimensions. Defaults to 0.0. offset: the offset of image to extract patches (the starting position of the upper left patch). offset_limits: if offset is set to "random", a tuple of integers defining the lower and upper limit of the random offset for all dimensions, or a tuple of tuples that defines the limits for each dimension. transform: transforms to be executed on input data. include_label: whether to load and include labels in the output center_location: whether the input location information is the position of the center of the patch additional_meta_keys: the list of keys for items to be copied to the output metadata from the input data reader: the module to be used for loading whole slide imaging. Defaults to cuCIM. If `reader` is - a string, it defines the backend of `monai.data.WSIReader`. - a class (inherited from `BaseWSIReader`), it is initialized and set as wsi_reader, - an instance of a class inherited from `BaseWSIReader`, it is set as the wsi_reader. seed: random seed to randomly generate offsets. Defaults to 0. kwargs: additional arguments to pass to `WSIReader` or provided whole slide reader class Note: The input data has the following form as an example: .. code-block:: python [ {"image": "path/to/image1.tiff"}, {"image": "path/to/image2.tiff", "patch_size": [20, 20], "patch_level": 2} ] Unlike `MaskedPatchWSIDataset`, this dataset does not filter any patches. Nrg)rrFrrrrrXztuple[float, float] | floatztuple[int, int] | int | strz@tuple[tuple[int, int], tuple[int, int]] | tuple[int, int] | Nonerr Sequence[str]) rrr mask_leveloverlapoffset offset_limitsrrrr seedc s tjfg|||| | | | d|||_|| d|_t|tr|dkrd|_||dkrfd|_qt|trt|dt r||f|_qt|dtr||_qt dqt dqt d|d n t |d |_ ||_ |t||_|jD]}||}|j|qdS) Nrrrrrrr r0FrandomTrzUThe offset limits should be either a tuple of integers or tuple of tuple of integers.z$The offset limits should be a tuple.zInvalid string for offset "zc". It should be either "random" as a string,an integer, or a tuple of integers defining the offset.r!)r%r&rgset_random_state random_offsetr'r(rituplerXr-rrhrflist image_data_evaluate_patch_locationsrextend)r/rrrrfrgrhrirrrr r0rjr1r8 patch_samplesr2r4r5r&sP            zSlidingPatchWSIDataset.__init__csLjrFjdkr*tdd|D}nj}tfdd|DSjS)Ncss|]}| |fVqdSr9r4)rFsr4r4r5 sz5SlidingPatchWSIDataset._get_offset..c3s |]\}}j||VqdSr9)Rrandint)rFlowhighr/r4r5rvs)rnrirorKrh)r/r8rir4r{r5 _get_offsets  z"SlidingPatchWSIDataset._get_offsetc s|}|}|}|j|d}|j||j}|j||tfdd|D}| }tt t ||||j dd} t | |dt|} |tjj<|tjj<tjtjtjj<t| tjj<t|j||jtjj<fddt| | DS)z@Calculate the location for each patch in a sliding-window mannerrcsg|] }|qSr4r4rFp patch_ratior4r5rJ)szDSlidingPatchWSIDataset._evaluate_patch_locations..F) image_sizer start_posrgpaddedr!cs.g|]&\}}tjjt|tjj|iqSr4rrEvaluenparrayrrFlocZmask_locr7r4r5rJ;s)rKrQr=r)get_sizeget_downsample_ratiorfrrr|rprrgroundfloatrrRrrPospathbasenamerr:rNAMErMCOUNTzip) r/r8rrrVZwsi_size mask_ratio patch_size_0rhpatch_locationsmask_locationsr4rr8r5rrs8       z0SlidingPatchWSIDataset._evaluate_patch_locations) r`rarbrcrrErRrr&r|rrrdr4r4r2r5rs +*A c sVeZdZdZddddddejejfdfdddd d d d d d fdd ZddZZ S)ra4 This dataset extracts patches from whole slide images at the locations where foreground mask at a given level is non-zero. Args: data: the list of input samples including image, location, and label (see the note below for more details). patch_size: the size of patch to be extracted from the whole slide image. patch_level: the level at which the patches to be extracted (default to 0). mask_level: the resolution level at which the mask is created. transform: transforms to be executed on input data. include_label: whether to load and include labels in the output center_location: whether the input location information is the position of the center of the patch additional_meta_keys: the list of keys for items to be copied to the output metadata from the input data reader: the module to be used for loading whole slide imaging. Defaults to cuCIM. If `reader` is - a string, it defines the backend of `monai.data.WSIReader`. - a class (inherited from `BaseWSIReader`), it is initialized and set as wsi_reader, - an instance of a class inherited from `BaseWSIReader`, it is set as the wsi_reader. kwargs: additional arguments to pass to `WSIReader` or provided whole slide reader class Note: The input data has the following form as an example: .. code-block:: python [ {"image": "path/to/image1.tiff"}, {"image": "path/to/image2.tiff", "size": [20, 20], "level": 2} ] NFrrrrrXrrre)rrrrfrrrr c s^tjfg||||||| d| ||_|t||_|jD]} || } |j| q>dS)Nrk)r%r&rfrprqrrrrs) r/rrrrfrrrr r0r1r8rtr2r4r5r&cs$      zMaskedPatchWSIDataset.__init__c s*|}|}|}|jj||jd\}}ttt ddid||dd}t | j }|j ||j} |j ||tfdd|D} t|d t| | d t} |tjj<|tjj<tjtjtjj<t| tjj<|j tjj<fd dt!| |DS) zUCalculate the location for each patch based on the mask at different resolution level)r#Sotsu) hsv_threshold)dstrcsg|] }|qSr4r4r}rr4r5rJszCMaskedPatchWSIDataset._evaluate_patch_locations..g?r!cs.g|]&\}}tjjt|tjj|iqSr4rrr7r4r5rJs)"rKrQr=r)rUrfrsqueezer r vstacknonzeroTrrrrastyperXrrRrrPrrrrr:rrrMrshaper) r/r8rrrVrS_maskrrrrr4rr5rrs$   $$   z/MaskedPatchWSIDataset._evaluate_patch_locations) r`rarbrcrrErr&rrrdr4r4r2r5rAs$ "!)" __future__rr*rcollections.abcrrnumpyrr? monai.datarmonai.data.meta_tensorrmonai.data.utilsrZmonai.data.wsi_readerrr monai.transformsr r r monai.utilsr rmonai.utils.enumsrrr__all__rrrr4r4r4r5 s$