[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