The R notebooks follow the general structure of the python equivalents.
A few comments to get started:
Let's start by creating an image and accessing information about it.
In [ ]:
# Load the SimpleITK library
library(SimpleITK)
imA = Image(256, 128, 64, "sitkInt16")
imB = SimpleITK::Image(64, 64, "sitkFloat32")
imC = Image(c(32, 32), "sitkUInt32")
imRGB = Image(c(128,128), "sitkVectorUInt8", 3)
We've created 3 different (empty) images using slightly differeing syntax to specify the dimensions. We've also specified the pixel type. The range of available pixel types is:
In [ ]:
get(".__E___itk__simple__PixelIDValueEnum", pos="package:SimpleITK")
It isn't usually necessary to access the enumeration classes directly, but it can be handy to know how when debugging.
Lets start querying the images we've created. The $
operator is used to access object methods:
In [ ]:
imA$GetSize()
imC$GetSpacing()
We can change the spacing (voxel size):
In [ ]:
imC$SetSpacing(c(2, 0.25))
imC$GetSpacing()
There are shortcuts for accessing a single dimension:
In [ ]:
imC$GetWidth()
imA$GetHeight()
imA$GetDepth()
imC$GetDepth()
The depth refers to the z dimension. A colour or vector image has an additional "dimension":
In [ ]:
imRGB$GetNumberOfComponentsPerPixel()
The list of available methods can be retrieved using the following. There are many functions for accessing pixels in a type dependent way, which don't need to be accessed directly.
In [ ]:
getMethod('$', class(imA))
R, like python and matlab, has a flexible notation for accessing elements of arrays. SimpleITK adopts the same notation for accessing pixels (or sub images, which will be covered in a subsequent notebook). First, lets get set up so that we can display an image in the notebook.
In [ ]:
# override show function
# The example below will respect image voxel sizes
## This is a hack to allow global setting of the displayed image width
Dwidth <- grid::unit(10, "cm")
setMethod('show', '_p_itk__simple__Image',
function(object)
{
a <- t(as.array(object))
rg <- range(a)
A <- (a-rg[1])/(rg[2]-rg[1])
dd <- dim(a)
sp <- object$GetSpacing()
sz <- object$GetSize()
worlddim <- sp*sz
worlddim <- worlddim/worlddim[1]
W <- Dwidth
H <- Dwidth * worlddim[2]
grid::grid.raster(A,default.units="mm", width=W, height=H)
}
)
options(repr.plot.height = 5, repr.plot.width=5)
Typing the name of an image variable will now result in the image being displayed using an R graphics device. Lets load up an image from the package and test:
Now we source the code to allow us to fetch images used in examples. This code will download the images if they aren't already on the system.
In [ ]:
source("downloaddata.R")
In [ ]:
cthead <- ReadImage(fetch_data("cthead1.png"))
cthead
Now we will check the value of a single pixel:
In [ ]:
cthead[146, 45]
The rule for index ordering in R/SimpleITK is most rapidly changing index first. For images this is x (horizontal), then y (vertical), then z. For R arrays this is row, then column. The conversion between images and arrays maintains the ordering of speed of index change, so the most rapidly changing index is always the first element:
In [ ]:
imA$GetSize()
imA.arr <- as.array(imA)
dim(imA.arr)
The array and image dimensions are the same, however if they are displayed they are likely to appear different as R interprets the first index as rows. Also note that traditional graphing tools are likely to interpret vertical direction differently: For example, lets plot the cthead image - the result is flipped vertically, because the graph origin is bottom left, and rows and columns are swapped. The show method we use in this notebook has a transpose operation to reverse the row/column swap.
In [ ]:
image(as.array(cthead))
In [ ]: