Exemple #1
0
    def __init__(
        self,
        keys: KeysCollection,
        meta_keys: Optional[KeysCollection] = None,
        meta_key_postfix: str = "meta_dict",
    ) -> None:
        """
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            meta_keys: explicitly indicate the key of the corresponding meta data dictionary.
                for example, for data with key `image`, the metadata by default is in `image_meta_dict`.
                the meta data is a dictionary object which contains: filename, original_shape, etc.
                it can be a sequence of string, map to the `keys`.
                if None, will try to construct meta_keys by `key_{meta_key_postfix}`.
            meta_key_postfix: if meta_keys is None and `key_{postfix}` was used to store the metadata in `LoadImaged`.
                So need the key to extract metadata for channel dim information, default is `meta_dict`.
                For example, for data with key `image`, metadata by default is in `image_meta_dict`.

        """
        super().__init__(keys)
        self.adjuster = EnsureChannelFirst()
        self.meta_keys = ensure_tuple_rep(meta_keys, len(self.keys))
        self.meta_key_postfix = ensure_tuple_rep(meta_key_postfix,
                                                 len(self.keys))
Exemple #2
0
    def get_data(
        self,
        img,
        location: Tuple[int, int] = (0, 0),
        size: Optional[Tuple[int, int]] = None,
        level: int = 0,
        dtype: DtypeLike = np.uint8,
        grid_shape: Tuple[int, int] = (1, 1),
        patch_size: Optional[int] = None,
    ):
        """
        Extract regions as numpy array from WSI image and return them.

        Args:
            img: a WSIReader image object loaded from a file, or list of CuImage objects
            location: (x_min, y_min) tuple giving the top left pixel in the level 0 reference frame,
            or list of tuples (default=(0, 0))
            size: (height, width) tuple giving the region size, or list of tuples (default to full image size)
            This is the size of image at the given level (`level`)
            level: the level number, or list of level numbers (default=0)
            dtype: the data type of output image
            grid_shape: (row, columns) tuple define a grid to extract patches on that
            patch_size: (heigsht, width) the size of extracted patches at the given level
        """
        if size is None:
            if location == (0, 0):
                # the maximum size is set to WxH
                size = (img.shape[0] // (2**level), img.shape[1] // (2**level))
                print(
                    f"Reading the whole image at level={level} with shape={size}"
                )
            else:
                raise ValueError(
                    "Size need to be provided to extract the region!")

        region = self._extract_region(img,
                                      location=location,
                                      size=size,
                                      level=level,
                                      dtype=dtype)

        metadata: Dict = {}
        metadata["spatial_shape"] = size
        metadata["original_channel_dim"] = -1
        region = EnsureChannelFirst()(region, metadata)

        if patch_size is None:
            patches = region
        else:
            patches = self._extract_patches(region,
                                            patch_size=(patch_size,
                                                        patch_size),
                                            grid_shape=grid_shape,
                                            dtype=dtype)

        return patches, metadata
Exemple #3
0
    def get_data(
        self,
        img,
        location: Tuple[int, int] = (0, 0),
        size: Optional[Tuple[int, int]] = None,
        level: int = 0,
        dtype: DtypeLike = np.uint8,
        grid_shape: Tuple[int, int] = (1, 1),
        patch_size: Optional[Union[int, Tuple[int, int]]] = None,
    ):
        """
        Extract regions as numpy array from WSI image and return them.

        Args:
            img: a WSIReader image object loaded from a file, or list of CuImage objects
            location: (x_min, y_min) tuple giving the top left pixel in the level 0 reference frame,
            or list of tuples (default=(0, 0))
            size: (height, width) tuple giving the region size, or list of tuples (default to full image size)
            This is the size of image at the given level (`level`)
            level: the level number, or list of level numbers (default=0)
            dtype: the data type of output image
            grid_shape: (row, columns) tuple define a grid to extract patches on that
            patch_size: (height, width) the size of extracted patches at the given level
        """

        if self.reader_lib == "openslide" and size is None:
            # the maximum size is set to WxH
            size = (
                img.shape[0] // (2**level) - location[0],
                img.shape[1] // (2**level) - location[1],
            )

        region = self._extract_region(img,
                                      location=location,
                                      size=size,
                                      level=level,
                                      dtype=dtype)

        metadata: Dict = {}
        metadata["spatial_shape"] = size
        metadata["original_channel_dim"] = -1
        region = EnsureChannelFirst()(region, metadata)
        if patch_size is None:
            patches = region
        else:
            tuple_patch_size = ensure_tuple_rep(patch_size, 2)
            patches = self._extract_patches(
                region,
                patch_size=tuple_patch_size,  # type: ignore
                grid_shape=grid_shape,
                dtype=dtype,
            )

        return patches, metadata
Exemple #4
0
    def __init__(self, keys: KeysCollection, meta_key_postfix: str = "meta_dict") -> None:
        """
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            meta_key_postfix: `key_{postfix}` was used to store the metadata in `LoadImaged`.
                So need the key to extract metadata for channel dim information, default is `meta_dict`.
                For example, for data with key `image`, metadata by default is in `image_meta_dict`.

        """
        super().__init__(keys)
        self.adjuster = EnsureChannelFirst()
        self.meta_key_postfix = meta_key_postfix
Exemple #5
0
    def __call__(self, filename: Union[Sequence[PathLike], PathLike], reader: Optional[ImageReader] = None):
        """
        Load image file and meta data from the given filename(s).
        If `reader` is not specified, this class automatically chooses readers based on the
        reversed order of registered readers `self.readers`.

        Args:
            filename: path file or file-like object or a list of files.
                will save the filename to meta_data with key `filename_or_obj`.
                if provided a list of files, use the filename of first file to save,
                and will stack them together as multi-channels data.
                if provided directory path instead of file path, will treat it as
                DICOM images series and read.
            reader: runtime reader to load image file and meta data.

        """
        filename = tuple(f"{Path(s).expanduser()}" for s in ensure_tuple(filename))  # allow Path objects
        img, err = None, []
        if reader is not None:
            img = reader.read(filename)  # runtime specified reader
        else:
            for reader in self.readers[::-1]:
                if self.auto_select:  # rely on the filename extension to choose the reader
                    if reader.verify_suffix(filename):
                        img = reader.read(filename)
                        break
                else:  # try the user designated readers
                    try:
                        img = reader.read(filename)
                    except Exception as e:
                        err.append(traceback.format_exc())
                        logging.getLogger(self.__class__.__name__).debug(e, exc_info=True)
                        logging.getLogger(self.__class__.__name__).info(
                            f"{reader.__class__.__name__}: unable to load {filename}.\n"
                        )
                    else:
                        err = []
                        break

        if img is None or reader is None:
            if isinstance(filename, tuple) and len(filename) == 1:
                filename = filename[0]
            msg = "\n".join([f"{e}" for e in err])
            raise RuntimeError(
                f"{self.__class__.__name__} cannot find a suitable reader for file: {filename}.\n"
                "    Please install the reader libraries, see also the installation instructions:\n"
                "    https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies.\n"
                f"   The current registered: {self.readers}.\n{msg}"
            )

        img_array: NdarrayOrTensor
        img_array, meta_data = reader.get_data(img)
        img_array = img_array.astype(self.dtype, copy=False)
        if not isinstance(meta_data, dict):
            raise ValueError("`meta_data` must be a dict.")
        # make sure all elements in metadata are little endian
        meta_data = switch_endianness(meta_data, "<")
        if self.ensure_channel_first:
            img_array = EnsureChannelFirst()(img_array, meta_data)

        if self.image_only:
            return img_array
        meta_data[Key.FILENAME_OR_OBJ] = f"{ensure_tuple(filename)[0]}"  # Path obj should be strings for data loader

        return img_array, meta_data