From 00f3362af5df6e279e5978b6117517c34adf93cd Mon Sep 17 00:00:00 2001
From: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
Date: Tue, 24 Sep 2024 13:59:47 -0400
Subject: [PATCH 1/7] Fixed dependency issues with itkwidgets
---
...PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb | 1530 +++++++++--------
1 file changed, 792 insertions(+), 738 deletions(-)
diff --git a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
index f1dc6f0e5f..15d89d16b1 100644
--- a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
+++ b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
@@ -1,771 +1,825 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "Yxvh7SsKbvv_"
- },
- "source": [
- "Copyright (c) MONAI Consortium \n",
- "Licensed under the Apache License, Version 2.0 (the \"License\"); \n",
- "you may not use this file except in compliance with the License. \n",
- "You may obtain a copy of the License at \n",
- " http://www.apache.org/licenses/LICENSE-2.0 \n",
- "Unless required by applicable law or agreed to in writing, software \n",
- "distributed under the License is distributed on an \"AS IS\" BASIS, \n",
- "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n",
- "See the License for the specific language governing permissions and \n",
- "limitations under the License.\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "M565w1lqtd4M"
- },
- "source": [
- "You can download and run this notebook locally, or you can run it for free in a cloud environment using Colab or Sagemaker Studio Lab:\n",
- "\n",
- "[](https://colab.research.google.com/github/Project-MONAI/tutorials/blob/main/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb)\n",
- "\n",
- "[](https://studiolab.sagemaker.aws/import/github.com/Project-MONAI/tutorials/blob/main/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "N92pMd7ig0ZS",
- "jp-MarkdownHeadingCollapsed": true,
- "tags": []
- },
- "source": [
- "# Summary\n",
- "This notebook demonstrates downloading the [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model from MONAI's Model Zoo and applying it to segment a subset of data from the [SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection](https://doi.org/10.7937/K9TCIA.2017.MURS5CL10.7937/TCIA.X0H0-1706) on [The Cancer Imaging Archive (TCIA)](https://www.cancerimagingarchive.net/). The resulting data are then visualized using [itkWidgets].(https://github.com/InsightSoftwareConsortium/itkwidgets)\n",
- "\n",
- "Features demonstrated include:\n",
- "* Using a python script to download and load a model from MONAI's Model Zoo into python.\n",
- "* Downloading and preparing data from TCIA for processing using that model.\n",
- "* Applying the model to the TCIA data.\n",
- "* Visually comparing model results with expert segmentation results available on TCIA.\n",
- "\n",
- "# Background\n",
- "[MONAI's Model Zoo](https://monai.io/model-zoo.html) provides pre-trained AI deep learning models that can be downloaded and used to process new data or as a starting point for transfer learning. The [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model was trained with the UNet architecture and is used for 3D volumetric segmentation of the anatomical prostate zones on T2w MRI images. The segmentation of the anatomical regions is formulated as a voxel-wise classification. Each voxel is classified as either central gland (1), peripheral zone (2), or background (0). The model is optimized using a gradient descent method that minimizes the focal soft-dice loss between the predicted mask and the actual segmentation. The model was trained in the prostate158 training data, which is available at https://doi.org/10.5281/zenodo.6481141. Only T2w images were used for this task.\n",
- "\n",
- "[The Cancer Imaging Archive (TCIA)](https://www.cancerimagingarchive.net/) is a public service funded by the National Cancer Institute that addresses this challenge by providing hosting and de-identification services to take major burdens of data sharing off researchers. Its rich collection of clinical data and annotations is particularly powerful as a community resource when it is paired with interactive code systems, such as Jupyter systems.\n",
- "\n",
- "[itkWidgets](https://github.com/InsightSoftwareConsortium/itkwidgets) allows researchers to visualize images, point sets, and 3D geometry in Jupyter systems (Jupyer Notebooks, JupyterLab, AWS SageMaker, and Google Colab). Despite its name, itkWidgets does not require the use of ITK. It can directly visualize numpy arrays, torch tensors, DASK arrays, VTK polydata, and a multitude of other python data structures."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "nj6P7YCmll4S",
- "tags": []
- },
- "source": [
- "# Outline\n",
- "\n",
- "1. Setup\n",
- "2. Download data from TCIA\n",
- "3. Prepare the data with ITK\n",
- "4. Setup itkWidgets\n",
- "5. MONAI Zoo Basics\n",
- "6. MONAI Model Inference\n",
- "7. Visualizing and Comparing Model and Expert Results"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "8FgizAMWemJM"
- },
- "source": [
- "# 1. Setup\n",
- "\n",
- "These are the initial steps for running notebooks within various Jupyter environments."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "As3EplXrbvwF"
- },
- "source": [
- "## Setup environment"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "K3DOvHnXsf-I",
- "tags": []
- },
- "outputs": [],
- "source": [
- "# Install itk for DICOM I/O and for reading DICOM into an itkImage\n",
- "# that manages all DICOM field values, include acquistion details\n",
- "# such as voxel image, image orientation, and image directions,\n",
- "# which are critical to image processing and display.\n",
- "\n",
- "# Upgrade pip, just in case.\n",
- "!python -m pip install --upgrade -q pip\n",
- "\n",
- "# installations required for monai\n",
- "!python -c \"import monai\" || pip install -q \"monai[nibabel,itk,tqdm,pandas,skimage]\"\n",
- "!python -c \"import cv2\" || pip install -q opencv-python-headless\n",
- "\n",
- "# These are the libraries used to read DICOM Seg objects.\n",
- "!python -m pip install -q pydicom pydicom-seg\n",
- "\n",
- "# Install tcia_utils to download the datasets.\n",
- "!python -m pip install --upgrade -q --no-deps tcia_utils\n",
- "\n",
- "# Install the dependency manually to avoid installing opencv-python.\n",
- "!python -m pip install -q plotly bs4 ipywidgets unidecode jsonschema\n",
- "!python -m pip install -q --no-deps rt-utils\n",
- "\n",
- "# This is the installation required for itkWidgets.\n",
- "!python -m pip install --upgrade --pre -q \"itkwidgets[all]==1.0a23\" imjoy_elfinder"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "oYxvN-rebvwG"
- },
- "source": [
- "## Setup imports\n",
- "\n",
- "### Setup the im-joy-jupyter-extension for itkWidgets\n",
- "On many systems you must manually install the imjoy-jupyter-extension for itkWidgets! If you do not see a blue 'ImJoy' icon on the menu bar in this notebook:\n",
- "\n",
- "* Google CoLab: The following does not apply to Google CoLab - it will not show an ImJoy and all should work without modification.\n",
- "* Enable Extensions: Many Jupyter Lab systems disable jupyter extensions by default, and they must be enabled for this notebook to work. Typically this is accomplished using the Jupyter interface to select the extension manager (left-hand side, icon that looks like a piece of a puzzle) and select the Enable button if it appears.\n",
- "* Install imjoy extension: In the extension manager, search for 'imjoy' and install the 'imjoy-jupyter-extension'. The installation can take several minutes. It may also prompt you to rebuild, save, and reload your jupyter environment as part of this process. In the end, you should see a blue 'ImJoy' icon on the left side of the menu bar in this notebook."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "tF8-MqoN6YT5"
- },
- "outputs": [],
- "source": [
- "import glob\n",
- "import os\n",
- "\n",
- "# Numpy for numpy.arrays\n",
- "import numpy as np\n",
- "\n",
- "# Include ITK for DICOM reading.\n",
- "import itk\n",
- "\n",
- "# Include pydicom_seg for DICOM SEG objects\n",
- "import pydicom\n",
- "import pydicom_seg\n",
- "\n",
- "# for downloading data from TCIA\n",
- "from tcia_utils import nbia\n",
- "\n",
- "# This is the most common import command for itkWidgets.\n",
- "# The view() function opens an interactive viewer for 2D and 3D\n",
- "# data in a variety of formats.\n",
- "from itkwidgets import view\n",
- "\n",
- "# imports for monai\n",
- "import torch\n",
- "from monai.data import decollate_batch\n",
- "from monai.bundle import ConfigParser, download\n",
- "\n",
- "from monai.config import print_config\n",
- "\n",
- "print_config()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "Ub0GzFRXemJN"
- },
- "outputs": [],
- "source": [
- "# If running on SageMaker or Studio Lab, install essential packages and extensions.\n",
- "if \"studio-lab-user\" in os.getcwd():\n",
- " print(\"Upgrading dependencies\")\n",
- " !conda install --yes -q --prefix {sys.prefix} -c conda-forge opencv nodejs"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "di4lxyikemJN",
- "outputId": "408c7a4d-492f-43cf-cb38-afa92d1f53d3"
- },
- "source": [
- "# 2. Download the data from TCIA\n",
- "\n",
- "[Browsing Collections](https://www.cancerimagingarchive.net/collections) and viewing [Analysis Results](https://www.cancerimagingarchive.net/tcia-analysis-results/) of datasets on TCIA are the easiest ways to become familiar with what is available. These pages will help you quickly identify datasets of interest, find valuable, supporting data that are not available via TCIA's APIs (e.g. clinical spreadsheets, non-DICOM segmentation data), and answer the most common questions you might have about the datasets. In this tutorial we'll be working with the [SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection](https://doi.org/10.7937/K9TCIA.2017.MURS5CL), but if you browse the previously mentioned links you will find that TCIA has many other prostate datasets which could be used with the [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model. \n",
- "\n",
- "We will utilize the [tcia_utils](https://pypi.org/project/tcia-utils/) package to simplify downloading the data from TCIA. If you are new to accessing TCIA via notebooks, you can find additional tutorials on querying and downloading data at https://github.com/kirbyju/TCIA_Notebooks. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "urhgDgvb39pS"
- },
- "outputs": [],
- "source": [
- "# Download a \"Shared Cart\" containing 6 scans from PROSTATEx\n",
- "# that has been previously created via the TCIA website\n",
- "# (https://nbia.cancerimagingarchive.net).\n",
- "cart_name = \"nbia-17571668146714049\"\n",
- "\n",
- "# retrieve cart metadata\n",
- "cart_data = nbia.getSharedCart(cart_name)\n",
- "\n",
- "# download the series_uids list and return dataframe of metadata\n",
- "df = nbia.downloadSeries(cart_data, format=\"df\")\n",
- "\n",
- "# display dataframe\n",
- "# display(df)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "MGPw6j3hbvwI"
- },
- "source": [
- "# 3. Prepare the data with itk\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "7wR4HJu-emJP"
- },
- "outputs": [],
- "source": [
- "dicom_data_dir = \"tciaDownload\"\n",
- "\n",
- "# The series_uid defines their directory where the MR data was stored on disk.\n",
- "mr_series_uid = df.at[df.Modality.eq(\"MR\").idxmax(), \"Series UID\"]\n",
- "mr_dir = os.path.join(dicom_data_dir, mr_series_uid)\n",
- "\n",
- "# Read the DICOM MR series' objects and reconstruct them into a 3D ITK image.\n",
- "# The itk.F option is added to store the image in memory using floating-point precision pixels (useful if you will filter the image or use it with MONAI).\n",
- "# For more info on imread, see https://itkpythonpackage.readthedocs.io/en/master/Quick_start_guide.html.\n",
- "mr_image = itk.imread(mr_dir, itk.F)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "JdT44AzPemJP"
- },
- "outputs": [],
- "source": [
- "# The series_uid defines where the RTSTRUCT was stored on disk. It is stored in a single file.\n",
- "seg_series_uid = df.at[df.Modality.eq(\"SEG\").idxmax(), \"Series UID\"]\n",
- "seg_dir = os.path.join(dicom_data_dir, seg_series_uid)\n",
- "seg_file = glob.glob(os.path.join(seg_dir, \"*.dcm\"))[0]\n",
- "\n",
- "# Read the DICOM SEG object using pydicom and pydicom_seg.\n",
- "seg_dicom = pydicom.dcmread(seg_file)\n",
- "seg_reader = pydicom_seg.MultiClassReader()\n",
- "seg_obj = seg_reader.read(seg_dicom)\n",
- "\n",
- "# Convert the DICOM SEG object into an itk image, with correct voxel origin, spacing, and directions in physical space.\n",
- "seg_image = itk.GetImageFromArray(seg_obj.data.astype(np.float32))\n",
- "seg_image.CopyInformation(mr_image)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "yGV9j8TbemJP",
- "tags": []
- },
- "source": [
- "# 4. MONAI Zoo Basics"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "diJ1EeQQemJQ"
- },
- "outputs": [],
- "source": [
- "model_name = \"prostate_mri_anatomy\"\n",
- "model_version = \"0.3.1\"\n",
- "zoo_dir = os.path.abspath(\"./models\")\n",
- "\n",
- "download(name=model_name, version=model_version, bundle_dir=zoo_dir)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "xcj8cA_ZemJQ"
- },
- "outputs": [],
- "source": [
- "# This model includes scripts that must be run on new data.\n",
- "# We could import those scripts into this python notebook, but they\n",
- "# bring in additional dependencies. Instead, we provide the following\n",
- "# more compact and compatible implementation. Otherwise, you can\n",
- "# include the model's script directory by uncommenting these lines and\n",
- "# installing their dependencies and doing appropriate data conversions.\n",
- "# scripts_dir = os.path.join(zoo_dir, model_name, \"scripts\")\n",
- "# sys.path.insert(1, scripts_dir)\n",
- "\n",
- "\n",
- "# Compact alternative implementation of this model's specific cropping step.\n",
- "# Ideally this would have been accomplished using MONAI's transforms\n",
- "# for data pre-processing / augmentation instead of using a separate\n",
- "# function.\n",
- "def prostate_crop(img):\n",
- " boundary = [int(crop_size * 0.2) for crop_size in img.GetLargestPossibleRegion().GetSize()]\n",
- " new_image = itk.CropImageFilter(Input=img, BoundaryCropSize=boundary)\n",
- " return new_image\n",
- "\n",
- "\n",
- "mr_image_prep = prostate_crop(mr_image)\n",
- "seg_image_prep = prostate_crop(seg_image)\n",
- "\n",
- "# Running a MONAI model on new data requires that data to be saved on\n",
- "# local disk.\n",
- "itk.imwrite(mr_image_prep, mr_dir + \".nii.gz\")\n",
- "itk.imwrite(seg_image_prep, seg_dir + \".nii.gz\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "YhDJqRkHemJQ"
- },
- "outputs": [],
- "source": [
- "# The model's config file dynamically generates the functions needed to process new data.\n",
- "\n",
- "# Define our local system and filesystem.\n",
- "output_dir = os.path.abspath(\"./monai_results\")\n",
- "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
- "\n",
- "# Parse the variables in the config file.\n",
- "model_config_file = os.path.join(zoo_dir, model_name, \"configs\", \"inference.json\")\n",
- "model_config = ConfigParser()\n",
- "model_config.read_config(model_config_file)\n",
- "\n",
- "# Update the confir variables to match our filesystem.\n",
- "model_config[\"bundle_root\"] = zoo_dir\n",
- "model_config[\"output_dir\"] = output_dir\n",
- "\n",
- "# Identify which version of the model we want to load (each version is a\n",
- "# \"checkpoint\"). For most models, the \"best\" checkpoint is called \"model.pt\"\n",
- "# and it is stored in the models subdir.\n",
- "checkpoint = os.path.join(zoo_dir, model_name, \"models\", \"model.pt\")\n",
- "\n",
- "# Ask the config file to generate the functions needed to process new data.\n",
- "# These functions are adapted to our system by the config variables we\n",
- "# modified above. The order of first defining variables and then creating the\n",
- "# functions is critical.\n",
- "preprocessing = model_config.get_parsed_content(\"preprocessing\")\n",
- "\n",
- "model = model_config.get_parsed_content(\"network\").to(device)\n",
- "\n",
- "inferer = model_config.get_parsed_content(\"inferer\")\n",
- "\n",
- "postprocessing = model_config.get_parsed_content(\"postprocessing\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "CqoHulOhemJR"
- },
- "outputs": [],
- "source": [
- "# Point the dataloader to the downloaded and converted TCIA data.\n",
- "datalist = [mr_dir + \".nii.gz\"]\n",
- "model_config[\"datalist\"] = datalist\n",
- "dataloader = model_config.get_parsed_content(\"dataloader\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "zX0UIVt9bvwJ"
- },
- "source": [
- "# 5. Visualize the data with itkWidgets\n",
- "\n",
- "[itkWidgets documentation](https://itkwidgets.readthedocs.io/en/latest/?badge=latest) provides a summary and illustrations of itkWidgets for a wide variety of scientific data visualization use cases."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "RF4LqDs-emJR",
- "tags": []
- },
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- "
\n",
- " \n",
- " "
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Yxvh7SsKbvv_"
+ },
+ "source": [
+ "Copyright (c) MONAI Consortium \n",
+ "Licensed under the Apache License, Version 2.0 (the \"License\"); \n",
+ "you may not use this file except in compliance with the License. \n",
+ "You may obtain a copy of the License at \n",
+ " http://www.apache.org/licenses/LICENSE-2.0 \n",
+ "Unless required by applicable law or agreed to in writing, software \n",
+ "distributed under the License is distributed on an \"AS IS\" BASIS, \n",
+ "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n",
+ "See the License for the specific language governing permissions and \n",
+ "limitations under the License.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "M565w1lqtd4M"
+ },
+ "source": [
+ "You can download and run this notebook locally, or you can run it for free in a cloud environment using Colab or Sagemaker Studio Lab:\n",
+ "\n",
+ "[](https://colab.research.google.com/github/Project-MONAI/tutorials/blob/main/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb)\n",
+ "\n",
+ "[](https://studiolab.sagemaker.aws/import/github.com/Project-MONAI/tutorials/blob/main/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "N92pMd7ig0ZS",
+ "jp-MarkdownHeadingCollapsed": true,
+ "tags": []
+ },
+ "source": [
+ "# Summary\n",
+ "This notebook demonstrates downloading the [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model from MONAI's Model Zoo and applying it to segment a subset of data from the [SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection](https://doi.org/10.7937/K9TCIA.2017.MURS5CL10.7937/TCIA.X0H0-1706) on [The Cancer Imaging Archive (TCIA)](https://www.cancerimagingarchive.net/). The resulting data are then visualized using [itkWidgets].(https://github.com/InsightSoftwareConsortium/itkwidgets)\n",
+ "\n",
+ "Features demonstrated include:\n",
+ "* Using a python script to download and load a model from MONAI's Model Zoo into python.\n",
+ "* Downloading and preparing data from TCIA for processing using that model.\n",
+ "* Applying the model to the TCIA data.\n",
+ "* Visually comparing model results with expert segmentation results available on TCIA.\n",
+ "\n",
+ "# Background\n",
+ "[MONAI's Model Zoo](https://monai.io/model-zoo.html) provides pre-trained AI deep learning models that can be downloaded and used to process new data or as a starting point for transfer learning. The [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model was trained with the UNet architecture and is used for 3D volumetric segmentation of the anatomical prostate zones on T2w MRI images. The segmentation of the anatomical regions is formulated as a voxel-wise classification. Each voxel is classified as either central gland (1), peripheral zone (2), or background (0). The model is optimized using a gradient descent method that minimizes the focal soft-dice loss between the predicted mask and the actual segmentation. The model was trained in the prostate158 training data, which is available at https://doi.org/10.5281/zenodo.6481141. Only T2w images were used for this task.\n",
+ "\n",
+ "[The Cancer Imaging Archive (TCIA)](https://www.cancerimagingarchive.net/) is a public service funded by the National Cancer Institute that addresses this challenge by providing hosting and de-identification services to take major burdens of data sharing off researchers. Its rich collection of clinical data and annotations is particularly powerful as a community resource when it is paired with interactive code systems, such as Jupyter systems.\n",
+ "\n",
+ "[itkWidgets](https://github.com/InsightSoftwareConsortium/itkwidgets) allows researchers to visualize images, point sets, and 3D geometry in Jupyter systems (Jupyer Notebooks, JupyterLab, AWS SageMaker, and Google Colab). Despite its name, itkWidgets does not require the use of ITK. It can directly visualize numpy arrays, torch tensors, DASK arrays, VTK polydata, and a multitude of other python data structures."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nj6P7YCmll4S",
+ "tags": []
+ },
+ "source": [
+ "# Outline\n",
+ "\n",
+ "1. Setup\n",
+ "2. Download data from TCIA\n",
+ "3. Prepare the data with ITK\n",
+ "4. Setup itkWidgets\n",
+ "5. MONAI Zoo Basics\n",
+ "6. MONAI Model Inference\n",
+ "7. Visualizing and Comparing Model and Expert Results"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8FgizAMWemJM"
+ },
+ "source": [
+ "# 1. Setup\n",
+ "\n",
+ "These are the initial steps for running notebooks within various Jupyter environments."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "As3EplXrbvwF"
+ },
+ "source": [
+ "## Setup environment"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "id": "K3DOvHnXsf-I",
+ "tags": [],
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "33af56ea-940d-4a3d-fd8e-4b9370a5954d"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m80.2/80.2 MB\u001b[0m \u001b[31m50.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.7/67.7 MB\u001b[0m \u001b[31m52.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m28.0/28.0 MB\u001b[0m \u001b[31m101.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m57.0/57.0 MB\u001b[0m \u001b[31m44.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m28.4/28.4 MB\u001b[0m \u001b[31m97.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m15.8/15.8 MB\u001b[0m \u001b[31m91.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m28.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m28.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.4/52.4 MB\u001b[0m \u001b[31m58.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.0/4.0 MB\u001b[0m \u001b[31m41.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m71.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m8.6/8.6 MB\u001b[0m \u001b[31m97.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.8/3.8 MB\u001b[0m \u001b[31m75.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.1/6.1 MB\u001b[0m \u001b[31m92.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.0/6.0 MB\u001b[0m \u001b[31m70.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[?25h Building wheel for elfinder-client (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ " Building wheel for asciitree (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
+ "albumentations 1.4.15 requires pydantic>=2.7.0, but you have pydantic 1.10.18 which is incompatible.\u001b[0m\u001b[31m\n",
+ "\u001b[0m"
+ ]
+ }
],
- "text/plain": [
- ""
+ "source": [
+ "# Install itk for DICOM I/O and for reading DICOM into an itkImage\n",
+ "# that manages all DICOM field values, include acquistion details\n",
+ "# such as voxel image, image orientation, and image directions,\n",
+ "# which are critical to image processing and display.\n",
+ "\n",
+ "import sys\n",
+ "\n",
+ "# Upgrade pip, just in case.\n",
+ "!{sys.executable} -m pip install --upgrade -q pip\n",
+ "\n",
+ "# installations required for monai\n",
+ "!{sys.executable} -m pip install -q \"monai[nibabel,itk,tqdm,pandas,skimage]\"\n",
+ "!{sys.executable} -m pip install -q opencv-python-headless\n",
+ "\n",
+ "# These are the libraries used to read DICOM Seg objects.\n",
+ "!{sys.executable} -m pip install -q pydicom==2.4.4 pydicom-seg\n",
+ "\n",
+ "# Install the dependency manually to avoid installing opencv-python.\n",
+ "!{sys.executable} -m pip install -q plotly bs4 ipywidgets unidecode jsonschema\n",
+ "!{sys.executable} -m pip install -q --no-deps rt-utils\n",
+ "\n",
+ "# Install tcia_utils to download the datasets.\n",
+ "!{sys.executable} -m pip install --upgrade -q --no-deps tcia_utils\n",
+ "\n",
+ "# This is the installation required for itkWidgets.\n",
+ "!{sys.executable} -m pip install --upgrade --pre -q \"itkwidgets[all]\" imjoy_elfinder\n",
+ "\n",
+ "# TEMPORARY WORKAROUND TO RESOLVE: https://github.com/kirbyju/TCIA_Notebooks/issues/30\n",
+ "!pip uninstall -y zarr ngff_zarr\n",
+ "!pip install zarr ngff_zarr"
]
- },
- "metadata": {},
- "output_type": "display_data"
},
{
- "data": {
- "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
- "text/plain": [
- ""
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oYxvN-rebvwG"
+ },
+ "source": [
+ "## Setup imports\n",
+ "\n",
+ "### Setup the im-joy-jupyter-extension for itkWidgets\n",
+ "On many systems you must manually install the imjoy-jupyter-extension for itkWidgets! If you do not see a blue 'ImJoy' icon on the menu bar in this notebook:\n",
+ "\n",
+ "* Google CoLab: The following does not apply to Google CoLab - it will not show an ImJoy and all should work without modification.\n",
+ "* Enable Extensions: Many Jupyter Lab systems disable jupyter extensions by default, and they must be enabled for this notebook to work. Typically this is accomplished using the Jupyter interface to select the extension manager (left-hand side, icon that looks like a piece of a puzzle) and select the Enable button if it appears.\n",
+ "* Install imjoy extension: In the extension manager, search for 'imjoy' and install the 'imjoy-jupyter-extension'. The installation can take several minutes. It may also prompt you to rebuild, save, and reload your jupyter environment as part of this process. In the end, you should see a blue 'ImJoy' icon on the left side of the menu bar in this notebook."
]
- },
- "metadata": {},
- "output_type": "display_data"
},
{
- "data": {
- "text/html": [
- ""
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "id": "tF8-MqoN6YT5",
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "821ac4d2-d064-40c5-dea8-710e51afd93e"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "MONAI version: 1.3.2\n",
+ "Numpy version: 1.26.4\n",
+ "Pytorch version: 2.4.1+cu121\n",
+ "MONAI flags: HAS_EXT = False, USE_COMPILED = False, USE_META_DICT = False\n",
+ "MONAI rev id: 59a7211070538586369afd4a01eca0a7fe2e742e\n",
+ "MONAI __file__: /usr/local/lib/python3.10/dist-packages/monai/__init__.py\n",
+ "\n",
+ "Optional dependencies:\n",
+ "Pytorch Ignite version: NOT INSTALLED or UNKNOWN VERSION.\n",
+ "ITK version: 5.4.0\n",
+ "Nibabel version: 5.2.1\n",
+ "scikit-image version: 0.24.0\n",
+ "scipy version: 1.13.1\n",
+ "Pillow version: 10.4.0\n",
+ "Tensorboard version: 2.17.0\n",
+ "gdown version: 5.2.0\n",
+ "TorchVision version: 0.19.1+cu121\n",
+ "tqdm version: 4.66.5\n",
+ "lmdb version: NOT INSTALLED or UNKNOWN VERSION.\n",
+ "psutil version: 5.9.5\n",
+ "pandas version: 2.1.4\n",
+ "einops version: 0.8.0\n",
+ "transformers version: 4.44.2\n",
+ "mlflow version: NOT INSTALLED or UNKNOWN VERSION.\n",
+ "pynrrd version: NOT INSTALLED or UNKNOWN VERSION.\n",
+ "clearml version: NOT INSTALLED or UNKNOWN VERSION.\n",
+ "\n",
+ "For details about installing the optional dependencies, please visit:\n",
+ " https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies\n",
+ "\n"
+ ]
+ }
],
- "text/plain": [
- ""
+ "source": [
+ "import glob\n",
+ "import os\n",
+ "\n",
+ "# Numpy for numpy.arrays\n",
+ "import numpy as np\n",
+ "\n",
+ "# Include ITK for DICOM reading.\n",
+ "import itk\n",
+ "\n",
+ "# Include pydicom_seg for DICOM SEG objects\n",
+ "import pydicom\n",
+ "import pydicom_seg\n",
+ "\n",
+ "# for downloading data from TCIA\n",
+ "from tcia_utils import nbia\n",
+ "\n",
+ "# This is the most common import command for itkWidgets.\n",
+ "# The view() function opens an interactive viewer for 2D and 3D\n",
+ "# data in a variety of formats.\n",
+ "from itkwidgets import view\n",
+ "\n",
+ "# imports for monai\n",
+ "import monai\n",
+ "import cv2\n",
+ "import torch\n",
+ "from monai.data import decollate_batch\n",
+ "from monai.bundle import ConfigParser, download\n",
+ "\n",
+ "from monai.config import print_config\n",
+ "\n",
+ "print_config()"
]
- },
- "metadata": {},
- "output_type": "display_data"
},
{
- "data": {
- "text/plain": [
- ""
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "Ub0GzFRXemJN"
+ },
+ "outputs": [],
+ "source": [
+ "# If running on SageMaker or Studio Lab, install essential packages and extensions.\n",
+ "if \"studio-lab-user\" in os.getcwd():\n",
+ " print(\"Upgrading dependencies\")\n",
+ " !conda install --yes -q --prefix {sys.prefix} -c conda-forge opencv nodejs"
]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "view(image=mr_image_prep, label_image=seg_image_prep)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "8FmGXwzXemJR",
- "tags": []
- },
- "source": [
- "# 6. MONAI Model Inference"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "kbGZrHfWemJR",
- "tags": []
- },
- "outputs": [],
- "source": [
- "model.load_state_dict(torch.load(checkpoint, map_location=device))\n",
- "model.eval()\n",
- "results = []\n",
- "with torch.no_grad():\n",
- " for d in dataloader:\n",
- " images = d[\"image\"].to(device)\n",
- " d[\"pred\"] = inferer(images, network=model)\n",
- " results.append([postprocessing(i) for i in decollate_batch(d)])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "HrMqViotemJS"
- },
- "source": [
- "# 7. Visualizing and Comparing Model and Expert Results"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "cjLs9PjDemJS"
- },
- "outputs": [],
- "source": [
- "# Read the result image that was written into the output_dir.\n",
- "result_image = itk.imread(\n",
- " os.path.join(output_dir, os.path.split(mr_dir)[1], os.path.split(mr_dir)[1] + \"_trans.nii.gz\")\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "xkh3TtD9emJS"
- },
- "outputs": [],
- "source": [
- "# Various manipulations were done to the input image before it is fed to the model\n",
- "# for inference. As a result, the result image may not be in the same\n",
- "# spacing, orientation, etc as the original input data. So, we resample the results\n",
- "# image to match the physical properties of the original input data.\n",
- "interpolator = itk.NearestNeighborInterpolateImageFunction.New(seg_image)\n",
- "result_image_resampled = itk.resample_image_filter(\n",
- " Input=result_image, Interpolator=interpolator, reference_image=seg_image_prep, use_reference_image=True\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "id": "9bmgCBL9emJS",
- "tags": []
- },
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- "
\n",
- " \n",
- " "
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "di4lxyikemJN",
+ "outputId": "408c7a4d-492f-43cf-cb38-afa92d1f53d3"
+ },
+ "source": [
+ "# 2. Download the data from TCIA\n",
+ "\n",
+ "[Browsing Collections](https://www.cancerimagingarchive.net/collections) and viewing [Analysis Results](https://www.cancerimagingarchive.net/tcia-analysis-results/) of datasets on TCIA are the easiest ways to become familiar with what is available. These pages will help you quickly identify datasets of interest, find valuable, supporting data that are not available via TCIA's APIs (e.g. clinical spreadsheets, non-DICOM segmentation data), and answer the most common questions you might have about the datasets. In this tutorial we'll be working with the [SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection](https://doi.org/10.7937/K9TCIA.2017.MURS5CL), but if you browse the previously mentioned links you will find that TCIA has many other prostate datasets which could be used with the [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model.\n",
+ "\n",
+ "We will utilize the [tcia_utils](https://pypi.org/project/tcia-utils/) package to simplify downloading the data from TCIA. If you are new to accessing TCIA via notebooks, you can find additional tutorials on querying and downloading data at https://github.com/kirbyju/TCIA_Notebooks."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "id": "urhgDgvb39pS"
+ },
+ "outputs": [],
+ "source": [
+ "# Download a \"Shared Cart\" containing 6 scans from PROSTATEx\n",
+ "# that has been previously created via the TCIA website\n",
+ "# (https://nbia.cancerimagingarchive.net).\n",
+ "cart_name = \"nbia-17571668146714049\"\n",
+ "\n",
+ "# retrieve cart metadata\n",
+ "cart_data = nbia.getSharedCart(cart_name)\n",
+ "\n",
+ "# download the series_uids list and return dataframe of metadata\n",
+ "df = nbia.downloadSeries(cart_data, format=\"df\")\n",
+ "\n",
+ "# display dataframe\n",
+ "# display(df)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MGPw6j3hbvwI"
+ },
+ "source": [
+ "# 3. Prepare the data with itk\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "id": "7wR4HJu-emJP"
+ },
+ "outputs": [],
+ "source": [
+ "dicom_data_dir = \"tciaDownload\"\n",
+ "\n",
+ "# The series_uid defines their directory where the MR data was stored on disk.\n",
+ "mr_series_uid = df.at[df.Modality.eq(\"MR\").idxmax(), \"Series UID\"]\n",
+ "mr_dir = os.path.join(dicom_data_dir, mr_series_uid)\n",
+ "\n",
+ "# Read the DICOM MR series' objects and reconstruct them into a 3D ITK image.\n",
+ "# The itk.F option is added to store the image in memory using floating-point precision pixels (useful if you will filter the image or use it with MONAI).\n",
+ "# For more info on imread, see https://itkpythonpackage.readthedocs.io/en/master/Quick_start_guide.html.\n",
+ "mr_image = itk.imread(mr_dir, itk.F)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "id": "JdT44AzPemJP",
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "e1b2fb77-1cf1-4302-a641-539363384979"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stderr",
+ "text": [
+ "WARNING:pydicom_seg.reader:DICOM-SEG does not specify \"(0062, 0013) SegmentsOverlap\", assuming UNDEFINED and checking pixels\n"
+ ]
+ }
],
- "text/plain": [
- ""
+ "source": [
+ "# The series_uid defines where the RTSTRUCT was stored on disk. It is stored in a single file.\n",
+ "seg_series_uid = df.at[df.Modality.eq(\"SEG\").idxmax(), \"Series UID\"]\n",
+ "seg_dir = os.path.join(dicom_data_dir, seg_series_uid)\n",
+ "seg_file = glob.glob(os.path.join(seg_dir, \"*.dcm\"))[0]\n",
+ "\n",
+ "# Read the DICOM SEG object using pydicom and pydicom_seg.\n",
+ "seg_dicom = pydicom.dcmread(seg_file)\n",
+ "seg_reader = pydicom_seg.MultiClassReader()\n",
+ "seg_obj = seg_reader.read(seg_dicom)\n",
+ "\n",
+ "# Convert the DICOM SEG object into an itk image, with correct voxel origin, spacing, and directions in physical space.\n",
+ "seg_image = itk.GetImageFromArray(seg_obj.data.astype(np.float32))\n",
+ "seg_image.CopyInformation(mr_image)"
]
- },
- "metadata": {},
- "output_type": "display_data"
},
{
- "data": {
- "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
- "text/plain": [
- ""
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "yGV9j8TbemJP",
+ "tags": []
+ },
+ "source": [
+ "# 4. MONAI Zoo Basics"
]
- },
- "metadata": {},
- "output_type": "display_data"
},
{
- "data": {
- "text/html": [
- ""
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "id": "diJ1EeQQemJQ",
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "485d99d2-fca3-4f36-93d1-a9c1ed56dba1"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-09-24 17:23:39,121 - INFO - --- input summary of monai.bundle.scripts.download ---\n",
+ "2024-09-24 17:23:39,123 - INFO - > name: 'prostate_mri_anatomy'\n",
+ "2024-09-24 17:23:39,125 - INFO - > version: '0.3.1'\n",
+ "2024-09-24 17:23:39,126 - INFO - > bundle_dir: '/content/models'\n",
+ "2024-09-24 17:23:39,128 - INFO - > source: 'monaihosting'\n",
+ "2024-09-24 17:23:39,131 - INFO - > remove_prefix: 'monai_'\n",
+ "2024-09-24 17:23:39,133 - INFO - > progress: True\n",
+ "2024-09-24 17:23:39,137 - INFO - ---\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "name": "stderr",
+ "text": [
+ "prostate_mri_anatomy_v0.3.1.zip: 269MB [00:07, 39.5MB/s] "
+ ]
+ },
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-09-24 17:23:46,293 - INFO - Downloaded: /content/models/prostate_mri_anatomy_v0.3.1.zip\n",
+ "2024-09-24 17:23:46,294 - INFO - Expected md5 is None, skip md5 check for file /content/models/prostate_mri_anatomy_v0.3.1.zip.\n",
+ "2024-09-24 17:23:46,296 - INFO - Writing into directory: /content/models.\n"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "name": "stderr",
+ "text": [
+ "\n"
+ ]
+ }
],
- "text/plain": [
- ""
+ "source": [
+ "model_name = \"prostate_mri_anatomy\"\n",
+ "model_version = \"0.3.1\"\n",
+ "zoo_dir = os.path.abspath(\"./models\")\n",
+ "\n",
+ "download(name=model_name, version=model_version, bundle_dir=zoo_dir)"
]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "# View the image with results overlaid in an interactive 2D slice viewer.\n",
- "viewer_b = view(image=mr_image_prep, label_image=result_image_resampled)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "id": "mYRlAbKusf-L",
- "tags": []
- },
- "outputs": [],
- "source": [
- "viewer_b.set_image_color_map(\"Grayscale\")\n",
- "viewer_b.set_label_image_blend(0.5)\n",
- "viewer_b.set_image_color_range([100, 500])\n",
- "viewer_b.set_view_mode(\"ZPlane\")\n",
- "viewer_b.set_ui_collapsed(False)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "id": "2wHOPVkWemJS",
- "tags": []
- },
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- "
\n",
- " \n",
- " "
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "id": "xcj8cA_ZemJQ"
+ },
+ "outputs": [],
+ "source": [
+ "# This model includes scripts that must be run on new data.\n",
+ "# We could import those scripts into this python notebook, but they\n",
+ "# bring in additional dependencies. Instead, we provide the following\n",
+ "# more compact and compatible implementation. Otherwise, you can\n",
+ "# include the model's script directory by uncommenting these lines and\n",
+ "# installing their dependencies and doing appropriate data conversions.\n",
+ "# scripts_dir = os.path.join(zoo_dir, model_name, \"scripts\")\n",
+ "# sys.path.insert(1, scripts_dir)\n",
+ "\n",
+ "\n",
+ "# Compact alternative implementation of this model's specific cropping step.\n",
+ "# Ideally this would have been accomplished using MONAI's transforms\n",
+ "# for data pre-processing / augmentation instead of using a separate\n",
+ "# function.\n",
+ "def prostate_crop(img):\n",
+ " boundary = [int(crop_size * 0.2) for crop_size in img.GetLargestPossibleRegion().GetSize()]\n",
+ " new_image = itk.CropImageFilter(Input=img, BoundaryCropSize=boundary)\n",
+ " return new_image\n",
+ "\n",
+ "\n",
+ "mr_image_prep = prostate_crop(mr_image)\n",
+ "seg_image_prep = prostate_crop(seg_image)\n",
+ "\n",
+ "# Running a MONAI model on new data requires that data to be saved on\n",
+ "# local disk.\n",
+ "itk.imwrite(mr_image_prep, mr_dir + \".nii.gz\")\n",
+ "itk.imwrite(seg_image_prep, seg_dir + \".nii.gz\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "id": "YhDJqRkHemJQ"
+ },
+ "outputs": [],
+ "source": [
+ "# The model's config file dynamically generates the functions needed to process new data.\n",
+ "\n",
+ "# Define our local system and filesystem.\n",
+ "output_dir = os.path.abspath(\"./monai_results\")\n",
+ "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
+ "\n",
+ "# Parse the variables in the config file.\n",
+ "model_config_file = os.path.join(zoo_dir, model_name, \"configs\", \"inference.json\")\n",
+ "model_config = ConfigParser()\n",
+ "model_config.read_config(model_config_file)\n",
+ "\n",
+ "# Update the confir variables to match our filesystem.\n",
+ "model_config[\"bundle_root\"] = zoo_dir\n",
+ "model_config[\"output_dir\"] = output_dir\n",
+ "\n",
+ "# Identify which version of the model we want to load (each version is a\n",
+ "# \"checkpoint\"). For most models, the \"best\" checkpoint is called \"model.pt\"\n",
+ "# and it is stored in the models subdir.\n",
+ "checkpoint = os.path.join(zoo_dir, model_name, \"models\", \"model.pt\")\n",
+ "\n",
+ "# Ask the config file to generate the functions needed to process new data.\n",
+ "# These functions are adapted to our system by the config variables we\n",
+ "# modified above. The order of first defining variables and then creating the\n",
+ "# functions is critical.\n",
+ "preprocessing = model_config.get_parsed_content(\"preprocessing\")\n",
+ "\n",
+ "model = model_config.get_parsed_content(\"network\").to(device)\n",
+ "\n",
+ "inferer = model_config.get_parsed_content(\"inferer\")\n",
+ "\n",
+ "postprocessing = model_config.get_parsed_content(\"postprocessing\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "id": "CqoHulOhemJR",
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "081925ff-be7a-4619-f4e5-734a42a15dbb"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stderr",
+ "text": [
+ "This DataLoader will create 4 worker processes in total. Our suggested max number of worker in current system is 2, which is smaller than what this DataLoader is going to create. Please be aware that excessive worker creation might get DataLoader running slow or even freeze, lower the worker number to avoid potential slowness/freeze if necessary.\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Point the dataloader to the downloaded and converted TCIA data.\n",
+ "datalist = [mr_dir + \".nii.gz\"]\n",
+ "model_config[\"datalist\"] = datalist\n",
+ "dataloader = model_config.get_parsed_content(\"dataloader\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zX0UIVt9bvwJ"
+ },
+ "source": [
+ "# 5. Visualize the data with itkWidgets\n",
+ "\n",
+ "[itkWidgets documentation](https://itkwidgets.readthedocs.io/en/latest/?badge=latest) provides a summary and illustrations of itkWidgets for a wide variety of scientific data visualization use cases."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "RF4LqDs-emJR",
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "view(image=mr_image_prep, label_image=seg_image_prep)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ ""
+ ],
+ "metadata": {
+ "id": "i8Cazs1CG2nf"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8FmGXwzXemJR",
+ "tags": []
+ },
+ "source": [
+ "# 6. MONAI Model Inference"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {
+ "id": "kbGZrHfWemJR",
+ "tags": [],
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "61880710-6836-4561-bd9f-81df472239e3"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stderr",
+ "text": [
+ "You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-09-24 17:25:50,204 INFO image_writer.py:197 - writing: /content/monai_results/1.3.6.1.4.1.14519.5.2.1.7311.5101.206828891270520544417996275680/1.3.6.1.4.1.14519.5.2.1.7311.5101.206828891270520544417996275680_trans.nii.gz\n"
+ ]
+ }
],
- "text/plain": [
- ""
+ "source": [
+ "model.load_state_dict(torch.load(checkpoint, map_location=device))\n",
+ "model.eval()\n",
+ "results = []\n",
+ "with torch.no_grad():\n",
+ " for d in dataloader:\n",
+ " images = d[\"image\"].to(device)\n",
+ " d[\"pred\"] = inferer(images, network=model)\n",
+ " results.append([postprocessing(i) for i in decollate_batch(d)])"
]
- },
- "metadata": {},
- "output_type": "display_data"
},
{
- "data": {
- "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
- "text/plain": [
- ""
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HrMqViotemJS"
+ },
+ "source": [
+ "# 7. Visualizing and Comparing Model and Expert Results"
]
- },
- "metadata": {},
- "output_type": "display_data"
},
{
- "data": {
- "text/html": [
- ""
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {
+ "id": "cjLs9PjDemJS"
+ },
+ "outputs": [],
+ "source": [
+ "# Read the result image that was written into the output_dir.\n",
+ "result_image = itk.imread(\n",
+ " os.path.join(output_dir, os.path.split(mr_dir)[1], os.path.split(mr_dir)[1] + \"_trans.nii.gz\")\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {
+ "id": "xkh3TtD9emJS"
+ },
+ "outputs": [],
+ "source": [
+ "# Various manipulations were done to the input image before it is fed to the model\n",
+ "# for inference. As a result, the result image may not be in the same\n",
+ "# spacing, orientation, etc as the original input data. So, we resample the results\n",
+ "# image to match the physical properties of the original input data.\n",
+ "interpolator = itk.NearestNeighborInterpolateImageFunction.New(seg_image)\n",
+ "result_image_resampled = itk.resample_image_filter(\n",
+ " Input=result_image, Interpolator=interpolator, reference_image=seg_image_prep, use_reference_image=True\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "9bmgCBL9emJS",
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# View the image with results overlaid in an interactive 2D slice viewer.\n",
+ "viewer_b = view(image=mr_image_prep, label_image=result_image_resampled)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ ""
],
- "text/plain": [
- ""
+ "metadata": {
+ "id": "dftNenXyHHfZ"
+ }
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {
+ "id": "mYRlAbKusf-L",
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "viewer_b.set_image_color_map(\"Grayscale\")\n",
+ "viewer_b.set_label_image_blend(0.5)\n",
+ "viewer_b.set_image_color_range([100, 500])\n",
+ "viewer_b.set_view_mode(\"ZPlane\")\n",
+ "viewer_b.set_ui_collapsed(False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "2wHOPVkWemJS",
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "result_array = itk.GetArrayViewFromImage(result_image_resampled)\n",
+ "expert_array = itk.GetArrayViewFromImage(seg_image_prep)\n",
+ "\n",
+ "# Note that the data in the ProstateX repo uses different labels than the data used to\n",
+ "# build the model. For example, the prostate is label 1 in the model and label 2\n",
+ "# in the ProstateX data.\n",
+ "# The following creates a label image where\n",
+ "# 1 = ideal prostate, but model called non-prostate (red)\n",
+ "# 2 = model called prostate, but ideal called non-prostate (purple)\n",
+ "# 3 = modeal and ideal agreed (green)\n",
+ "compare_model_expert = np.where(result_array != 1, 0, 2) + np.where(expert_array != 2, 0, 1)\n",
+ "compare_image = itk.GetImageFromArray(compare_model_expert.astype(np.float32))\n",
+ "compare_image.CopyInformation(seg_image_prep)\n",
+ "\n",
+ "viewer_c = view(image=mr_image_prep, label_image=compare_image)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ ""
+ ],
+ "metadata": {
+ "id": "m76Ue6tBHLgU"
+ }
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {
+ "id": "diqDQW4PemJS"
+ },
+ "outputs": [],
+ "source": [
+ "# Switch to an interactive slice view so that labels are more easily seen.\n",
+ "viewer_c.set_label_image_blend(0.6)\n",
+ "viewer_c.set_image_color_map(\"Grayscale\")\n",
+ "viewer_c.set_view_mode(\"ZPlane\")\n",
+ "viewer_c.set_image_color_range([100, 500])\n",
+ "viewer_c.set_ui_collapsed(False)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DYXsNGcY93B8",
+ "tags": []
+ },
+ "source": [
+ "# Acknowledgements\n",
+ "\n",
+ "TCIA is funded by the [Cancer Imaging Program (CIP)](https://imaging.cancer.gov/), a part of the United States [National Cancer Institute (NCI)](https://www.cancer.gov/), and is managed by the [Frederick National Laboratory for Cancer Research (FNLCR)](https://frederick.cancer.gov/).\n",
+ "\n",
+ "If you leverage this notebook or any TCIA datasets in your work, please be sure to comply with the [TCIA Data Usage Policy](https://wiki.cancerimagingarchive.net/x/c4hF). In particular, make sure to cite the DOI(s) for the specific TCIA datasets you used in addition to TCIA citation provided below!\n",
+ "\n",
+ "This notebook was created by [Stephen Aylward (Kitware)](https://www.kitware.com/stephen-aylward/), [Justin Kirby (Frederick National Laboratory for Cancer Research)](https://www.linkedin.com/in/justinkirby82/), [Brianna Major (Kitware)](https://www.kitware.com/brianna-major/), and [Matt McCormick (Kitware)](https://www.kitware.com/matt-mccormick/). The creation of this notebook was funded, in part, by NIBIB and NIGMS R01EB021396,\n",
+ "NIBIB R01EB014955, NCI R01CA220681, and NINDS R42NS086295.\n",
+ "\n",
+ "If you have any questions, suggestions, or issues with itkWidgets, please post them on the [itkwidget issue tracker](https://github.com/InsightSoftwareConsortium/itkwidgets/issues) or feel free to email us at kitware@kitware.com.\n",
+ "\n",
+ "## Dataset Citation\n",
+ "The data used in this notebook was part of the SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection:\n",
+ "\n",
+ "Geert Litjens, Oscar Debats, Jelle Barentsz, Nico Karssemeijer, and Henkjan Huisman. \"ProstateX Challenge data\", The Cancer Imaging Archive (2017). DOI: [10.7937/K9TCIA.2017.MURS5CL](https://doi.org/10.7937/K9TCIA.2017.MURS5CL)\n",
+ "\n",
+ "## Publication Citation\n",
+ "The data used in this notebook was part of the SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection:\n",
+ "\n",
+ "Litjens G, Debats O, Barentsz J, Karssemeijer N, Huisman H. \"Computer-aided detection of prostate cancer in MRI\", IEEE Transactions on Medical Imaging 2014;33:1083-1092. DOI: [10.1109/TMI.2014.2303821](https://doi.org/10.1109/TMI.2014.2303821)\n",
+ "\n",
+ "## TCIA Citation\n",
+ "\n",
+ "Clark, K., Vendt, B., Smith, K., Freymann, J., Kirby, J., Koppel, P., Moore, S., Phillips, S., Maffitt, D., Pringle, M., Tarbox, L., & Prior, F. (2013). The Cancer Imaging Archive (TCIA): Maintaining and Operating a Public Information Repository. Journal of Digital Imaging, 26(6), 1045–1057. https://doi.org/10.1007/s10278-013-9622-7"
]
- },
- "metadata": {},
- "output_type": "display_data"
}
- ],
- "source": [
- "result_array = itk.GetArrayViewFromImage(result_image_resampled)\n",
- "expert_array = itk.GetArrayViewFromImage(seg_image_prep)\n",
- "\n",
- "# Note that the data in the ProstateX repo uses different labels than the data used to\n",
- "# build the model. For example, the prostate is label 1 in the model and label 2\n",
- "# in the ProstateX data.\n",
- "# The following creates a label image where\n",
- "# 1 = ideal prostate, but model called non-prostate (red)\n",
- "# 2 = model called prostate, but ideal called non-prostate (purple)\n",
- "# 3 = modeal and ideal agreed (green)\n",
- "compare_model_expert = np.where(result_array != 1, 0, 2) + np.where(expert_array != 2, 0, 1)\n",
- "compare_image = itk.GetImageFromArray(compare_model_expert.astype(np.float32))\n",
- "compare_image.CopyInformation(seg_image_prep)\n",
- "\n",
- "viewer_c = view(image=mr_image_prep, label_image=compare_image)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "id": "diqDQW4PemJS"
- },
- "outputs": [],
- "source": [
- "# Switch to an interactive slice view so that labels are more easily seen.\n",
- "viewer_c.set_label_image_blend(0.6)\n",
- "viewer_c.set_image_color_map(\"Grayscale\")\n",
- "viewer_c.set_view_mode(\"ZPlane\")\n",
- "viewer_c.set_image_color_range([100, 500])\n",
- "viewer_c.set_ui_collapsed(False)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "DYXsNGcY93B8",
- "tags": []
- },
- "source": [
- "# Acknowledgements\n",
- "\n",
- "TCIA is funded by the [Cancer Imaging Program (CIP)](https://imaging.cancer.gov/), a part of the United States [National Cancer Institute (NCI)](https://www.cancer.gov/), and is managed by the [Frederick National Laboratory for Cancer Research (FNLCR)](https://frederick.cancer.gov/).\n",
- "\n",
- "If you leverage this notebook or any TCIA datasets in your work, please be sure to comply with the [TCIA Data Usage Policy](https://wiki.cancerimagingarchive.net/x/c4hF). In particular, make sure to cite the DOI(s) for the specific TCIA datasets you used in addition to TCIA citation provided below!\n",
- "\n",
- "This notebook was created by [Stephen Aylward (Kitware)](https://www.kitware.com/stephen-aylward/), [Justin Kirby (Frederick National Laboratory for Cancer Research)](https://www.linkedin.com/in/justinkirby82/), [Brianna Major (Kitware)](https://www.kitware.com/brianna-major/), and [Matt McCormick (Kitware)](https://www.kitware.com/matt-mccormick/). The creation of this notebook was funded, in part, by NIBIB and NIGMS R01EB021396,\n",
- "NIBIB R01EB014955, NCI R01CA220681, and NINDS R42NS086295.\n",
- "\n",
- "If you have any questions, suggestions, or issues with itkWidgets, please post them on the [itkwidget issue tracker](https://github.com/InsightSoftwareConsortium/itkwidgets/issues) or feel free to email us at kitware@kitware.com.\n",
- "\n",
- "## Dataset Citation\n",
- "The data used in this notebook was part of the SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection:\n",
- "\n",
- "Geert Litjens, Oscar Debats, Jelle Barentsz, Nico Karssemeijer, and Henkjan Huisman. \"ProstateX Challenge data\", The Cancer Imaging Archive (2017). DOI: [10.7937/K9TCIA.2017.MURS5CL](https://doi.org/10.7937/K9TCIA.2017.MURS5CL)\n",
- "\n",
- "## Publication Citation\n",
- "The data used in this notebook was part of the SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection:\n",
- "\n",
- "Litjens G, Debats O, Barentsz J, Karssemeijer N, Huisman H. \"Computer-aided detection of prostate cancer in MRI\", IEEE Transactions on Medical Imaging 2014;33:1083-1092. DOI: [10.1109/TMI.2014.2303821](https://doi.org/10.1109/TMI.2014.2303821)\n",
- "\n",
- "## TCIA Citation\n",
- "\n",
- "Clark, K., Vendt, B., Smith, K., Freymann, J., Kirby, J., Koppel, P., Moore, S., Phillips, S., Maffitt, D., Pringle, M., Tarbox, L., & Prior, F. (2013). The Cancer Imaging Archive (TCIA): Maintaining and Operating a Public Information Repository. Journal of Digital Imaging, 26(6), 1045–1057. https://doi.org/10.1007/s10278-013-9622-7"
- ]
- }
- ],
- "metadata": {
- "colab": {
- "provenance": []
- },
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
+ ],
+ "metadata": {
+ "colab": {
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.12"
+ }
},
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
\ No newline at end of file
From 6e36c647472b96e1bf01ead6a2f37550e9b4176a Mon Sep 17 00:00:00 2001
From: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
Date: Thu, 3 Oct 2024 09:14:04 -0400
Subject: [PATCH 2/7] Revert "Fixed dependency issues with itkwidgets"
This reverts commit 00f3362af5df6e279e5978b6117517c34adf93cd.
---
...PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb | 1530 ++++++++---------
1 file changed, 738 insertions(+), 792 deletions(-)
diff --git a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
index 15d89d16b1..f1dc6f0e5f 100644
--- a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
+++ b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
@@ -1,825 +1,771 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "Yxvh7SsKbvv_"
- },
- "source": [
- "Copyright (c) MONAI Consortium \n",
- "Licensed under the Apache License, Version 2.0 (the \"License\"); \n",
- "you may not use this file except in compliance with the License. \n",
- "You may obtain a copy of the License at \n",
- " http://www.apache.org/licenses/LICENSE-2.0 \n",
- "Unless required by applicable law or agreed to in writing, software \n",
- "distributed under the License is distributed on an \"AS IS\" BASIS, \n",
- "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n",
- "See the License for the specific language governing permissions and \n",
- "limitations under the License.\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "M565w1lqtd4M"
- },
- "source": [
- "You can download and run this notebook locally, or you can run it for free in a cloud environment using Colab or Sagemaker Studio Lab:\n",
- "\n",
- "[](https://colab.research.google.com/github/Project-MONAI/tutorials/blob/main/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb)\n",
- "\n",
- "[](https://studiolab.sagemaker.aws/import/github.com/Project-MONAI/tutorials/blob/main/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "N92pMd7ig0ZS",
- "jp-MarkdownHeadingCollapsed": true,
- "tags": []
- },
- "source": [
- "# Summary\n",
- "This notebook demonstrates downloading the [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model from MONAI's Model Zoo and applying it to segment a subset of data from the [SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection](https://doi.org/10.7937/K9TCIA.2017.MURS5CL10.7937/TCIA.X0H0-1706) on [The Cancer Imaging Archive (TCIA)](https://www.cancerimagingarchive.net/). The resulting data are then visualized using [itkWidgets].(https://github.com/InsightSoftwareConsortium/itkwidgets)\n",
- "\n",
- "Features demonstrated include:\n",
- "* Using a python script to download and load a model from MONAI's Model Zoo into python.\n",
- "* Downloading and preparing data from TCIA for processing using that model.\n",
- "* Applying the model to the TCIA data.\n",
- "* Visually comparing model results with expert segmentation results available on TCIA.\n",
- "\n",
- "# Background\n",
- "[MONAI's Model Zoo](https://monai.io/model-zoo.html) provides pre-trained AI deep learning models that can be downloaded and used to process new data or as a starting point for transfer learning. The [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model was trained with the UNet architecture and is used for 3D volumetric segmentation of the anatomical prostate zones on T2w MRI images. The segmentation of the anatomical regions is formulated as a voxel-wise classification. Each voxel is classified as either central gland (1), peripheral zone (2), or background (0). The model is optimized using a gradient descent method that minimizes the focal soft-dice loss between the predicted mask and the actual segmentation. The model was trained in the prostate158 training data, which is available at https://doi.org/10.5281/zenodo.6481141. Only T2w images were used for this task.\n",
- "\n",
- "[The Cancer Imaging Archive (TCIA)](https://www.cancerimagingarchive.net/) is a public service funded by the National Cancer Institute that addresses this challenge by providing hosting and de-identification services to take major burdens of data sharing off researchers. Its rich collection of clinical data and annotations is particularly powerful as a community resource when it is paired with interactive code systems, such as Jupyter systems.\n",
- "\n",
- "[itkWidgets](https://github.com/InsightSoftwareConsortium/itkwidgets) allows researchers to visualize images, point sets, and 3D geometry in Jupyter systems (Jupyer Notebooks, JupyterLab, AWS SageMaker, and Google Colab). Despite its name, itkWidgets does not require the use of ITK. It can directly visualize numpy arrays, torch tensors, DASK arrays, VTK polydata, and a multitude of other python data structures."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "nj6P7YCmll4S",
- "tags": []
- },
- "source": [
- "# Outline\n",
- "\n",
- "1. Setup\n",
- "2. Download data from TCIA\n",
- "3. Prepare the data with ITK\n",
- "4. Setup itkWidgets\n",
- "5. MONAI Zoo Basics\n",
- "6. MONAI Model Inference\n",
- "7. Visualizing and Comparing Model and Expert Results"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "8FgizAMWemJM"
- },
- "source": [
- "# 1. Setup\n",
- "\n",
- "These are the initial steps for running notebooks within various Jupyter environments."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "As3EplXrbvwF"
- },
- "source": [
- "## Setup environment"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "id": "K3DOvHnXsf-I",
- "tags": [],
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "outputId": "33af56ea-940d-4a3d-fd8e-4b9370a5954d"
- },
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m80.2/80.2 MB\u001b[0m \u001b[31m50.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.7/67.7 MB\u001b[0m \u001b[31m52.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m28.0/28.0 MB\u001b[0m \u001b[31m101.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m57.0/57.0 MB\u001b[0m \u001b[31m44.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m28.4/28.4 MB\u001b[0m \u001b[31m97.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m15.8/15.8 MB\u001b[0m \u001b[31m91.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m28.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m28.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.4/52.4 MB\u001b[0m \u001b[31m58.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.0/4.0 MB\u001b[0m \u001b[31m41.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
- " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m71.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m8.6/8.6 MB\u001b[0m \u001b[31m97.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.8/3.8 MB\u001b[0m \u001b[31m75.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.1/6.1 MB\u001b[0m \u001b[31m92.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.0/6.0 MB\u001b[0m \u001b[31m70.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
- "\u001b[?25h Building wheel for elfinder-client (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
- " Building wheel for asciitree (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
- "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
- "albumentations 1.4.15 requires pydantic>=2.7.0, but you have pydantic 1.10.18 which is incompatible.\u001b[0m\u001b[31m\n",
- "\u001b[0m"
- ]
- }
- ],
- "source": [
- "# Install itk for DICOM I/O and for reading DICOM into an itkImage\n",
- "# that manages all DICOM field values, include acquistion details\n",
- "# such as voxel image, image orientation, and image directions,\n",
- "# which are critical to image processing and display.\n",
- "\n",
- "import sys\n",
- "\n",
- "# Upgrade pip, just in case.\n",
- "!{sys.executable} -m pip install --upgrade -q pip\n",
- "\n",
- "# installations required for monai\n",
- "!{sys.executable} -m pip install -q \"monai[nibabel,itk,tqdm,pandas,skimage]\"\n",
- "!{sys.executable} -m pip install -q opencv-python-headless\n",
- "\n",
- "# These are the libraries used to read DICOM Seg objects.\n",
- "!{sys.executable} -m pip install -q pydicom==2.4.4 pydicom-seg\n",
- "\n",
- "# Install the dependency manually to avoid installing opencv-python.\n",
- "!{sys.executable} -m pip install -q plotly bs4 ipywidgets unidecode jsonschema\n",
- "!{sys.executable} -m pip install -q --no-deps rt-utils\n",
- "\n",
- "# Install tcia_utils to download the datasets.\n",
- "!{sys.executable} -m pip install --upgrade -q --no-deps tcia_utils\n",
- "\n",
- "# This is the installation required for itkWidgets.\n",
- "!{sys.executable} -m pip install --upgrade --pre -q \"itkwidgets[all]\" imjoy_elfinder\n",
- "\n",
- "# TEMPORARY WORKAROUND TO RESOLVE: https://github.com/kirbyju/TCIA_Notebooks/issues/30\n",
- "!pip uninstall -y zarr ngff_zarr\n",
- "!pip install zarr ngff_zarr"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "oYxvN-rebvwG"
- },
- "source": [
- "## Setup imports\n",
- "\n",
- "### Setup the im-joy-jupyter-extension for itkWidgets\n",
- "On many systems you must manually install the imjoy-jupyter-extension for itkWidgets! If you do not see a blue 'ImJoy' icon on the menu bar in this notebook:\n",
- "\n",
- "* Google CoLab: The following does not apply to Google CoLab - it will not show an ImJoy and all should work without modification.\n",
- "* Enable Extensions: Many Jupyter Lab systems disable jupyter extensions by default, and they must be enabled for this notebook to work. Typically this is accomplished using the Jupyter interface to select the extension manager (left-hand side, icon that looks like a piece of a puzzle) and select the Enable button if it appears.\n",
- "* Install imjoy extension: In the extension manager, search for 'imjoy' and install the 'imjoy-jupyter-extension'. The installation can take several minutes. It may also prompt you to rebuild, save, and reload your jupyter environment as part of this process. In the end, you should see a blue 'ImJoy' icon on the left side of the menu bar in this notebook."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "id": "tF8-MqoN6YT5",
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "outputId": "821ac4d2-d064-40c5-dea8-710e51afd93e"
- },
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "MONAI version: 1.3.2\n",
- "Numpy version: 1.26.4\n",
- "Pytorch version: 2.4.1+cu121\n",
- "MONAI flags: HAS_EXT = False, USE_COMPILED = False, USE_META_DICT = False\n",
- "MONAI rev id: 59a7211070538586369afd4a01eca0a7fe2e742e\n",
- "MONAI __file__: /usr/local/lib/python3.10/dist-packages/monai/__init__.py\n",
- "\n",
- "Optional dependencies:\n",
- "Pytorch Ignite version: NOT INSTALLED or UNKNOWN VERSION.\n",
- "ITK version: 5.4.0\n",
- "Nibabel version: 5.2.1\n",
- "scikit-image version: 0.24.0\n",
- "scipy version: 1.13.1\n",
- "Pillow version: 10.4.0\n",
- "Tensorboard version: 2.17.0\n",
- "gdown version: 5.2.0\n",
- "TorchVision version: 0.19.1+cu121\n",
- "tqdm version: 4.66.5\n",
- "lmdb version: NOT INSTALLED or UNKNOWN VERSION.\n",
- "psutil version: 5.9.5\n",
- "pandas version: 2.1.4\n",
- "einops version: 0.8.0\n",
- "transformers version: 4.44.2\n",
- "mlflow version: NOT INSTALLED or UNKNOWN VERSION.\n",
- "pynrrd version: NOT INSTALLED or UNKNOWN VERSION.\n",
- "clearml version: NOT INSTALLED or UNKNOWN VERSION.\n",
- "\n",
- "For details about installing the optional dependencies, please visit:\n",
- " https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies\n",
- "\n"
- ]
- }
- ],
- "source": [
- "import glob\n",
- "import os\n",
- "\n",
- "# Numpy for numpy.arrays\n",
- "import numpy as np\n",
- "\n",
- "# Include ITK for DICOM reading.\n",
- "import itk\n",
- "\n",
- "# Include pydicom_seg for DICOM SEG objects\n",
- "import pydicom\n",
- "import pydicom_seg\n",
- "\n",
- "# for downloading data from TCIA\n",
- "from tcia_utils import nbia\n",
- "\n",
- "# This is the most common import command for itkWidgets.\n",
- "# The view() function opens an interactive viewer for 2D and 3D\n",
- "# data in a variety of formats.\n",
- "from itkwidgets import view\n",
- "\n",
- "# imports for monai\n",
- "import monai\n",
- "import cv2\n",
- "import torch\n",
- "from monai.data import decollate_batch\n",
- "from monai.bundle import ConfigParser, download\n",
- "\n",
- "from monai.config import print_config\n",
- "\n",
- "print_config()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "Ub0GzFRXemJN"
- },
- "outputs": [],
- "source": [
- "# If running on SageMaker or Studio Lab, install essential packages and extensions.\n",
- "if \"studio-lab-user\" in os.getcwd():\n",
- " print(\"Upgrading dependencies\")\n",
- " !conda install --yes -q --prefix {sys.prefix} -c conda-forge opencv nodejs"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "di4lxyikemJN",
- "outputId": "408c7a4d-492f-43cf-cb38-afa92d1f53d3"
- },
- "source": [
- "# 2. Download the data from TCIA\n",
- "\n",
- "[Browsing Collections](https://www.cancerimagingarchive.net/collections) and viewing [Analysis Results](https://www.cancerimagingarchive.net/tcia-analysis-results/) of datasets on TCIA are the easiest ways to become familiar with what is available. These pages will help you quickly identify datasets of interest, find valuable, supporting data that are not available via TCIA's APIs (e.g. clinical spreadsheets, non-DICOM segmentation data), and answer the most common questions you might have about the datasets. In this tutorial we'll be working with the [SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection](https://doi.org/10.7937/K9TCIA.2017.MURS5CL), but if you browse the previously mentioned links you will find that TCIA has many other prostate datasets which could be used with the [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model.\n",
- "\n",
- "We will utilize the [tcia_utils](https://pypi.org/project/tcia-utils/) package to simplify downloading the data from TCIA. If you are new to accessing TCIA via notebooks, you can find additional tutorials on querying and downloading data at https://github.com/kirbyju/TCIA_Notebooks."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "id": "urhgDgvb39pS"
- },
- "outputs": [],
- "source": [
- "# Download a \"Shared Cart\" containing 6 scans from PROSTATEx\n",
- "# that has been previously created via the TCIA website\n",
- "# (https://nbia.cancerimagingarchive.net).\n",
- "cart_name = \"nbia-17571668146714049\"\n",
- "\n",
- "# retrieve cart metadata\n",
- "cart_data = nbia.getSharedCart(cart_name)\n",
- "\n",
- "# download the series_uids list and return dataframe of metadata\n",
- "df = nbia.downloadSeries(cart_data, format=\"df\")\n",
- "\n",
- "# display dataframe\n",
- "# display(df)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "MGPw6j3hbvwI"
- },
- "source": [
- "# 3. Prepare the data with itk\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "id": "7wR4HJu-emJP"
- },
- "outputs": [],
- "source": [
- "dicom_data_dir = \"tciaDownload\"\n",
- "\n",
- "# The series_uid defines their directory where the MR data was stored on disk.\n",
- "mr_series_uid = df.at[df.Modality.eq(\"MR\").idxmax(), \"Series UID\"]\n",
- "mr_dir = os.path.join(dicom_data_dir, mr_series_uid)\n",
- "\n",
- "# Read the DICOM MR series' objects and reconstruct them into a 3D ITK image.\n",
- "# The itk.F option is added to store the image in memory using floating-point precision pixels (useful if you will filter the image or use it with MONAI).\n",
- "# For more info on imread, see https://itkpythonpackage.readthedocs.io/en/master/Quick_start_guide.html.\n",
- "mr_image = itk.imread(mr_dir, itk.F)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "id": "JdT44AzPemJP",
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "outputId": "e1b2fb77-1cf1-4302-a641-539363384979"
- },
- "outputs": [
- {
- "output_type": "stream",
- "name": "stderr",
- "text": [
- "WARNING:pydicom_seg.reader:DICOM-SEG does not specify \"(0062, 0013) SegmentsOverlap\", assuming UNDEFINED and checking pixels\n"
- ]
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Yxvh7SsKbvv_"
+ },
+ "source": [
+ "Copyright (c) MONAI Consortium \n",
+ "Licensed under the Apache License, Version 2.0 (the \"License\"); \n",
+ "you may not use this file except in compliance with the License. \n",
+ "You may obtain a copy of the License at \n",
+ " http://www.apache.org/licenses/LICENSE-2.0 \n",
+ "Unless required by applicable law or agreed to in writing, software \n",
+ "distributed under the License is distributed on an \"AS IS\" BASIS, \n",
+ "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n",
+ "See the License for the specific language governing permissions and \n",
+ "limitations under the License.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "M565w1lqtd4M"
+ },
+ "source": [
+ "You can download and run this notebook locally, or you can run it for free in a cloud environment using Colab or Sagemaker Studio Lab:\n",
+ "\n",
+ "[](https://colab.research.google.com/github/Project-MONAI/tutorials/blob/main/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb)\n",
+ "\n",
+ "[](https://studiolab.sagemaker.aws/import/github.com/Project-MONAI/tutorials/blob/main/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "N92pMd7ig0ZS",
+ "jp-MarkdownHeadingCollapsed": true,
+ "tags": []
+ },
+ "source": [
+ "# Summary\n",
+ "This notebook demonstrates downloading the [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model from MONAI's Model Zoo and applying it to segment a subset of data from the [SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection](https://doi.org/10.7937/K9TCIA.2017.MURS5CL10.7937/TCIA.X0H0-1706) on [The Cancer Imaging Archive (TCIA)](https://www.cancerimagingarchive.net/). The resulting data are then visualized using [itkWidgets].(https://github.com/InsightSoftwareConsortium/itkwidgets)\n",
+ "\n",
+ "Features demonstrated include:\n",
+ "* Using a python script to download and load a model from MONAI's Model Zoo into python.\n",
+ "* Downloading and preparing data from TCIA for processing using that model.\n",
+ "* Applying the model to the TCIA data.\n",
+ "* Visually comparing model results with expert segmentation results available on TCIA.\n",
+ "\n",
+ "# Background\n",
+ "[MONAI's Model Zoo](https://monai.io/model-zoo.html) provides pre-trained AI deep learning models that can be downloaded and used to process new data or as a starting point for transfer learning. The [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model was trained with the UNet architecture and is used for 3D volumetric segmentation of the anatomical prostate zones on T2w MRI images. The segmentation of the anatomical regions is formulated as a voxel-wise classification. Each voxel is classified as either central gland (1), peripheral zone (2), or background (0). The model is optimized using a gradient descent method that minimizes the focal soft-dice loss between the predicted mask and the actual segmentation. The model was trained in the prostate158 training data, which is available at https://doi.org/10.5281/zenodo.6481141. Only T2w images were used for this task.\n",
+ "\n",
+ "[The Cancer Imaging Archive (TCIA)](https://www.cancerimagingarchive.net/) is a public service funded by the National Cancer Institute that addresses this challenge by providing hosting and de-identification services to take major burdens of data sharing off researchers. Its rich collection of clinical data and annotations is particularly powerful as a community resource when it is paired with interactive code systems, such as Jupyter systems.\n",
+ "\n",
+ "[itkWidgets](https://github.com/InsightSoftwareConsortium/itkwidgets) allows researchers to visualize images, point sets, and 3D geometry in Jupyter systems (Jupyer Notebooks, JupyterLab, AWS SageMaker, and Google Colab). Despite its name, itkWidgets does not require the use of ITK. It can directly visualize numpy arrays, torch tensors, DASK arrays, VTK polydata, and a multitude of other python data structures."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nj6P7YCmll4S",
+ "tags": []
+ },
+ "source": [
+ "# Outline\n",
+ "\n",
+ "1. Setup\n",
+ "2. Download data from TCIA\n",
+ "3. Prepare the data with ITK\n",
+ "4. Setup itkWidgets\n",
+ "5. MONAI Zoo Basics\n",
+ "6. MONAI Model Inference\n",
+ "7. Visualizing and Comparing Model and Expert Results"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8FgizAMWemJM"
+ },
+ "source": [
+ "# 1. Setup\n",
+ "\n",
+ "These are the initial steps for running notebooks within various Jupyter environments."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "As3EplXrbvwF"
+ },
+ "source": [
+ "## Setup environment"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "K3DOvHnXsf-I",
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# Install itk for DICOM I/O and for reading DICOM into an itkImage\n",
+ "# that manages all DICOM field values, include acquistion details\n",
+ "# such as voxel image, image orientation, and image directions,\n",
+ "# which are critical to image processing and display.\n",
+ "\n",
+ "# Upgrade pip, just in case.\n",
+ "!python -m pip install --upgrade -q pip\n",
+ "\n",
+ "# installations required for monai\n",
+ "!python -c \"import monai\" || pip install -q \"monai[nibabel,itk,tqdm,pandas,skimage]\"\n",
+ "!python -c \"import cv2\" || pip install -q opencv-python-headless\n",
+ "\n",
+ "# These are the libraries used to read DICOM Seg objects.\n",
+ "!python -m pip install -q pydicom pydicom-seg\n",
+ "\n",
+ "# Install tcia_utils to download the datasets.\n",
+ "!python -m pip install --upgrade -q --no-deps tcia_utils\n",
+ "\n",
+ "# Install the dependency manually to avoid installing opencv-python.\n",
+ "!python -m pip install -q plotly bs4 ipywidgets unidecode jsonschema\n",
+ "!python -m pip install -q --no-deps rt-utils\n",
+ "\n",
+ "# This is the installation required for itkWidgets.\n",
+ "!python -m pip install --upgrade --pre -q \"itkwidgets[all]==1.0a23\" imjoy_elfinder"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oYxvN-rebvwG"
+ },
+ "source": [
+ "## Setup imports\n",
+ "\n",
+ "### Setup the im-joy-jupyter-extension for itkWidgets\n",
+ "On many systems you must manually install the imjoy-jupyter-extension for itkWidgets! If you do not see a blue 'ImJoy' icon on the menu bar in this notebook:\n",
+ "\n",
+ "* Google CoLab: The following does not apply to Google CoLab - it will not show an ImJoy and all should work without modification.\n",
+ "* Enable Extensions: Many Jupyter Lab systems disable jupyter extensions by default, and they must be enabled for this notebook to work. Typically this is accomplished using the Jupyter interface to select the extension manager (left-hand side, icon that looks like a piece of a puzzle) and select the Enable button if it appears.\n",
+ "* Install imjoy extension: In the extension manager, search for 'imjoy' and install the 'imjoy-jupyter-extension'. The installation can take several minutes. It may also prompt you to rebuild, save, and reload your jupyter environment as part of this process. In the end, you should see a blue 'ImJoy' icon on the left side of the menu bar in this notebook."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "tF8-MqoN6YT5"
+ },
+ "outputs": [],
+ "source": [
+ "import glob\n",
+ "import os\n",
+ "\n",
+ "# Numpy for numpy.arrays\n",
+ "import numpy as np\n",
+ "\n",
+ "# Include ITK for DICOM reading.\n",
+ "import itk\n",
+ "\n",
+ "# Include pydicom_seg for DICOM SEG objects\n",
+ "import pydicom\n",
+ "import pydicom_seg\n",
+ "\n",
+ "# for downloading data from TCIA\n",
+ "from tcia_utils import nbia\n",
+ "\n",
+ "# This is the most common import command for itkWidgets.\n",
+ "# The view() function opens an interactive viewer for 2D and 3D\n",
+ "# data in a variety of formats.\n",
+ "from itkwidgets import view\n",
+ "\n",
+ "# imports for monai\n",
+ "import torch\n",
+ "from monai.data import decollate_batch\n",
+ "from monai.bundle import ConfigParser, download\n",
+ "\n",
+ "from monai.config import print_config\n",
+ "\n",
+ "print_config()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "Ub0GzFRXemJN"
+ },
+ "outputs": [],
+ "source": [
+ "# If running on SageMaker or Studio Lab, install essential packages and extensions.\n",
+ "if \"studio-lab-user\" in os.getcwd():\n",
+ " print(\"Upgrading dependencies\")\n",
+ " !conda install --yes -q --prefix {sys.prefix} -c conda-forge opencv nodejs"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "di4lxyikemJN",
+ "outputId": "408c7a4d-492f-43cf-cb38-afa92d1f53d3"
+ },
+ "source": [
+ "# 2. Download the data from TCIA\n",
+ "\n",
+ "[Browsing Collections](https://www.cancerimagingarchive.net/collections) and viewing [Analysis Results](https://www.cancerimagingarchive.net/tcia-analysis-results/) of datasets on TCIA are the easiest ways to become familiar with what is available. These pages will help you quickly identify datasets of interest, find valuable, supporting data that are not available via TCIA's APIs (e.g. clinical spreadsheets, non-DICOM segmentation data), and answer the most common questions you might have about the datasets. In this tutorial we'll be working with the [SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection](https://doi.org/10.7937/K9TCIA.2017.MURS5CL), but if you browse the previously mentioned links you will find that TCIA has many other prostate datasets which could be used with the [Prostate mri anatomy](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.3.1.zip) model. \n",
+ "\n",
+ "We will utilize the [tcia_utils](https://pypi.org/project/tcia-utils/) package to simplify downloading the data from TCIA. If you are new to accessing TCIA via notebooks, you can find additional tutorials on querying and downloading data at https://github.com/kirbyju/TCIA_Notebooks. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "urhgDgvb39pS"
+ },
+ "outputs": [],
+ "source": [
+ "# Download a \"Shared Cart\" containing 6 scans from PROSTATEx\n",
+ "# that has been previously created via the TCIA website\n",
+ "# (https://nbia.cancerimagingarchive.net).\n",
+ "cart_name = \"nbia-17571668146714049\"\n",
+ "\n",
+ "# retrieve cart metadata\n",
+ "cart_data = nbia.getSharedCart(cart_name)\n",
+ "\n",
+ "# download the series_uids list and return dataframe of metadata\n",
+ "df = nbia.downloadSeries(cart_data, format=\"df\")\n",
+ "\n",
+ "# display dataframe\n",
+ "# display(df)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MGPw6j3hbvwI"
+ },
+ "source": [
+ "# 3. Prepare the data with itk\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "7wR4HJu-emJP"
+ },
+ "outputs": [],
+ "source": [
+ "dicom_data_dir = \"tciaDownload\"\n",
+ "\n",
+ "# The series_uid defines their directory where the MR data was stored on disk.\n",
+ "mr_series_uid = df.at[df.Modality.eq(\"MR\").idxmax(), \"Series UID\"]\n",
+ "mr_dir = os.path.join(dicom_data_dir, mr_series_uid)\n",
+ "\n",
+ "# Read the DICOM MR series' objects and reconstruct them into a 3D ITK image.\n",
+ "# The itk.F option is added to store the image in memory using floating-point precision pixels (useful if you will filter the image or use it with MONAI).\n",
+ "# For more info on imread, see https://itkpythonpackage.readthedocs.io/en/master/Quick_start_guide.html.\n",
+ "mr_image = itk.imread(mr_dir, itk.F)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "JdT44AzPemJP"
+ },
+ "outputs": [],
+ "source": [
+ "# The series_uid defines where the RTSTRUCT was stored on disk. It is stored in a single file.\n",
+ "seg_series_uid = df.at[df.Modality.eq(\"SEG\").idxmax(), \"Series UID\"]\n",
+ "seg_dir = os.path.join(dicom_data_dir, seg_series_uid)\n",
+ "seg_file = glob.glob(os.path.join(seg_dir, \"*.dcm\"))[0]\n",
+ "\n",
+ "# Read the DICOM SEG object using pydicom and pydicom_seg.\n",
+ "seg_dicom = pydicom.dcmread(seg_file)\n",
+ "seg_reader = pydicom_seg.MultiClassReader()\n",
+ "seg_obj = seg_reader.read(seg_dicom)\n",
+ "\n",
+ "# Convert the DICOM SEG object into an itk image, with correct voxel origin, spacing, and directions in physical space.\n",
+ "seg_image = itk.GetImageFromArray(seg_obj.data.astype(np.float32))\n",
+ "seg_image.CopyInformation(mr_image)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "yGV9j8TbemJP",
+ "tags": []
+ },
+ "source": [
+ "# 4. MONAI Zoo Basics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "diJ1EeQQemJQ"
+ },
+ "outputs": [],
+ "source": [
+ "model_name = \"prostate_mri_anatomy\"\n",
+ "model_version = \"0.3.1\"\n",
+ "zoo_dir = os.path.abspath(\"./models\")\n",
+ "\n",
+ "download(name=model_name, version=model_version, bundle_dir=zoo_dir)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "xcj8cA_ZemJQ"
+ },
+ "outputs": [],
+ "source": [
+ "# This model includes scripts that must be run on new data.\n",
+ "# We could import those scripts into this python notebook, but they\n",
+ "# bring in additional dependencies. Instead, we provide the following\n",
+ "# more compact and compatible implementation. Otherwise, you can\n",
+ "# include the model's script directory by uncommenting these lines and\n",
+ "# installing their dependencies and doing appropriate data conversions.\n",
+ "# scripts_dir = os.path.join(zoo_dir, model_name, \"scripts\")\n",
+ "# sys.path.insert(1, scripts_dir)\n",
+ "\n",
+ "\n",
+ "# Compact alternative implementation of this model's specific cropping step.\n",
+ "# Ideally this would have been accomplished using MONAI's transforms\n",
+ "# for data pre-processing / augmentation instead of using a separate\n",
+ "# function.\n",
+ "def prostate_crop(img):\n",
+ " boundary = [int(crop_size * 0.2) for crop_size in img.GetLargestPossibleRegion().GetSize()]\n",
+ " new_image = itk.CropImageFilter(Input=img, BoundaryCropSize=boundary)\n",
+ " return new_image\n",
+ "\n",
+ "\n",
+ "mr_image_prep = prostate_crop(mr_image)\n",
+ "seg_image_prep = prostate_crop(seg_image)\n",
+ "\n",
+ "# Running a MONAI model on new data requires that data to be saved on\n",
+ "# local disk.\n",
+ "itk.imwrite(mr_image_prep, mr_dir + \".nii.gz\")\n",
+ "itk.imwrite(seg_image_prep, seg_dir + \".nii.gz\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "YhDJqRkHemJQ"
+ },
+ "outputs": [],
+ "source": [
+ "# The model's config file dynamically generates the functions needed to process new data.\n",
+ "\n",
+ "# Define our local system and filesystem.\n",
+ "output_dir = os.path.abspath(\"./monai_results\")\n",
+ "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
+ "\n",
+ "# Parse the variables in the config file.\n",
+ "model_config_file = os.path.join(zoo_dir, model_name, \"configs\", \"inference.json\")\n",
+ "model_config = ConfigParser()\n",
+ "model_config.read_config(model_config_file)\n",
+ "\n",
+ "# Update the confir variables to match our filesystem.\n",
+ "model_config[\"bundle_root\"] = zoo_dir\n",
+ "model_config[\"output_dir\"] = output_dir\n",
+ "\n",
+ "# Identify which version of the model we want to load (each version is a\n",
+ "# \"checkpoint\"). For most models, the \"best\" checkpoint is called \"model.pt\"\n",
+ "# and it is stored in the models subdir.\n",
+ "checkpoint = os.path.join(zoo_dir, model_name, \"models\", \"model.pt\")\n",
+ "\n",
+ "# Ask the config file to generate the functions needed to process new data.\n",
+ "# These functions are adapted to our system by the config variables we\n",
+ "# modified above. The order of first defining variables and then creating the\n",
+ "# functions is critical.\n",
+ "preprocessing = model_config.get_parsed_content(\"preprocessing\")\n",
+ "\n",
+ "model = model_config.get_parsed_content(\"network\").to(device)\n",
+ "\n",
+ "inferer = model_config.get_parsed_content(\"inferer\")\n",
+ "\n",
+ "postprocessing = model_config.get_parsed_content(\"postprocessing\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "CqoHulOhemJR"
+ },
+ "outputs": [],
+ "source": [
+ "# Point the dataloader to the downloaded and converted TCIA data.\n",
+ "datalist = [mr_dir + \".nii.gz\"]\n",
+ "model_config[\"datalist\"] = datalist\n",
+ "dataloader = model_config.get_parsed_content(\"dataloader\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zX0UIVt9bvwJ"
+ },
+ "source": [
+ "# 5. Visualize the data with itkWidgets\n",
+ "\n",
+ "[itkWidgets documentation](https://itkwidgets.readthedocs.io/en/latest/?badge=latest) provides a summary and illustrations of itkWidgets for a wide variety of scientific data visualization use cases."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "RF4LqDs-emJR",
+ "tags": []
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "
\n",
+ " \n",
+ " "
],
- "source": [
- "# The series_uid defines where the RTSTRUCT was stored on disk. It is stored in a single file.\n",
- "seg_series_uid = df.at[df.Modality.eq(\"SEG\").idxmax(), \"Series UID\"]\n",
- "seg_dir = os.path.join(dicom_data_dir, seg_series_uid)\n",
- "seg_file = glob.glob(os.path.join(seg_dir, \"*.dcm\"))[0]\n",
- "\n",
- "# Read the DICOM SEG object using pydicom and pydicom_seg.\n",
- "seg_dicom = pydicom.dcmread(seg_file)\n",
- "seg_reader = pydicom_seg.MultiClassReader()\n",
- "seg_obj = seg_reader.read(seg_dicom)\n",
- "\n",
- "# Convert the DICOM SEG object into an itk image, with correct voxel origin, spacing, and directions in physical space.\n",
- "seg_image = itk.GetImageFromArray(seg_obj.data.astype(np.float32))\n",
- "seg_image.CopyInformation(mr_image)"
+ "text/plain": [
+ ""
]
+ },
+ "metadata": {},
+ "output_type": "display_data"
},
{
- "cell_type": "markdown",
- "metadata": {
- "id": "yGV9j8TbemJP",
- "tags": []
- },
- "source": [
- "# 4. MONAI Zoo Basics"
+ "data": {
+ "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
+ "text/plain": [
+ ""
]
+ },
+ "metadata": {},
+ "output_type": "display_data"
},
{
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "id": "diJ1EeQQemJQ",
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "outputId": "485d99d2-fca3-4f36-93d1-a9c1ed56dba1"
- },
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "2024-09-24 17:23:39,121 - INFO - --- input summary of monai.bundle.scripts.download ---\n",
- "2024-09-24 17:23:39,123 - INFO - > name: 'prostate_mri_anatomy'\n",
- "2024-09-24 17:23:39,125 - INFO - > version: '0.3.1'\n",
- "2024-09-24 17:23:39,126 - INFO - > bundle_dir: '/content/models'\n",
- "2024-09-24 17:23:39,128 - INFO - > source: 'monaihosting'\n",
- "2024-09-24 17:23:39,131 - INFO - > remove_prefix: 'monai_'\n",
- "2024-09-24 17:23:39,133 - INFO - > progress: True\n",
- "2024-09-24 17:23:39,137 - INFO - ---\n",
- "\n",
- "\n"
- ]
- },
- {
- "output_type": "stream",
- "name": "stderr",
- "text": [
- "prostate_mri_anatomy_v0.3.1.zip: 269MB [00:07, 39.5MB/s] "
- ]
- },
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "2024-09-24 17:23:46,293 - INFO - Downloaded: /content/models/prostate_mri_anatomy_v0.3.1.zip\n",
- "2024-09-24 17:23:46,294 - INFO - Expected md5 is None, skip md5 check for file /content/models/prostate_mri_anatomy_v0.3.1.zip.\n",
- "2024-09-24 17:23:46,296 - INFO - Writing into directory: /content/models.\n"
- ]
- },
- {
- "output_type": "stream",
- "name": "stderr",
- "text": [
- "\n"
- ]
- }
+ "data": {
+ "text/html": [
+ ""
],
- "source": [
- "model_name = \"prostate_mri_anatomy\"\n",
- "model_version = \"0.3.1\"\n",
- "zoo_dir = os.path.abspath(\"./models\")\n",
- "\n",
- "download(name=model_name, version=model_version, bundle_dir=zoo_dir)"
+ "text/plain": [
+ ""
]
+ },
+ "metadata": {},
+ "output_type": "display_data"
},
{
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "id": "xcj8cA_ZemJQ"
- },
- "outputs": [],
- "source": [
- "# This model includes scripts that must be run on new data.\n",
- "# We could import those scripts into this python notebook, but they\n",
- "# bring in additional dependencies. Instead, we provide the following\n",
- "# more compact and compatible implementation. Otherwise, you can\n",
- "# include the model's script directory by uncommenting these lines and\n",
- "# installing their dependencies and doing appropriate data conversions.\n",
- "# scripts_dir = os.path.join(zoo_dir, model_name, \"scripts\")\n",
- "# sys.path.insert(1, scripts_dir)\n",
- "\n",
- "\n",
- "# Compact alternative implementation of this model's specific cropping step.\n",
- "# Ideally this would have been accomplished using MONAI's transforms\n",
- "# for data pre-processing / augmentation instead of using a separate\n",
- "# function.\n",
- "def prostate_crop(img):\n",
- " boundary = [int(crop_size * 0.2) for crop_size in img.GetLargestPossibleRegion().GetSize()]\n",
- " new_image = itk.CropImageFilter(Input=img, BoundaryCropSize=boundary)\n",
- " return new_image\n",
- "\n",
- "\n",
- "mr_image_prep = prostate_crop(mr_image)\n",
- "seg_image_prep = prostate_crop(seg_image)\n",
- "\n",
- "# Running a MONAI model on new data requires that data to be saved on\n",
- "# local disk.\n",
- "itk.imwrite(mr_image_prep, mr_dir + \".nii.gz\")\n",
- "itk.imwrite(seg_image_prep, seg_dir + \".nii.gz\")"
+ "data": {
+ "text/plain": [
+ ""
]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "id": "YhDJqRkHemJQ"
- },
- "outputs": [],
- "source": [
- "# The model's config file dynamically generates the functions needed to process new data.\n",
- "\n",
- "# Define our local system and filesystem.\n",
- "output_dir = os.path.abspath(\"./monai_results\")\n",
- "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
- "\n",
- "# Parse the variables in the config file.\n",
- "model_config_file = os.path.join(zoo_dir, model_name, \"configs\", \"inference.json\")\n",
- "model_config = ConfigParser()\n",
- "model_config.read_config(model_config_file)\n",
- "\n",
- "# Update the confir variables to match our filesystem.\n",
- "model_config[\"bundle_root\"] = zoo_dir\n",
- "model_config[\"output_dir\"] = output_dir\n",
- "\n",
- "# Identify which version of the model we want to load (each version is a\n",
- "# \"checkpoint\"). For most models, the \"best\" checkpoint is called \"model.pt\"\n",
- "# and it is stored in the models subdir.\n",
- "checkpoint = os.path.join(zoo_dir, model_name, \"models\", \"model.pt\")\n",
- "\n",
- "# Ask the config file to generate the functions needed to process new data.\n",
- "# These functions are adapted to our system by the config variables we\n",
- "# modified above. The order of first defining variables and then creating the\n",
- "# functions is critical.\n",
- "preprocessing = model_config.get_parsed_content(\"preprocessing\")\n",
- "\n",
- "model = model_config.get_parsed_content(\"network\").to(device)\n",
- "\n",
- "inferer = model_config.get_parsed_content(\"inferer\")\n",
- "\n",
- "postprocessing = model_config.get_parsed_content(\"postprocessing\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "id": "CqoHulOhemJR",
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "outputId": "081925ff-be7a-4619-f4e5-734a42a15dbb"
- },
- "outputs": [
- {
- "output_type": "stream",
- "name": "stderr",
- "text": [
- "This DataLoader will create 4 worker processes in total. Our suggested max number of worker in current system is 2, which is smaller than what this DataLoader is going to create. Please be aware that excessive worker creation might get DataLoader running slow or even freeze, lower the worker number to avoid potential slowness/freeze if necessary.\n"
- ]
- }
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "view(image=mr_image_prep, label_image=seg_image_prep)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8FmGXwzXemJR",
+ "tags": []
+ },
+ "source": [
+ "# 6. MONAI Model Inference"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "kbGZrHfWemJR",
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "model.load_state_dict(torch.load(checkpoint, map_location=device))\n",
+ "model.eval()\n",
+ "results = []\n",
+ "with torch.no_grad():\n",
+ " for d in dataloader:\n",
+ " images = d[\"image\"].to(device)\n",
+ " d[\"pred\"] = inferer(images, network=model)\n",
+ " results.append([postprocessing(i) for i in decollate_batch(d)])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HrMqViotemJS"
+ },
+ "source": [
+ "# 7. Visualizing and Comparing Model and Expert Results"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "cjLs9PjDemJS"
+ },
+ "outputs": [],
+ "source": [
+ "# Read the result image that was written into the output_dir.\n",
+ "result_image = itk.imread(\n",
+ " os.path.join(output_dir, os.path.split(mr_dir)[1], os.path.split(mr_dir)[1] + \"_trans.nii.gz\")\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "xkh3TtD9emJS"
+ },
+ "outputs": [],
+ "source": [
+ "# Various manipulations were done to the input image before it is fed to the model\n",
+ "# for inference. As a result, the result image may not be in the same\n",
+ "# spacing, orientation, etc as the original input data. So, we resample the results\n",
+ "# image to match the physical properties of the original input data.\n",
+ "interpolator = itk.NearestNeighborInterpolateImageFunction.New(seg_image)\n",
+ "result_image_resampled = itk.resample_image_filter(\n",
+ " Input=result_image, Interpolator=interpolator, reference_image=seg_image_prep, use_reference_image=True\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {
+ "id": "9bmgCBL9emJS",
+ "tags": []
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "
\n",
+ " \n",
+ " "
],
- "source": [
- "# Point the dataloader to the downloaded and converted TCIA data.\n",
- "datalist = [mr_dir + \".nii.gz\"]\n",
- "model_config[\"datalist\"] = datalist\n",
- "dataloader = model_config.get_parsed_content(\"dataloader\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "zX0UIVt9bvwJ"
- },
- "source": [
- "# 5. Visualize the data with itkWidgets\n",
- "\n",
- "[itkWidgets documentation](https://itkwidgets.readthedocs.io/en/latest/?badge=latest) provides a summary and illustrations of itkWidgets for a wide variety of scientific data visualization use cases."
+ "text/plain": [
+ ""
]
+ },
+ "metadata": {},
+ "output_type": "display_data"
},
{
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "RF4LqDs-emJR",
- "tags": []
- },
- "outputs": [],
- "source": [
- "view(image=mr_image_prep, label_image=seg_image_prep)"
+ "data": {
+ "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
+ "text/plain": [
+ ""
]
+ },
+ "metadata": {},
+ "output_type": "display_data"
},
{
- "cell_type": "markdown",
- "source": [
- ""
+ "data": {
+ "text/html": [
+ ""
],
- "metadata": {
- "id": "i8Cazs1CG2nf"
- }
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "8FmGXwzXemJR",
- "tags": []
- },
- "source": [
- "# 6. MONAI Model Inference"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "id": "kbGZrHfWemJR",
- "tags": [],
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "outputId": "61880710-6836-4561-bd9f-81df472239e3"
- },
- "outputs": [
- {
- "output_type": "stream",
- "name": "stderr",
- "text": [
- "You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n"
- ]
- },
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "2024-09-24 17:25:50,204 INFO image_writer.py:197 - writing: /content/monai_results/1.3.6.1.4.1.14519.5.2.1.7311.5101.206828891270520544417996275680/1.3.6.1.4.1.14519.5.2.1.7311.5101.206828891270520544417996275680_trans.nii.gz\n"
- ]
- }
- ],
- "source": [
- "model.load_state_dict(torch.load(checkpoint, map_location=device))\n",
- "model.eval()\n",
- "results = []\n",
- "with torch.no_grad():\n",
- " for d in dataloader:\n",
- " images = d[\"image\"].to(device)\n",
- " d[\"pred\"] = inferer(images, network=model)\n",
- " results.append([postprocessing(i) for i in decollate_batch(d)])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "HrMqViotemJS"
- },
- "source": [
- "# 7. Visualizing and Comparing Model and Expert Results"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "id": "cjLs9PjDemJS"
- },
- "outputs": [],
- "source": [
- "# Read the result image that was written into the output_dir.\n",
- "result_image = itk.imread(\n",
- " os.path.join(output_dir, os.path.split(mr_dir)[1], os.path.split(mr_dir)[1] + \"_trans.nii.gz\")\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "id": "xkh3TtD9emJS"
- },
- "outputs": [],
- "source": [
- "# Various manipulations were done to the input image before it is fed to the model\n",
- "# for inference. As a result, the result image may not be in the same\n",
- "# spacing, orientation, etc as the original input data. So, we resample the results\n",
- "# image to match the physical properties of the original input data.\n",
- "interpolator = itk.NearestNeighborInterpolateImageFunction.New(seg_image)\n",
- "result_image_resampled = itk.resample_image_filter(\n",
- " Input=result_image, Interpolator=interpolator, reference_image=seg_image_prep, use_reference_image=True\n",
- ")"
+ "text/plain": [
+ ""
]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "9bmgCBL9emJS",
- "tags": []
- },
- "outputs": [],
- "source": [
- "# View the image with results overlaid in an interactive 2D slice viewer.\n",
- "viewer_b = view(image=mr_image_prep, label_image=result_image_resampled)"
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- ""
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# View the image with results overlaid in an interactive 2D slice viewer.\n",
+ "viewer_b = view(image=mr_image_prep, label_image=result_image_resampled)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {
+ "id": "mYRlAbKusf-L",
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "viewer_b.set_image_color_map(\"Grayscale\")\n",
+ "viewer_b.set_label_image_blend(0.5)\n",
+ "viewer_b.set_image_color_range([100, 500])\n",
+ "viewer_b.set_view_mode(\"ZPlane\")\n",
+ "viewer_b.set_ui_collapsed(False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {
+ "id": "2wHOPVkWemJS",
+ "tags": []
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "
\n",
+ " \n",
+ " "
],
- "metadata": {
- "id": "dftNenXyHHfZ"
- }
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "id": "mYRlAbKusf-L",
- "tags": []
- },
- "outputs": [],
- "source": [
- "viewer_b.set_image_color_map(\"Grayscale\")\n",
- "viewer_b.set_label_image_blend(0.5)\n",
- "viewer_b.set_image_color_range([100, 500])\n",
- "viewer_b.set_view_mode(\"ZPlane\")\n",
- "viewer_b.set_ui_collapsed(False)"
+ "text/plain": [
+ ""
]
+ },
+ "metadata": {},
+ "output_type": "display_data"
},
{
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "2wHOPVkWemJS",
- "tags": []
- },
- "outputs": [],
- "source": [
- "result_array = itk.GetArrayViewFromImage(result_image_resampled)\n",
- "expert_array = itk.GetArrayViewFromImage(seg_image_prep)\n",
- "\n",
- "# Note that the data in the ProstateX repo uses different labels than the data used to\n",
- "# build the model. For example, the prostate is label 1 in the model and label 2\n",
- "# in the ProstateX data.\n",
- "# The following creates a label image where\n",
- "# 1 = ideal prostate, but model called non-prostate (red)\n",
- "# 2 = model called prostate, but ideal called non-prostate (purple)\n",
- "# 3 = modeal and ideal agreed (green)\n",
- "compare_model_expert = np.where(result_array != 1, 0, 2) + np.where(expert_array != 2, 0, 1)\n",
- "compare_image = itk.GetImageFromArray(compare_model_expert.astype(np.float32))\n",
- "compare_image.CopyInformation(seg_image_prep)\n",
- "\n",
- "viewer_c = view(image=mr_image_prep, label_image=compare_image)"
+ "data": {
+ "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
+ "text/plain": [
+ ""
]
+ },
+ "metadata": {},
+ "output_type": "display_data"
},
{
- "cell_type": "markdown",
- "source": [
- ""
+ "data": {
+ "text/html": [
+ ""
],
- "metadata": {
- "id": "m76Ue6tBHLgU"
- }
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "id": "diqDQW4PemJS"
- },
- "outputs": [],
- "source": [
- "# Switch to an interactive slice view so that labels are more easily seen.\n",
- "viewer_c.set_label_image_blend(0.6)\n",
- "viewer_c.set_image_color_map(\"Grayscale\")\n",
- "viewer_c.set_view_mode(\"ZPlane\")\n",
- "viewer_c.set_image_color_range([100, 500])\n",
- "viewer_c.set_ui_collapsed(False)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "DYXsNGcY93B8",
- "tags": []
- },
- "source": [
- "# Acknowledgements\n",
- "\n",
- "TCIA is funded by the [Cancer Imaging Program (CIP)](https://imaging.cancer.gov/), a part of the United States [National Cancer Institute (NCI)](https://www.cancer.gov/), and is managed by the [Frederick National Laboratory for Cancer Research (FNLCR)](https://frederick.cancer.gov/).\n",
- "\n",
- "If you leverage this notebook or any TCIA datasets in your work, please be sure to comply with the [TCIA Data Usage Policy](https://wiki.cancerimagingarchive.net/x/c4hF). In particular, make sure to cite the DOI(s) for the specific TCIA datasets you used in addition to TCIA citation provided below!\n",
- "\n",
- "This notebook was created by [Stephen Aylward (Kitware)](https://www.kitware.com/stephen-aylward/), [Justin Kirby (Frederick National Laboratory for Cancer Research)](https://www.linkedin.com/in/justinkirby82/), [Brianna Major (Kitware)](https://www.kitware.com/brianna-major/), and [Matt McCormick (Kitware)](https://www.kitware.com/matt-mccormick/). The creation of this notebook was funded, in part, by NIBIB and NIGMS R01EB021396,\n",
- "NIBIB R01EB014955, NCI R01CA220681, and NINDS R42NS086295.\n",
- "\n",
- "If you have any questions, suggestions, or issues with itkWidgets, please post them on the [itkwidget issue tracker](https://github.com/InsightSoftwareConsortium/itkwidgets/issues) or feel free to email us at kitware@kitware.com.\n",
- "\n",
- "## Dataset Citation\n",
- "The data used in this notebook was part of the SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection:\n",
- "\n",
- "Geert Litjens, Oscar Debats, Jelle Barentsz, Nico Karssemeijer, and Henkjan Huisman. \"ProstateX Challenge data\", The Cancer Imaging Archive (2017). DOI: [10.7937/K9TCIA.2017.MURS5CL](https://doi.org/10.7937/K9TCIA.2017.MURS5CL)\n",
- "\n",
- "## Publication Citation\n",
- "The data used in this notebook was part of the SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection:\n",
- "\n",
- "Litjens G, Debats O, Barentsz J, Karssemeijer N, Huisman H. \"Computer-aided detection of prostate cancer in MRI\", IEEE Transactions on Medical Imaging 2014;33:1083-1092. DOI: [10.1109/TMI.2014.2303821](https://doi.org/10.1109/TMI.2014.2303821)\n",
- "\n",
- "## TCIA Citation\n",
- "\n",
- "Clark, K., Vendt, B., Smith, K., Freymann, J., Kirby, J., Koppel, P., Moore, S., Phillips, S., Maffitt, D., Pringle, M., Tarbox, L., & Prior, F. (2013). The Cancer Imaging Archive (TCIA): Maintaining and Operating a Public Information Repository. Journal of Digital Imaging, 26(6), 1045–1057. https://doi.org/10.1007/s10278-013-9622-7"
+ "text/plain": [
+ ""
]
+ },
+ "metadata": {},
+ "output_type": "display_data"
}
- ],
- "metadata": {
- "colab": {
- "provenance": []
- },
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.12"
- }
+ ],
+ "source": [
+ "result_array = itk.GetArrayViewFromImage(result_image_resampled)\n",
+ "expert_array = itk.GetArrayViewFromImage(seg_image_prep)\n",
+ "\n",
+ "# Note that the data in the ProstateX repo uses different labels than the data used to\n",
+ "# build the model. For example, the prostate is label 1 in the model and label 2\n",
+ "# in the ProstateX data.\n",
+ "# The following creates a label image where\n",
+ "# 1 = ideal prostate, but model called non-prostate (red)\n",
+ "# 2 = model called prostate, but ideal called non-prostate (purple)\n",
+ "# 3 = modeal and ideal agreed (green)\n",
+ "compare_model_expert = np.where(result_array != 1, 0, 2) + np.where(expert_array != 2, 0, 1)\n",
+ "compare_image = itk.GetImageFromArray(compare_model_expert.astype(np.float32))\n",
+ "compare_image.CopyInformation(seg_image_prep)\n",
+ "\n",
+ "viewer_c = view(image=mr_image_prep, label_image=compare_image)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {
+ "id": "diqDQW4PemJS"
+ },
+ "outputs": [],
+ "source": [
+ "# Switch to an interactive slice view so that labels are more easily seen.\n",
+ "viewer_c.set_label_image_blend(0.6)\n",
+ "viewer_c.set_image_color_map(\"Grayscale\")\n",
+ "viewer_c.set_view_mode(\"ZPlane\")\n",
+ "viewer_c.set_image_color_range([100, 500])\n",
+ "viewer_c.set_ui_collapsed(False)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DYXsNGcY93B8",
+ "tags": []
+ },
+ "source": [
+ "# Acknowledgements\n",
+ "\n",
+ "TCIA is funded by the [Cancer Imaging Program (CIP)](https://imaging.cancer.gov/), a part of the United States [National Cancer Institute (NCI)](https://www.cancer.gov/), and is managed by the [Frederick National Laboratory for Cancer Research (FNLCR)](https://frederick.cancer.gov/).\n",
+ "\n",
+ "If you leverage this notebook or any TCIA datasets in your work, please be sure to comply with the [TCIA Data Usage Policy](https://wiki.cancerimagingarchive.net/x/c4hF). In particular, make sure to cite the DOI(s) for the specific TCIA datasets you used in addition to TCIA citation provided below!\n",
+ "\n",
+ "This notebook was created by [Stephen Aylward (Kitware)](https://www.kitware.com/stephen-aylward/), [Justin Kirby (Frederick National Laboratory for Cancer Research)](https://www.linkedin.com/in/justinkirby82/), [Brianna Major (Kitware)](https://www.kitware.com/brianna-major/), and [Matt McCormick (Kitware)](https://www.kitware.com/matt-mccormick/). The creation of this notebook was funded, in part, by NIBIB and NIGMS R01EB021396,\n",
+ "NIBIB R01EB014955, NCI R01CA220681, and NINDS R42NS086295.\n",
+ "\n",
+ "If you have any questions, suggestions, or issues with itkWidgets, please post them on the [itkwidget issue tracker](https://github.com/InsightSoftwareConsortium/itkwidgets/issues) or feel free to email us at kitware@kitware.com.\n",
+ "\n",
+ "## Dataset Citation\n",
+ "The data used in this notebook was part of the SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection:\n",
+ "\n",
+ "Geert Litjens, Oscar Debats, Jelle Barentsz, Nico Karssemeijer, and Henkjan Huisman. \"ProstateX Challenge data\", The Cancer Imaging Archive (2017). DOI: [10.7937/K9TCIA.2017.MURS5CL](https://doi.org/10.7937/K9TCIA.2017.MURS5CL)\n",
+ "\n",
+ "## Publication Citation\n",
+ "The data used in this notebook was part of the SPIE-AAPM-NCI PROSTATEx Challenges (PROSTATEx) collection:\n",
+ "\n",
+ "Litjens G, Debats O, Barentsz J, Karssemeijer N, Huisman H. \"Computer-aided detection of prostate cancer in MRI\", IEEE Transactions on Medical Imaging 2014;33:1083-1092. DOI: [10.1109/TMI.2014.2303821](https://doi.org/10.1109/TMI.2014.2303821)\n",
+ "\n",
+ "## TCIA Citation\n",
+ "\n",
+ "Clark, K., Vendt, B., Smith, K., Freymann, J., Kirby, J., Koppel, P., Moore, S., Phillips, S., Maffitt, D., Pringle, M., Tarbox, L., & Prior, F. (2013). The Cancer Imaging Archive (TCIA): Maintaining and Operating a Public Information Repository. Journal of Digital Imaging, 26(6), 1045–1057. https://doi.org/10.1007/s10278-013-9622-7"
+ ]
+ }
+ ],
+ "metadata": {
+ "colab": {
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
},
- "nbformat": 4,
- "nbformat_minor": 0
-}
\ No newline at end of file
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
From f3d172ea744f305dbe0937a71684f7c92365f208 Mon Sep 17 00:00:00 2001
From: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
Date: Fri, 4 Oct 2024 21:04:27 -0400
Subject: [PATCH 3/7] Updated tcia_prostatex_prostate_mri_anatomy_model.ipynb
Fixed some dependency issues related to itkwidgets that were preventing the notebook from running.
---
...IA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
index f1dc6f0e5f..a5cff65e06 100644
--- a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
+++ b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
@@ -116,17 +116,21 @@
"!python -c \"import cv2\" || pip install -q opencv-python-headless\n",
"\n",
"# These are the libraries used to read DICOM Seg objects.\n",
- "!python -m pip install -q pydicom pydicom-seg\n",
- "\n",
- "# Install tcia_utils to download the datasets.\n",
- "!python -m pip install --upgrade -q --no-deps tcia_utils\n",
+ "!python -m pip install -q \"pydicom<3\" pydicom-seg\n",
"\n",
"# Install the dependency manually to avoid installing opencv-python.\n",
- "!python -m pip install -q plotly bs4 ipywidgets unidecode jsonschema\n",
+ "!python -m pip install -q plotly bs4 unidecode\n",
"!python -m pip install -q --no-deps rt-utils\n",
"\n",
+ "# Install tcia_utils to download the datasets.\n",
+ "!python -m pip install --upgrade -q --no-deps tcia_utils\n",
+ "\n",
"# This is the installation required for itkWidgets.\n",
- "!python -m pip install --upgrade --pre -q \"itkwidgets[all]==1.0a23\" imjoy_elfinder"
+ "!python -m pip install --upgrade --pre -q \"itkwidgets[all]\" imjoy_elfinder\n",
+ "\n",
+ "# TEMPORARY WORKAROUND TO RESOLVE: https://github.com/kirbyju/TCIA_Notebooks/issues/30\n",
+ "!python -m pip uninstall -y -q zarr ngff_zarr\n",
+ "!python -m pip install -q zarr ngff_zarr"
]
},
{
From 6fc1435c5431d5a84237cfb0f2db4f759dea1ea6 Mon Sep 17 00:00:00 2001
From: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
Date: Tue, 8 Oct 2024 14:15:31 -0400
Subject: [PATCH 4/7] Update TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
Updated with the guidance provided in https://github.com/Project-MONAI/tutorials/pull/1852.
---
...PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb | 41 +++++++++++--------
1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
index a5cff65e06..263ded214d 100644
--- a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
+++ b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
@@ -108,29 +108,28 @@
"# such as voxel image, image orientation, and image directions,\n",
"# which are critical to image processing and display.\n",
"\n",
+ "import sys\n",
+ "\n",
"# Upgrade pip, just in case.\n",
- "!python -m pip install --upgrade -q pip\n",
+ "!{sys.executable} -m pip install --upgrade -q pip\n",
"\n",
"# installations required for monai\n",
- "!python -c \"import monai\" || pip install -q \"monai[nibabel,itk,tqdm,pandas,skimage]\"\n",
- "!python -c \"import cv2\" || pip install -q opencv-python-headless\n",
+ "!{sys.executable} -m pip install -q \"monai[nibabel,itk,tqdm,pandas,skimage]\"\n",
+ "!{sys.executable} -m pip install -q opencv-python-headless\n",
"\n",
"# These are the libraries used to read DICOM Seg objects.\n",
- "!python -m pip install -q \"pydicom<3\" pydicom-seg\n",
+ "!{sys.executable} -m pip install -q \"pydicom==2.4.4\" pydicom-seg\n",
"\n",
"# Install the dependency manually to avoid installing opencv-python.\n",
- "!python -m pip install -q plotly bs4 unidecode\n",
- "!python -m pip install -q --no-deps rt-utils\n",
+ "!{sys.executable} -m pip install -q plotly bs4 unidecode\n",
+ "!{sys.executable} -m pip install -q --no-deps rt-utils\n",
"\n",
"# Install tcia_utils to download the datasets.\n",
- "!python -m pip install --upgrade -q --no-deps tcia_utils\n",
+ "!{sys.executable} -m pip install --upgrade -q --no-deps tcia_utils\n",
"\n",
"# This is the installation required for itkWidgets.\n",
- "!python -m pip install --upgrade --pre -q \"itkwidgets[all]\" imjoy_elfinder\n",
- "\n",
- "# TEMPORARY WORKAROUND TO RESOLVE: https://github.com/kirbyju/TCIA_Notebooks/issues/30\n",
- "!python -m pip uninstall -y -q zarr ngff_zarr\n",
- "!python -m pip install -q zarr ngff_zarr"
+ "!{sys.executable} -m pip install --upgrade -q \"itkwidgets[all]==1.0a53\" imjoy_elfinder\n",
+ "\n"
]
},
{
@@ -450,7 +449,9 @@
},
{
"data": {
- "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
+ "application/javascript": [
+ "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")"
+ ],
"text/plain": [
""
]
@@ -586,7 +587,9 @@
},
{
"data": {
- "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
+ "application/javascript": [
+ "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")"
+ ],
"text/plain": [
""
]
@@ -659,7 +662,9 @@
},
{
"data": {
- "application/javascript": "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")",
+ "application/javascript": [
+ "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")"
+ ],
"text/plain": [
""
]
@@ -753,9 +758,9 @@
"provenance": []
},
"kernelspec": {
- "display_name": "Python 3 (ipykernel)",
+ "display_name": "monai",
"language": "python",
- "name": "python3"
+ "name": "monai"
},
"language_info": {
"codemirror_mode": {
@@ -771,5 +776,5 @@
}
},
"nbformat": 4,
- "nbformat_minor": 1
+ "nbformat_minor": 4
}
From 11621f6abfb509cb27e502cdb55b078570fd5daf Mon Sep 17 00:00:00 2001
From: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
Date: Wed, 9 Oct 2024 09:35:45 -0400
Subject: [PATCH 5/7] Justin Kirby <2379527+kirbyju@users.noreply.github.com>
DCO Remediation Commit for Justin Kirby
<2379527+kirbyju@users.noreply.github.com>
I, Justin Kirby <2379527+kirbyju@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 00f3362af5df6e279e5978b6117517c34adf93cd
I, Justin Kirby <2379527+kirbyju@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 6e36c647472b96e1bf01ead6a2f37550e9b4176a
I, Justin Kirby <2379527+kirbyju@users.noreply.github.com>, hereby add my Signed-off-by to this commit: f3d172ea744f305dbe0937a71684f7c92365f208
I, Justin Kirby <2379527+kirbyju@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 6fc1435c5431d5a84237cfb0f2db4f759dea1ea6
Signed-off-by: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
From 17b2c4969043c27d132926a0448b32569d3fe1b3 Mon Sep 17 00:00:00 2001
From: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
Date: Wed, 9 Oct 2024 13:47:35 -0400
Subject: [PATCH 6/7] Update TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
Fix pep8/premerge errors.
Signed-off-by: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
---
...PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
index 263ded214d..dc2c47ccfd 100644
--- a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
+++ b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
@@ -108,28 +108,25 @@
"# such as voxel image, image orientation, and image directions,\n",
"# which are critical to image processing and display.\n",
"\n",
- "import sys\n",
- "\n",
"# Upgrade pip, just in case.\n",
- "!{sys.executable} -m pip install --upgrade -q pip\n",
+ "!python -m pip install --upgrade -q pip\n",
"\n",
"# installations required for monai\n",
- "!{sys.executable} -m pip install -q \"monai[nibabel,itk,tqdm,pandas,skimage]\"\n",
- "!{sys.executable} -m pip install -q opencv-python-headless\n",
+ "!python -c \"import monai\" || pip install -q \"monai[nibabel,itk,tqdm,pandas,skimage]\"\n",
+ "!python -c \"import cv2\" || pip install -q opencv-python-headless\n",
"\n",
"# These are the libraries used to read DICOM Seg objects.\n",
- "!{sys.executable} -m pip install -q \"pydicom==2.4.4\" pydicom-seg\n",
+ "!python -m pip install -q \"pydicom==2.4.4\" pydicom-seg\n",
"\n",
"# Install the dependency manually to avoid installing opencv-python.\n",
- "!{sys.executable} -m pip install -q plotly bs4 unidecode\n",
- "!{sys.executable} -m pip install -q --no-deps rt-utils\n",
+ "!python -m pip install -q plotly bs4 unidecode\n",
+ "!python -m pip install -q --no-deps rt-utils\n",
"\n",
"# Install tcia_utils to download the datasets.\n",
- "!{sys.executable} -m pip install --upgrade -q --no-deps tcia_utils\n",
+ "!python -m pip install --upgrade -q --no-deps tcia_utils\n",
"\n",
"# This is the installation required for itkWidgets.\n",
- "!{sys.executable} -m pip install --upgrade -q \"itkwidgets[all]==1.0a53\" imjoy_elfinder\n",
- "\n"
+ "!python -m pip install --upgrade -q \"itkwidgets[all]==1.0a53\" imjoy_elfinder"
]
},
{
From 8592b7fbbc39a16dfa9fa3899d61f8c7a23afa6a Mon Sep 17 00:00:00 2001
From: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
Date: Thu, 10 Oct 2024 12:47:16 -0400
Subject: [PATCH 7/7] Update TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
Removing screenshots of viewers to see if that fixes pre-merge checks.
Signed-off-by: Justin Kirby <2379527+kirbyju@users.noreply.github.com>
---
...PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb | 158 +-----------------
1 file changed, 5 insertions(+), 153 deletions(-)
diff --git a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
index dc2c47ccfd..08d8746568 100644
--- a/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
+++ b/model_zoo/TCIA_PROSTATEx_Prostate_MRI_Anatomy_Model.ipynb
@@ -422,63 +422,7 @@
"id": "RF4LqDs-emJR",
"tags": []
},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- "
\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/javascript": [
- "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- ""
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"view(image=mr_image_prep, label_image=seg_image_prep)"
]
@@ -555,58 +499,12 @@
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": null,
"metadata": {
"id": "9bmgCBL9emJS",
"tags": []
},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- "
\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/javascript": [
- "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- ""
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
"# View the image with results overlaid in an interactive 2D slice viewer.\n",
"viewer_b = view(image=mr_image_prep, label_image=result_image_resampled)"
@@ -630,58 +528,12 @@
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": null,
"metadata": {
"id": "2wHOPVkWemJS",
"tags": []
},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- "
\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/javascript": [
- "window.connectPlugin && window.connectPlugin(\"f2c5a353-92e5-49ea-8f0a-4a5232883799\")"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- ""
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
"result_array = itk.GetArrayViewFromImage(result_image_resampled)\n",
"expert_array = itk.GetArrayViewFromImage(seg_image_prep)\n",