[ITK Community] [Insight-users] Convert image to (multi-dimensional) array in SimpleITK
Dan Mueller
dan.muel at gmail.com
Sun Jan 12 16:47:22 EST 2014
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
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.php
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>
>
>
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.php
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>
_____________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php
Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ
Follow this link to subscribe/unsubscribe:
http://www.itk.org/mailman/listinfo/insight-users
More information about the Community
mailing list