--- a
+++ b/tutorials/UsingITK.md
@@ -0,0 +1,295 @@
+# Using C++ ITK code in Python
+
+The beauty of ANTsPy is the ease at which users can incorporate (i.e. wrap)
+their existing C++ code into Python while simultaneously leveraging the
+IO, visualization, and greater python inter-operability provided by ANTsPy.
+This short tutorial demonstrates how you can wrap your ITK C++ functions
+in 15 minutes or less.
+
+You'll notice how seamless the wrapping is between C++ and Python due to implicit
+casting of standard types by `pybind11` - making the process immensely smoother than
+an Rcpp equivalent, for instance.
+
+# Problem Definition
+
+I have a function that takes an ITK image and rescales the intensity.
+I want to use this function in Python, but don't want to go
+about 1) learning a new framework for wrapping my C++ code, 2) learning how
+to build ITK and my python code at the same time, 3) building an entire
+set of IO and plotting tools just for using my function.
+
+Here is my original code in a file called "rescaleImage.cxx":
+
+```cpp
+#include "itkImage.h"
+#include "itkRescaleIntensityImageFilter.h"
+
+template <typename ImageType>
+ImageType::Pointer rescaleAntsImage( typename ImageType::Pointer itkImage,
+                                     float outputMinimum, float outputMaximum )
+{
+    typedef itk::RescaleIntensityImageFilter< ImageType, ImageType > RescaleFilterType;
+    typename RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
+    rescaleFilter->SetInput( itkImage );
+    rescaleFilter->SetOutputMinimum( outputMinimum );
+    rescaleFilter->SetOutputMaximum( outputMaximum );
+
+    rescaleFilter->Update();
+    return rescaleFilter->GetOutput();
+}
+
+
+```
+
+# Problem Solution
+
+Starting from the pure C++ ITK function above, we will demonstrate the sequential steps
+needed to integrate this code into ANTsPy.
+
+The general steps are as follows:
+
+- alter function arguments & add a few headers
+- unwrap ANTsPy images & wrap ITK images
+- declare the c++ function with pybind11
+- build the function in CMakeLists.txt
+- optionally add an abstract python interface
+- re-build the ANTsPy package
+
+## Step 0. Build ANTsPy from source
+
+If you haven't already, build the ANTsPy package from source. A simple way to do this is the following:
+
+```bash
+git clone https://github.com/ANTsX/ANTsPy.git
+cd ANTsPy
+python setup.py develop
+```
+
+This step will generally take ~1 hour - during which time you can easily become an
+expert at integrating your C++ code into the ANTsPy package.
+
+## Step 1. Altering function arguments & Adding a few headers
+
+The first thing to do is to convert the Input and Output argument types from `ImageType::Pointer` to
+`py::capsule`. Py::capsules are containers which hold the underlying ITK smartpointer and let
+us pass them around in Python. This needs to be done _ONLY_ for input and output arguments.
+
+We also need to add in our pybind11 headers which let us implicitly cast between C++
+
+```cpp
+#include <pybind11/pybind11.h> // header for wrapping code
+#include <pybind11/stl.h> // header for implicitly casting btwn python-cpp types
+
+#include "itkImage.h"
+#include "itkRescaleIntensityImageFilter.h"
+
+namespace py = pybind11; // needed to use "py:"
+
+ttemplate <typename ImageType>
+py::capsule rescaleAntsImage( py::capsule & antsImage,
+                              float outputMinimum, float outputMaximum )
+{
+    typedef itk::RescaleIntensityImageFilter< ImageType, ImageType > RescaleFilterType;
+    typename RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
+    rescaleFilter->SetInput( itkImage );
+    rescaleFilter->SetOutputMinimum( outputMinimum );
+    rescaleFilter->SetOutputMaximum( outputMaximum );
+
+    rescaleFilter->Update();
+    return rescaleFilter->GetOutput();
+}
+
+```
+
+## Step 2. Unwrapping ANTs images & Wrapping ITK images
+
+Now, since we are passing in py::capsule types, we have to add the simple functions for
+converting py::capsules to ITK smartpointers and vice-versa. NOTE how we
+add another header `LOCAL_antsImage.h` for doing this.
+
+```cpp
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+#include "itkImage.h"
+#include "itkRescaleIntensityImageFilter.h"
+
+// NEED THIS INCLUDE FOR WRAPPING/UNWRAPPING
+#include "LOCAL_antsImage.h"
+
+namespace py = pybind11;
+
+template <typename ImageType>
+py::capsule rescaleAntsImage( py::capsule & antsImage,
+                              float outputMinimum, float outputMaximum )
+{
+    // cast from py::capsule to ITK smartpointer (unwrapping)
+    typename ImageType::Pointer itkImage = as< ImageType >( antsImage );
+
+    typedef itk::RescaleIntensityImageFilter< ImageType, ImageType > RescaleFilterType;
+    typename RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
+    rescaleFilter->SetInput( itkImage );
+    rescaleFilter->SetOutputMinimum( outputMinimum );
+    rescaleFilter->SetOutputMaximum( outputMaximum );
+
+    rescaleFilter->Update();
+
+    // cast from ITK smartpointer to py::capsule (wrapping)
+    return wrap< ImageType >( rescaleFilter->GetOutput() );
+}
+
+```
+
+## Step 3. Declaring your function for Python
+
+Now, in the file, we need to declare the function for `pybind11` to wrap it in python.
+This is a simple process, but can be tedious since every image type needs to be declared
+explicitly. However, this tediousness caused by template usage leads to cleaner code
+and better maintainability in the long run.
+
+After declaring your function, your code will look like this (see bottom):
+
+```cpp
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+#include "itkImage.h"
+#include "itkRescaleIntensityImageFilter.h"
+
+// NEED THIS INCLUDE FOR WRAPPING/UNWRAPPING
+#include "LOCAL_antsImage.h"
+
+// NEED THIS FOR PYBIND11
+namespace py = pybind11;
+
+template <typename ImageType>
+py::capsule rescaleAntsImage( py::capsule & antsImage,
+                              float outputMinimum, float outputMaximum )
+{
+    typename ImageType::Pointer itkImage = as< ImageType >( antsImage );
+
+    typedef itk::RescaleIntensityImageFilter< ImageType, ImageType > RescaleFilterType;
+    typename RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
+    rescaleFilter->SetInput( itkImage );
+    rescaleFilter->SetOutputMinimum( outputMinimum );
+    rescaleFilter->SetOutputMaximum( outputMaximum );
+
+    rescaleFilter->Update();
+    return wrap< ImageType >( rescaleFilter->GetOutput() );
+}
+
+
+// DECLARE OUR FUNCTION FOR APPROPRIATE TYPES
+PYBIND11_MODULE(rescaleImageModule, m)
+{
+    m.def("rescaleImageF2", &rescaleAntsImage<itk::Image<float,2>>);
+    m.def("rescaleImageF3", &rescaleAntsImage<itk::Image<float,3>>);
+}
+```
+
+The wrap declaration process is second nature after a while. Notice how
+we named our module `rescaleImageModule` - this is what our python module will also be called.
+You can also see how I named the functions based on the type of input image. This will lead to
+TWO functions available in python - rescaleImageModule.rescaleImageF2 and rescaleImagemodule.rescaleImageF3.
+
+## Step 4. Building the function in CMakeLists.txt
+
+Next (almost done), we need to actually build our function during the build process by adding
+it to the CMakeLists.txt file in the `antspy/ants/lib/` directory. We only need to add two
+lines:
+
+```
+pybind11_add_module(rescaleImageModule rescaleImage.cxx)
+target_link_libraries(rescaleImageModule PRIVATE ${ITK_LIBRARIES})
+```
+
+Our module will now be built into a python-compatible shared object library when
+you run `python setup.py develop` or `python setup.py install`.
+
+The rest of the steps involve making sure our functions are imported into
+the package namespace - we need to import it in the `__init__.py` file found in the
+`antspy/ants/lib/` directory. Simply add this line:
+
+```python
+from .rescaleImageModule import *
+```
+
+## Step 5. Adding an abstract Python interface
+
+Now, we have full access to our C++ function in the python/ANTsPY namespace. We can use
+this function directly if we want, but for users it's better to have a small python
+interface. This is very easy to implement, and mostly involves argument checking and such.
+
+```python
+import ants
+
+def rescale_image(image, min_val, max_val):
+    """
+    Rescale the intensity of an ANTsImage to be between
+    min_val and max_val
+
+    Arguments
+    ---------
+    image : ANTsImage type
+        image to be scaled
+
+    min_val : float
+        min value for rescaling
+
+    max_val : float
+        max value for rescaling
+
+    Example
+    -------
+    >>> import ants
+    >>> img = ants.image_read(ants.get_data('r16'))
+    >>> img_rescaled = ants.rescale_image(img, 0., 1.)
+    >>> print(img.min(), img.max())
+    >>> print(img_rescaled.min(), img_rescaled.max())
+    """
+    image = image.clone('float')
+
+    # get function from its name
+    lib_fn = get_lib_fn('rescaleAntsImage%s' % (image._libsuffix))
+
+    # apply the function to my image
+    # remember this function returns a py::capsule
+    rescaled_img_ptr = lib_fn(image.pointer, min_val, max_val)
+
+    # wrap the py::capsule back in ANTsImage class
+    rescaled_img = ants.from_pointer(rescaled_img_ptr)
+    return rescaled_img
+```
+
+We also need to import this function in the ANTsPy namespace. If we put the above
+python code in a file called `rescale_image.py` in the `antspy/ants/utils/` directory,
+then we would add the following line to the `__init__.py` file in the
+`antspy/ants/utils/` directory:
+
+```python
+from .rescale_image import *
+```
+
+## Step 6. Rebuild ANTsPy
+
+Finally, we rebuild the ANTsPy package by going to the main directory and running setup.py again:
+
+```
+python setup.py develop
+```
+
+This should be very quick if you've built ANTsPy before, since only the altered C++ code
+will need to be rebuilt.
+
+Now we can use this function quite easily:
+
+```python
+import ants
+img = ants.image_read(ants.get_data('r16'))
+rescaled_img = ants.rescale_image(img, 0., 1.) # rescale between 0 and 1
+```
+
+---
+
+And that's it - a painless 15 minute process that gives you access to all of the ANTsPy functionality
+such as IO, visualization, numpy-conversion, etc.