|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "attachments": {}, |
| 5 | + "cell_type": "markdown", |
| 6 | + "metadata": {}, |
| 7 | + "source": [ |
| 8 | + "Copyright (c) MONAI Consortium \n", |
| 9 | + "Licensed under the Apache License, Version 2.0 (the \"License\"); \n", |
| 10 | + "you may not use this file except in compliance with the License. \n", |
| 11 | + "You may obtain a copy of the License at \n", |
| 12 | + " http://www.apache.org/licenses/LICENSE-2.0 \n", |
| 13 | + "Unless required by applicable law or agreed to in writing, software \n", |
| 14 | + "distributed under the License is distributed on an \"AS IS\" BASIS, \n", |
| 15 | + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n", |
| 16 | + "See the License for the specific language governing permissions and \n", |
| 17 | + "limitations under the License. \n", |
| 18 | + "\n", |
| 19 | + "# MONAI Label - Lung Nodule Detection - 3D Slicer Integration\n", |
| 20 | + "\n", |
| 21 | + "***The Detection Task Workflow in MONAI Label***\n", |
| 22 | + "\n", |
| 23 | + "In this notebook, we provide a monaibundle app usecase example with lung nodule detection. The first detection task that can be used within MONAI Label.\n", |
| 24 | + "\n", |
| 25 | + "3D Slicer as the client viewer, we show how MONAI Label workflow serves as interactive AI-Assisted tool for box-based ROI detection labeling.\n", |
| 26 | + "\n", |
| 27 | + "**Lung Nodule Detection Bundle:**\n", |
| 28 | + "\n", |
| 29 | + "This tutorial uses a Swin UNETR bundle for the task of multi-organ segmentation task. The architecture of Swin UNETR is demonstrated as below\n", |
| 30 | + "\n", |
| 31 | + "\n", |
| 32 | + "\n", |
| 33 | + "**Method:** Lung Nodule Detection Networks\n", |
| 34 | + "\n", |
| 35 | + "The workflow of lung nodule detection with CT scans is from RetinaNet (Lin, Tsung-Yi, et al. \"Focal loss for dense object detection.\" ICCV 2017. https://arxiv.org/abs/1708.02002).\n", |
| 36 | + "\n", |
| 37 | + "" |
| 38 | + ] |
| 39 | + }, |
| 40 | + { |
| 41 | + "attachments": {}, |
| 42 | + "cell_type": "markdown", |
| 43 | + "metadata": {}, |
| 44 | + "source": [ |
| 45 | + "## Setup environment\n", |
| 46 | + "\n", |
| 47 | + "MONAI Label is pre-built within the MONAI Toolkit. Download monaibundle app\n", |
| 48 | + "\n", |
| 49 | + "### Prerequisites\n", |
| 50 | + "- **Install MONAI Label**" |
| 51 | + ] |
| 52 | + }, |
| 53 | + { |
| 54 | + "cell_type": "code", |
| 55 | + "execution_count": null, |
| 56 | + "metadata": {}, |
| 57 | + "outputs": [], |
| 58 | + "source": [ |
| 59 | + "!pip install monailabel-weekly" |
| 60 | + ] |
| 61 | + }, |
| 62 | + { |
| 63 | + "cell_type": "markdown", |
| 64 | + "metadata": {}, |
| 65 | + "source": [ |
| 66 | + "- **Get latest MONAI Label Slicer plugin** (Optional)\n", |
| 67 | + "\n", |
| 68 | + "If you are using older release of 3D Slicer MONAI Label plugin, you can update to the latest plugin which supports ***drawing ROI nodes from MONAI Label server prediction***.\n", |
| 69 | + "\n", |
| 70 | + "Or to use the developer mode of MONAI Label plugin by:\n", |
| 71 | + "\n", |
| 72 | + " - Pull latest MONAI Label repo:\n", |
| 73 | + " ```bash\n", |
| 74 | + " git clone https://github.com/Project-MONAI/MONAILabel.git\n", |
| 75 | + " ```\n", |
| 76 | + " - Go to `MONAILabel/plugins/slicer/`\n", |
| 77 | + " - Follow the Readme page to use developer mode of Slicer plugin.\n", |
| 78 | + " https://github.com/Project-MONAI/MONAILabel/tree/main/plugins/slicer#install-plugin-in-developer-mode\n", |
| 79 | + " - Install Plugin in Developer Mode\n", |
| 80 | + " - Open 3D Slicer: Go to Edit -> Application Settings -> Modules -> Additional Module Paths\n", |
| 81 | + " - Add New Module Path: <FULL_PATH>/plugins/slicer/MONAILabel\n", |
| 82 | + " - Restart 3D Slicer\n", |
| 83 | + " " |
| 84 | + ] |
| 85 | + }, |
| 86 | + { |
| 87 | + "cell_type": "markdown", |
| 88 | + "metadata": {}, |
| 89 | + "source": [ |
| 90 | + "### 1.1 Download monaibundle app\n", |
| 91 | + "Sample-app with built-in versions are in the Toolkit, pull the monaibundle app using monailabel API " |
| 92 | + ] |
| 93 | + }, |
| 94 | + { |
| 95 | + "cell_type": "code", |
| 96 | + "execution_count": 2, |
| 97 | + "metadata": {}, |
| 98 | + "outputs": [ |
| 99 | + { |
| 100 | + "name": "stdout", |
| 101 | + "output_type": "stream", |
| 102 | + "text": [ |
| 103 | + "Using PYTHONPATH=/home/yucheng:\n", |
| 104 | + "\n", |
| 105 | + "monaibundle is copied at: /home/yucheng/yucheng/2023/detection_totalsegment_tutorial/tutorials/monailabel/apps/monaibundle\n" |
| 106 | + ] |
| 107 | + } |
| 108 | + ], |
| 109 | + "source": [ |
| 110 | + "!monailabel apps --download --name monaibundle --output apps" |
| 111 | + ] |
| 112 | + }, |
| 113 | + { |
| 114 | + "attachments": {}, |
| 115 | + "cell_type": "markdown", |
| 116 | + "metadata": {}, |
| 117 | + "source": [ |
| 118 | + "### 1.2 Download sample data\n", |
| 119 | + "The lung nodule detection model is trained and evaluated using [LUNA16](https://luna16.grand-challenge.org/Home/) dataset.\n", |
| 120 | + "\n", |
| 121 | + "LUNA16 is a public dataset of CT lung nodule detection. Using raw CT scans, the goal is to identify locations of possible nodules and to assign a probability for being a nodule to each location.\n", |
| 122 | + "\n", |
| 123 | + "Disclaimer: We are not the host of the data. Please make sure to read the requirements and usage policies of the data and give credit to the authors of the dataset! We acknowledge the National Cancer Institute and the Foundation for the National Institutes of Health, and their critical role in the creation of the free publicly available LIDC/IDRI Database used in this study.\n", |
| 124 | + "\n", |
| 125 | + " - If you are going to use full dataset of LUNA16, please refer to the dataset link, download the data, create and preprocess the images following [this page]( https://github.com/Project-MONAI/model-zoo/tree/dev/models/lung_nodule_ct_detection#data \n", |
| 126 | + ").\n", |
| 127 | + " \n", |
| 128 | + " - In this tutorial, we prepared a sample subset, resampled and ready to use. The subset is only for demonstration. Download [here](https://github.com/Project-MONAI/MONAILabel/releases/download/data/detection_dataset.zip).\n", |
| 129 | + " \n", |
| 130 | + " Or use these commands to download and extract directly.\n", |
| 131 | + "\n", |
| 132 | + "```bash\n", |
| 133 | + "mkdir datasets\n", |
| 134 | + "wget \"https://github.com/Project-MONAI/MONAILabel/releases/download/data/detection_dataset.zip\" -O datasets/detection_dataset.zip\n", |
| 135 | + "unzip datasets/detection_dataset.zip -d datasets/detection_dataset\n", |
| 136 | + "```\n", |
| 137 | + " \n", |
| 138 | + " - The detection model also supports MSD Task06_Lung dataset for inference. Note this dataset is created for nodule segmentation task. We do not use the segmentation mask, only the images for inference. Use following monailabel API to automatically download the dataset." |
| 139 | + ] |
| 140 | + }, |
| 141 | + { |
| 142 | + "cell_type": "code", |
| 143 | + "execution_count": null, |
| 144 | + "metadata": {}, |
| 145 | + "outputs": [], |
| 146 | + "source": [ |
| 147 | + "!monailabel datasets --download --name Task06_Lung --output datasets" |
| 148 | + ] |
| 149 | + }, |
| 150 | + { |
| 151 | + "cell_type": "markdown", |
| 152 | + "metadata": {}, |
| 153 | + "source": [ |
| 154 | + "### 1.3 Starting MONAI Label Server\n", |
| 155 | + "\n", |
| 156 | + "Specify the bundle name in --conf models <BUNDLENAME> argument. For example: lung_nodule_ct_detection\n", |
| 157 | + " \n", |
| 158 | + " ```--conf auth_token <Github Auth Token>```" |
| 159 | + ] |
| 160 | + }, |
| 161 | + { |
| 162 | + "cell_type": "code", |
| 163 | + "execution_count": null, |
| 164 | + "metadata": {}, |
| 165 | + "outputs": [], |
| 166 | + "source": [ |
| 167 | + "!monailabel start_server --app apps/monaibundle --studies datasets/Task06_Lung/imagesTr --conf models lung_nodule_ct_detection --conf auth_token <Github Auth Token>" |
| 168 | + ] |
| 169 | + }, |
| 170 | + { |
| 171 | + "cell_type": "markdown", |
| 172 | + "metadata": {}, |
| 173 | + "source": [ |
| 174 | + "### 1.4 (Optional) Modify Detection Parameters in the Bundle\n", |
| 175 | + "\n", |
| 176 | + "The lung_nodule_ct_detection bundle can set box prediction probability threshold. In `apps/monaibundle/model/lung_nodule_ct_detection_v0.5.0/configs/inference.json`, it's define here `score_thresh=0.02`: \n", |
| 177 | + "\n", |
| 178 | + "```json\n", |
| 179 | + " \"detector_ops\": [\n", |
| 180 | + " \"[email protected]_target_keys(box_key='box', label_key='label')\",\n", |
| 181 | + " \"[email protected]_box_selector_parameters(score_thresh=0.02,topk_candidates_per_level=1000,nms_thresh=0.22,detections_per_img=300)\",\n", |
| 182 | + " \"[email protected]_sliding_window_inferer(roi_size=@infer_patch_size,overlap=0.25,sw_batch_size=1,mode='constant',device='cpu')\"\n", |
| 183 | + " ],\n", |
| 184 | + "\n", |
| 185 | + "```\n", |
| 186 | + "\n", |
| 187 | + "This parameter will impact the number of boxes in the final prediction output. Then show all boxes ROIs in 3D Slicer.\n", |
| 188 | + "\n", |
| 189 | + "If users want to limit the number of predicted boxes showing on 3D Slicer, users can set higher `score_thresh`, e.g., `score_thresh=0.5`, `score_thresh=0.6`, or even higher. " |
| 190 | + ] |
| 191 | + }, |
| 192 | + { |
| 193 | + "attachments": {}, |
| 194 | + "cell_type": "markdown", |
| 195 | + "metadata": {}, |
| 196 | + "source": [ |
| 197 | + "## 2. Auto Box Detection with 3D Slicer\n", |
| 198 | + "\n", |
| 199 | + "Below is a step-by-step tutorial on using 3D Slicer for auto lung nodule detection. Pre-trained model is provided by the bundle and loaded by MONAI Label server.\n", |
| 200 | + "\n", |
| 201 | + "\n", |
| 202 | + "**Start 3D Slicer and MONAI Label Plugin**: the tutorial starts with monaibundle app in the 3D Slicer, please refer to the [\"Hello World\" tutorial](monailabel_radiology_3dslicer.ipynb) for detailed instructions on installing 3D Slicer and MONAI Label plugin.\n", |
| 203 | + "\n", |
| 204 | + "**Important**: If your MONAI Label plugin is from older release, please refer to [Prerequisites](#Prerequisites) in this notebook to update and use latest MONAI Label plugin. The detection task needs to draw ROI nodes to 3D Slicer markups.\n", |
| 205 | + "\n", |
| 206 | + "### 2.1 Select Model and Fetch Data\n", |
| 207 | + "\n", |
| 208 | + "- Select the bundle model loaded with MONAI Label server, **lung_nodule_ct_detection** in this tutorial. Start MONAI Label server will automatically download the bundle from model-zoo.\n", |
| 209 | + "\n", |
| 210 | + "\n", |
| 211 | + "click **next sample** to load image data from datastore.\n", |
| 212 | + "\n", |
| 213 | + "\n", |
| 214 | + "\n", |
| 215 | + "\n", |
| 216 | + "### 2.2 Run Auto Inference\n", |
| 217 | + "\n", |
| 218 | + "- MONAI Label has loaded the pre-trained weights within the bundle for multi-organ segmentation task, click **run** to do inference on the currently loaded data. \n", |
| 219 | + "\n", |
| 220 | + "- Note: the pre-trained models are in the bundle's \"**models**\" folder. For instance, in this usecase, a downloaded pre-trained model is saved at \"**apps/monaibundle/model/lung_nodule_ct_detection/models/model.pt**\".\n", |
| 221 | + "\n", |
| 222 | + "- Note: the detection model uses RetinaNet, please reserve at least ~12G memory for inference and training, modify the bundle config file if out of memory.\n", |
| 223 | + "\n", |
| 224 | + "Users can monitor the logs in the MONAI Label server terminal\n", |
| 225 | + "\n", |
| 226 | + "\n", |
| 227 | + "\n", |
| 228 | + "\n", |
| 229 | + "### 2.3 Edit Annotations and Submit Label\n", |
| 230 | + "\n", |
| 231 | + "- Users can edit the inference labels manually using 3D Slicer ROI box Editor, click the **Markups** tab on the top, the tools for adjusting ROIs. Once done annotation, users can go back to MONAI Label plugin and click **Submit Label** to save the ground truth label to the file system.\n", |
| 232 | + "\n", |
| 233 | + "- Note: the final annotations will be saved to \"**labels/final**\" folder in the study dataset, for example, in this usecase, the ground truth label will be saved to \"**datasets/Task06_Lung/imagesTr/labels/final**\"\n", |
| 234 | + "\n", |
| 235 | + "- The saved annotation will be in JSON file with the 3D Slicer ROINode format. It can be loaded with 3D Slicer.\n", |
| 236 | + "\n", |
| 237 | + "\n" |
| 238 | + ] |
| 239 | + }, |
| 240 | + { |
| 241 | + "attachments": {}, |
| 242 | + "cell_type": "markdown", |
| 243 | + "metadata": {}, |
| 244 | + "source": [ |
| 245 | + "## 3. Active Learning with 3D Slicer\n", |
| 246 | + "\n", |
| 247 | + "Active learning and interactive fine-tuning models have highlighted features in MONAI Label, users can train their models anytime when new annotated labels are saved. Click **Train** button, MONAI Label server will fetch the saved final ground truth label and fine-tune the prior model. \n", |
| 248 | + "\n", |
| 249 | + "- Sample of annotated box coordinate in JSON file. \n", |
| 250 | + "\n", |
| 251 | + "\n", |
| 252 | + "\n", |
| 253 | + "\n", |
| 254 | + "Users can monitor the logs in the MONAI Label server terminal\n", |
| 255 | + "\n", |
| 256 | + "- The ROINode box annotation will be converted to the model-compatible ground truth label automatically.\n", |
| 257 | + "\n", |
| 258 | + "\n", |
| 259 | + "\n", |
| 260 | + "Same to the Radiology app, users can do auto segmentation using the latest fine-tuned model. \n", |
| 261 | + "The active learning process will select unlabeled batch data.\n", |
| 262 | + "\n", |
| 263 | + "The next image is selected, already trained images will be marked as labeled data, then won't be selected for the next labeling batch. Active learning strategies such as \"first/random\" will be used for selecting which unlabeled data to fetch. \n", |
| 264 | + "\n" |
| 265 | + ] |
| 266 | + }, |
| 267 | + { |
| 268 | + "attachments": {}, |
| 269 | + "cell_type": "markdown", |
| 270 | + "metadata": {}, |
| 271 | + "source": [ |
| 272 | + "## 4. Repeat Until All Data are Annotated and Trained \n", |
| 273 | + "\n", |
| 274 | + "Repeated fetch data and active learning process to section 2.2, until all unlabeled data are annotated and trained. \n", |
| 275 | + "\n", |
| 276 | + "For each training loop, the new best metric model will be saved in \"**model/model.pt**\", in this usecase, \"**apps/monaibundle/lung_nodule_ct_detection/model/model.pt**\" is saved." |
| 277 | + ] |
| 278 | + }, |
| 279 | + { |
| 280 | + "cell_type": "markdown", |
| 281 | + "metadata": {}, |
| 282 | + "source": [ |
| 283 | + "## 5. Conclusion\n", |
| 284 | + "\n", |
| 285 | + "This tutorial demonstrates MONAI Label usage with monaibundle app, the lung nodule ct detection task is introduced. Active learning process, auto inference, detection editor, submit labels, and save models are included with the bundle. The monaibundle app highlights the robust model deployment for MONAI Label." |
| 286 | + ] |
| 287 | + } |
| 288 | + ], |
| 289 | + "metadata": { |
| 290 | + "kernelspec": { |
| 291 | + "display_name": "Python 3 (ipykernel)", |
| 292 | + "language": "python", |
| 293 | + "name": "python3" |
| 294 | + }, |
| 295 | + "language_info": { |
| 296 | + "codemirror_mode": { |
| 297 | + "name": "ipython", |
| 298 | + "version": 3 |
| 299 | + }, |
| 300 | + "file_extension": ".py", |
| 301 | + "mimetype": "text/x-python", |
| 302 | + "name": "python", |
| 303 | + "nbconvert_exporter": "python", |
| 304 | + "pygments_lexer": "ipython3", |
| 305 | + "version": "3.8.10" |
| 306 | + }, |
| 307 | + "vscode": { |
| 308 | + "interpreter": { |
| 309 | + "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" |
| 310 | + } |
| 311 | + } |
| 312 | + }, |
| 313 | + "nbformat": 4, |
| 314 | + "nbformat_minor": 4 |
| 315 | +} |
0 commit comments