[Insight-users] Linear registration in SimpleITK

Bradley Lowekamp blowekamp at mail.nih.gov
Mon Jan 13 10:35:57 EST 2014


Hello,

Currently, in the master branch there is not registration framework.

However there is a prototype I have develop which will be integrated in the coming months:
https://github.com/blowekamp/SimpleITK/tree/STRAW

Additionally there are some IPython Notebooks which demonstrate the usage:
http://nbviewer.ipython.org/github/SimpleITK/SimpleITK-Notebooks/blob/STRAW/STRAW_Registration.ipynb

If you are feeling adventurous you can download the branch above and compile the experimental topic in SimpleITK for CSharp yourself.

Also any feed back on the interface would be appreciated.

Thanks,
Brad

On Jan 13, 2014, at 7:19 AM, Zhongliu Xie <zhongliu.xie10 at imperial.ac.uk> wrote:

> Dear Brad, Dan and fellow Simple ITK users,
> 
> Another problem from me here is that I need to linearly register a 3D MRI brain image to another, and I have checked through the Simple ITK docs but have not been able to find a filter or method that does registration. Can someone give a clue? Thanks.
> 
> FYI, C# environment
> 
> Regards,
> Zhongliu
> 
> On 12/01/2014 21:53, Zhongliu Xie wrote:
>> Many thanks for the help of you both.
>> 
>> Regards,
>> Zhongliu
>> 
>> On 12/01/2014 21:47, Dan Mueller wrote:
>>> Hi Zhongliu,
>>> 
>>> Further to Brad's email, please find below an example SimpleITK C#
>>> program demonstrating how to access the pixel buffer of a 2D floating
>>> point image.
>>> 
>>> To answer your other question: the "c" stands for component (or
>>> channel). For a multi-component image (such as a RGB image) each
>>> component/channel (e.g. red channel, green channel, blue channel) must
>>> also be accessed in the 1-d array.
>>> 
>>> HTH
>>> 
>>> Cheers, Dan
>>> 
>>> using System;
>>> using System.Runtime.InteropServices;
>>> 
>>> using itk.simple;
>>> using PixelId = itk.simple.PixelIDValueEnum;
>>> 
>>> namespace TestSimpleITK {
>>> public class Program {
>>> static void Main(string[] args) {
>>> 
>>>     var input = SimpleITK.ReadImage("C:/Temp/cthead1.png"); // UC2 =
>>> unsigned char, 2d
>>>     input = SimpleITK.Cast(input, PixelId.sitkFloat32);
>>>     var size = input.GetSize();
>>>     int len = 1;
>>>     for (int dim = 0; dim < input.GetDimension(); dim++) {
>>>         len *= (int)size[dim];
>>>     }
>>>     IntPtr buffer = input.GetBufferAsFloat();
>>> 
>>>     // There are two ways to access the buffer:
>>> 
>>>     // (1) Access the underlying buffer as a pointer in an "unsafe" block
>>>     // (note that in C# "unsafe" simply means that the compiler can not
>>>     // perform full type checking)
>>>     unsafe {
>>>         float* bufferPtr = (float*)buffer.ToPointer();
>>> 
>>>         // Now the byte pointer can be accessed as per Brad's email
>>>         // (of course this example is only a 2d single channel image):
>>>         // This is a 1-D array but can be access as a 3-D. Given an
>>>         // image of size [xS,yS,zS], you can access the image at
>>>         // index [x,y,z] as you wish by image[x+y*xS+z*xS*yS],
>>>         // so x is the fastest axis and z is the slowest.
>>>         for (int j = 0; j < size[1]; j++) {
>>>             for (int i = 0; i < size[0]; i++) {
>>>                 float pixel = bufferPtr[i + j*size[1]];
>>>                 // Do something with pixel here
>>>             }
>>>         }
>>>     }
>>> 
>>>     // (2) Copy the buffer to a "safe" array (i.e. a fully typed array)
>>>     // (note that this means memory is duplicated)
>>>     var bufferAsArray = new float[len]; // Allocates new memory the
>>> size of input
>>>     Marshal.Copy(source: buffer, destination: bufferAsArray,
>>> startIndex: 0, length: len);
>>>     for (int j = 0; j < size[1]; j++) {
>>>         for (int i = 0; i < size[0]; i++) {
>>>             float pixel = bufferAsArray[i + j*size[1]];
>>>             // Do something with pixel here
>>>         }
>>>     }
>>> 
>>> }
>>> }
>>> }
>>> 
>>> On 13 January 2014 06:54, Zhongliu Xie <zhongliu.xie10 at imperial.ac.uk> wrote:
>>>> Dear Brad,
>>>> 
>>>> Thanks for your reply. Yet the method image.GetBufferAsFloat() returns an
>>>> IntPtr, how do I convert it to float[] then? Also, in the SimpleITK docs it
>>>> says:
>>>> uint8_t *buffer = img->GetBufferAsUInt8();
>>>> buffer[c + numComponents*(x+ xSize* (y*+ySize*z))]
>>>> what is c in this case?
>>>> 
>>>> Regards,
>>>> Zhongliu
>>>> 
>>>> 
>>>> 
>>>> On 12/01/2014 20:07, Bradley Lowekamp wrote:
>>>> 
>>>> Hello,
>>>> 
>>>> Available only in C++ and C#, are a set of methods which being as
>>>> "GetBufferAs":
>>>> 
>>>> itk::simple::Image::GetBufferAsInt8;
>>>> itk::simple::Image::GetBufferAsUInt8;
>>>> itk::simple::Image::GetBufferAsInt16;
>>>> itk::simple::Image::GetBufferAsUInt16;
>>>> itk::simple::Image::GetBufferAsInt32;
>>>> itk::simple::Image::GetBufferAsUInt32;
>>>> itk::simple::Image::GetBufferAsInt64;
>>>> itk::simple::Image::GetBufferAsUInt64;
>>>> itk::simple::Image::GetBufferAsFloat;
>>>> itk::simple::Image::GetBufferAsDouble;
>>>> 
>>>> These return a pointer or array to the image buffer that you are looking
>>>> for. The correctly typed method mush be call, or else an exception will be
>>>> thrown. The array returned has not line padding, and a SimpleITK image
>>>> always begins with an index of [0,0,0].
>>>> 
>>>> This is a 1-D array but can be access as a 3-D. Given an image of size
>>>> [xS,yS,zS], you can access the image at index [x,y,z] as you wish by
>>>> image[x+y*xS+z*xS*yS], so x is the fastest axis and z is the slowest.
>>>> 
>>>> Brad
>>>> 
>>>> 
>>>> On Jan 12, 2014, at 1:35 PM, Zhongliu Xie <zhongliu.xie10 at imperial.ac.uk>
>>>> wrote:
>>>> 
>>>> Dear fellow ITK users,
>>>> 
>>>> Recently I have been using Simple ITK under C# environment. I wonder whether
>>>> there is a way to quickly convert an image into an array of intensities
>>>> (leaving out the meta info)? In particular, is it possible to directly
>>>> convert to a multidimensional array such as intensity[x,y,z] (or
>>>> intensity[x][y][z] in C++) indicating the intensity of voxel at <x,y,z>?
>>>> 
>>>> BTW, I also noticed there is something called Buffer which seems related.
>>>> Could someone explain what  buffer is more explicitly so that I can make
>>>> sure I understand it correctly?
>>>> 
>>>> Thanks in advance,
>>>> Zhongliu
>>>> _____



More information about the Insight-users mailing list