{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. 3D Image Registration with Masks" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Registration" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often, some content in the images may not correspond. For example, there may be background content or noisy areas. A mask defined on the fixed and/or moving image can be used to exclude these regions at a pixel level from the similarity metric computations. This improves the robustness of registration.\n", "\n", "A mask is a binary image with 1 meaning that a pixel is include in elastix' computation and a 0 meaning it's not.\n", "\n", "For more information, see Section 5.4, \"Masks\" of the [Elastix Manual](https://elastix.lumc.nl/download/elastix-5.0.1-manual.pdf)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import itk\n", "from itkwidgets import compare, checkerboard, view" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function calls in the 3D case to import and register the images is similar to the 2D case. Masks, usually binary images, are import with the itk library similar to the images. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# Import Images\n", "fixed_image = itk.imread('data/CT_3D_lung_fixed.mha', itk.F)\n", "moving_image = itk.imread('data/CT_3D_lung_moving.mha', itk.F)\n", "\n", "# Import Custom Parameter Map\n", "parameter_object = itk.ParameterObject.New()\n", "parameter_object.AddParameterFile('data/parameters.3D.NC.affine.ASGD.001.txt')\n", "\n", "# \"WriteResultImage\" needs to be set to \"true\" so that the image is resampled at the end of the registration\n", "# and the result_image is populated properly\n", "parameter_object.SetParameter(0, \"WriteResultImage\", \"true\")\n", "\n", "# Import Mask Images\n", "fixed_mask = itk.imread('data/CT_3D_lung_fixed_mask.mha', itk.UC)\n", "moving_mask = itk.imread('data/CT_3D_lung_moving_mask.mha', itk.UC)\n", "\n", "# Or Optionally Create Masks from scratch\n", "\n", "# MaskImageType = itk.Image[itk.UC, 2]\n", "# fixed_mask = itk.binary_threshold_image_filter(fixed,\n", "# lower_threshold=80.0,\n", "# inside_value=1,\n", "# ttype=(type(fixed), MaskImageType))\n", "# moving_mask = itk.binary_threshold_image_filter(moving,\n", "# lower_threshold=80.0,\n", "# inside_value=1,\n", "# ttype=(type(moving), MaskImageType))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Input Visualization\n", "The images and their masks can be visualized with the itkwidget's view function. This can be useful to visually inspect the quality of the masks." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9e0ed89550c043a29bef90625e1cb58e", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Viewer(geometries=[], gradient_opacity=0.22, interpolation=False, point_sets=[], rendered_image=