[Insight-users] rotating data with in a 3D array

rama rama at robots.ox.ac.uk
Mon Sep 19 16:39:14 EDT 2005


Hi Luis,

****previous message bounced back. so sending again. sorry****

I read all the suggestions you gave to Rotate a 3D array and finally 
wrote a piece of code to rotate the 3D array around Z-Axis (think that z 
is pointing into the screen).

But I did not get the correct result. I get a jarred and zig-zag image. 
I rotated it 0.5 degrees CW.
Please see the images before and after rotation. 
http://www.funnotes.net/img-before.JPG http://www.funnotes.net/img-after.JPG

I did not understand exactly where it is going wrong in the code I 
wrote. I followed the software guide of ITK you gave and followed all 
the instructions you gave.

Here is the code that I wrote to rotate the 3D array.

       const unsigned int Dimension=3;
       typedef unsigned char InputPixelType;
       typedef unsigned char OutputPixelType;
       typedef itk::Image<InputPixelType, Dimension> InputImage;
       typedef itk::Image<OutputPixelType, Dimension> OutputImage;
       typedef itk::ResampleImageFilter<InputImage, OutputImage> Resampler;
       Resampler::Pointer resampler=Resampler::New();

       typedef itk::ImportImageFilter<InputPixelType, Dimension> 
ImportImgFromArray;
       ImportImgFromArray::Pointer importFilter = 
ImportImgFromArray::New();
       ImportImgFromArray::SizeType size;
       size[0]=DICOMData::Instance()->GetX(m_curDataSetListSel);      
                 //x number of pixels   - 'm_curDataSetListSel' is 
nothing but the variable which indicates current data set
       size[1]=DICOMData::Instance()->GetY(m_curDataSetListSel);      
                 //y number of pixels
       size[2]=DICOMData::Instance()->GetZ(m_curDataSetListSel);      
                 //z number of pixels
       ImportImgFromArray::IndexType start;
       start.Fill(0);
       ImportImgFromArray::RegionType region;
       region.SetIndex(start);
       region.SetSize(size);
       importFilter->SetRegion(region);
       double origin[Dimension];
       origin[0]=0.0;
       origin[1]=0.0;
       origin[2]=0.0;
       importFilter->SetOrigin(origin);
       double spacing[Dimension];
       
spacing[0]=DICOMData::Instance()->GetPixelXWidth(m_curDataSetListSel);   
           //pixel x width
       
spacing[1]=DICOMData::Instance()->GetPixelYWidth(m_curDataSetListSel);   
           //pixel y width
       
spacing[2]=DICOMData::Instance()->GetPixelZWidth(m_curDataSetListSel);   
           //pixel z width
       importFilter->SetSpacing(spacing);
       
importFilter->SetImportPointer(m_data[m_curDataSetListSel].m_actualDisplayData[0], 
size[0]*size[1]*size[2], false);   //data pointer

       typedef itk::NearestNeighborInterpolateImageFunction<InputImage, 
double> Interpolator;
       Interpolator::Pointer interpolator=Interpolator::New();
       resampler->SetInterpolator(interpolator);

       typedef itk::AffineTransform<double, Dimension> TransformType;
       TransformType::Pointer transform=TransformType::New();

       TransformType::OutputVectorType rotation;
       rotation[0]=0;
       rotation[1]=0;
       rotation[2]=1;
       transform->Rotate3D(rotation, 
m_cmnData->CoronalRotateZ(m_curDataSetListSel)*DegToRad, false);
       resampler->SetTransform(transform);

       resampler->SetDefaultPixelValue(0);
       resampler->SetSize(size);
       resampler->SetOutputOrigin(origin);
       resampler->SetOutputSpacing(spacing);

       resampler->SetInput(importFilter->GetOutput());
       resampler->Update();

       InputImage::PixelContainer *container;                           
                                         // taking data back to my array
       container=resampler->GetOutput()->GetPixelContainer();
       container->SetContainerManageMemory(false);
       
m_data[m_curDataSetListSel].m_actualDisplayData[0]=container->GetImportPointer(); 


The code worked well wihtout any link errors that I am getting before. 
But the result is not correct. What is wrong in this code.
This code exactly imitates the exercise in the software guide of ITK.

Can you please spot out what extra things have to be added in this code 
for it to give correct result.

thank you,
Rama.

Luis Ibanez wrote:

>
> Hi Rama,
>
> In order to create an itk::Image from your C++ array, you can use
> the ImportImageFilter, as described in the ITK Software Guide:
>
>            http://www.itk.org/ItkSoftwareGuide.pdf
>
> In particular in Section 4.1.7 "Importing Image Data from a Buffer",
> in pdf-page 78.
>
>
> Once you set up your importer filter, you can pass the output of the
> importer to the resample image filter as:
>
>            resampler->SetInput( importer->GetOutput() );
>
> then run the filter
>
>            resampler->Update();
>
> then get the buffer back
>
>    ImageType::PixelContainer  * container;
>    container = filter->GetOutput()->GetPixelContainer();
>    buffer = container->GetImportPointer();
>
> and *VERY* important, mummifying the buffer so it doesn't get
> destroyed when the resampler filter is destroyed.
>
>
>    container->SetContainerManageMemory( false );
>
>
> You will also find useful to read the Tutorials, in particular
> the one describing Integration of ITK with your application.
> That tutorial describes how to exchange data between ITK filters
> and the typical C++ arrays used in applications.
>
>
>    Regards,
>
>
>       Luis
>
>
> ---------------
> rama wrote:
>
>> Hi Luis,
>>
>> I have read the documentation that you have suggested and it has been 
>> quite useful. But I want to clarify a small doubt before starting to 
>> attempt it.
>>
>> That is, how to give input data and how to collect output data.
>>
>> The manual says input can be obtained from any filter and there are 
>> functions like,
>> filter->SetInput( reader->GetOutput() );
>> writer->SetInput( filter->GetOutput() );
>> writer->Update();   // to trigger the operation
>>
>> But I have the data as a normal C++ array. I have the data as,
>>    unsigned int *data[X*Y*Z].
>> So the whole 3D data is packed as a single array.
>>
>> Shall I just write
>>    filter->SetInput(data);
>> and
>>    data=filter->GetOutput();
>>
>> I am bit confused about how to give the input and how to collect the 
>> output.
>>
>> Can you please clarify this doubt to me.
>>
>> thank you,
>> Rama.
>>
>> Luis Ibanez wrote:
>>
>>>
>>> Hi Rama,
>>>
>>> Please read the ITK Software Guide.
>>>
>>>    http://www.itk.org/ItkSoftwareGuide.pdf
>>>
>>> In particular, you should read Section 6.9,
>>> "Geometric Transformations" in pdf-page 249.
>>>
>>>
>>> This section describes in detail how to use the
>>>
>>>              itk::ResampleImageFilter<>
>>>
>>> in order to apply rotations and translation to images.
>>>
>>>
>>> Note that for a rotation you probably want to use the
>>> itk::VersorRigid3DTransform, as described in that section,
>>> and you want to initilize the transform using the
>>> itk::CenteredTransformInitializer.
>>>
>>>
>>> Source code for these examples is available in
>>>
>>>
>>>      Insight/Examples/Filtering/
>>>            ResampleImageFilter.cxx
>>>            ResampleImageFilter2.cxx
>>>            ResampleImageFilter3.cxx
>>>            ResampleImageFilter4.cxx
>>>            ResampleImageFilter5.cxx
>>>            ResampleImageFilter6.cxx
>>>            ResampleImageFilter7.cxx
>>>            ResampleImageFilter8.cxx
>>>            ResampleImageFilter9.cxx
>>>
>>>
>>>
>>>   Regards,
>>>
>>>
>>>      Luis
>>>
>>>
>>>
>>> --------------------
>>> rama wrote:
>>>
>>>> Hi,
>>>>
>>>> I am looking for a way to rotate data within a 3D array. I have a 
>>>> 3D array with dimensions X*Y*Z with each value being an integer in 
>>>> the range 0-255 which actually represents a gray scale 3D image.
>>>> Now I want to rotate the image in that array, by this I mean, I 
>>>> want to rotate the data with in that 3D array and store the result 
>>>> in the array of same dimensions.
>>>>
>>>> I have come accross the MultiResMIRegistration example in ITK 2.0.0 
>>>> distribution. I have seen it rotating a 3D data set (array) to 
>>>> register with another 3D data set. I have seen its code but there 
>>>> is little help in it. I have also seen the Transform class in ITK. 
>>>> But it doesn't give any information about how to trigger the 
>>>> transformation and will it transform the whole 3D array in a single 
>>>> go.
>>>>
>>>> Can anyone give an idea of how to do rotations on data with in a 3D 
>>>> array.
>>>>
>>>> thanks,
>>>> Rama.
>>>>
>>>> _______________________________________________
>>>> Insight-users mailing list
>>>> Insight-users at itk.org
>>>> http://www.itk.org/mailman/listinfo/insight-users
>>>>
>>>>
>>
>>
>>
>



More information about the Insight-users mailing list