[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
>


More information about the Insight-users mailing list