[Insight-users] Linear registration in SimpleITK

Zhongliu Xie zhongliu.xie10 at imperial.ac.uk
Mon Jan 13 07:19:13 EST 2014


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