[Insight-users] Grafting a C++ array onto a VectorImage filter output

Ramón Casero Cañas rcasero at gmail.com
Mon Jun 18 13:04:38 EDT 2012


On 04/06/12 13:47, Ramón Casero Cañas wrote:
>
> But how can this be done if the output of the filter is a VectorImage,
> e.g. the third output of the DanielssonDistanceMapImageFilter?


Hi all,

After some tinkering I figured out how to graft an 
itk::ImageToImageFilter output where each voxel corresponds to a vector 
onto a Matlab buffer. I'm reporting the result here, in case it's useful 
for somebody else.

Here's an example for the case where we have a (100, 120, 200)-image, 
and we want to graft the 3rd output of the 
DanielssonDistanceMapImageFilter. This output has type OffsetType, which 
is a 3-vector of OffsetValueType (int64 in a 64-bit architecture).

// map the ITK type of each element inside the vector to the
// corresponding Matlab type (i.e. OutputType==OffsetValueType==int64)
   mxClassID outputVoxelClassId = mxUNKNOWN_CLASS;
   if (TypeIsBool<OutputType>::value) {
     outputVoxelClassId = mxLOGICAL_CLASS;
   } else if (TypeIsUint8<OutputType>::value) {
     outputVoxelClassId = mxUINT8_CLASS;
   } else if (TypeIsInt8<OutputType>::value) {
     outputVoxelClassId = mxINT8_CLASS;
   } else if (TypeIsUint16<OutputType>::value) {
     outputVoxelClassId = mxUINT16_CLASS;
   } else if (TypeIsInt16<OutputType>::value) {
     outputVoxelClassId = mxINT16_CLASS;
   } else if (TypeIsInt32<OutputType>::value) {
     outputVoxelClassId = mxINT32_CLASS;
   } else if (TypeIsInt64<OutputType>::value) {
     outputVoxelClassId = mxINT64_CLASS;
     // a signed long can be 32- or 64-bit depending on the
     // architecture. 64-bit is the safest option
   } else if (TypeIsSignedLong<OutputType>::value) {
     outputVoxelClassId = mxINT64_CLASS;
   } else if (TypeIsFloat<OutputType>::value) {
     outputVoxelClassId = mxSINGLE_CLASS;
   } else if (TypeIsDouble<OutputType>::value) {
     outputVoxelClassId = mxDOUBLE_CLASS;
   } else {
     mexErrMsgTxt("Assertion fail: Unrecognised output data type");
   }

// increase the number of dimensions for the Matlab buffer
mwSize ndim = 3+1;

// the vector length will be in the first dimension
dims[4] = {3, 100, 120, 200};

// allocate memory in Matlab for the 3rd ouput
plhs[2] = (mxArray *)mxCreateNumericArray(ndim, dims, 		 
outputVoxelClassId, mxREAL);

// pointer to the Matlab output buffer (note that from here on, the
// type we use is OffsetType instead of OffsetValueType)
OffsetType *imOutp =  (OffsetType *)mxGetData(this->argOut[idx]);

// impersonate the data buffer in the filter with the Matlab output
// buffer
typedef typename itk::Image<OffsetType, Dimension> OutputImageType;
OutputImageType *pOutput =
   dynamic_cast<OutputImageType 
*>(this->filter->GetOutputs()[idx].GetPointer());
   const bool filterWillDeleteTheBuffer = false;
   pOutput->GetPixelContainer()->SetImportPointer(imOutp,						 
mxGetNumberOfElements(this->nrrd.getData()),
filterWillDeleteTheBuffer);


Best regards,

ramon.

-- 
Dr. Ramón Casero Cañas

Computational Biology
Department of Computer Science
University of Oxford
Wolfson Building, Parks Rd
Oxford OX1 3QD

tlf     +44 (0) 1865 610737
web     http://www.cs.ox.ac.uk/people/Ramon.CaseroCanas
photos  http://www.flickr.com/photos/rcasero/


More information about the Insight-users mailing list