[vtkusers] reconstruct a stack of TIFF images in 3D

Marco Nawijn nawijn at gmail.com
Tue Mar 26 09:23:17 EDT 2013


On Tue, Mar 26, 2013 at 12:50 PM, ljp19890525 <ljp19890525 at 163.com> wrote:
> And How to  Extract resolution from the TIFF file? Is there any function or
> something others? When looping over pixels in TIFF file and assign them to
> the corresponding "layer",which object would store the assignment. Is
> vtkImageData object ? How to change the "layer" when it comes to next TIFF
> file? Is it the "N",and how to combine them?
> Thanks a lot for your help!
> ________________________________
> ljp19890525
>
> From: Marco Nawijn
> Date: 2013-03-26 18:50
> To: ljp19890525
> Subject: Re: [vtkusers] reconstruct a stack of TIFF images in 3D
> On Mon, Mar 25, 2013 at 2:40 PM, ljp19890525 <ljp19890525 at 163.com> wrote:
>> Hi all,
>>    I have obtained  a stack of TIFF images. I want to show the images in
>> 3D
>> by VTK.  And I want to reconstruct  the images in 3D.   By now I can only
>> show just one tiff image【through the vtkTIFFReader】,but  What I need is to
>> show a stack of TIFF images  in 3D. I would like to see three-dimensional
>> Artistic.  They are tiff imgaes. Thanks a lot!
>> below is my code,reading one,just one tiff image!
>> #include <vtkSmartPointer.h>
>> #include <vtkImageViewer2.h>
>> #include <vtkTIFFReader.h>
>> #include <vtkRenderWindow.h>
>> #include <vtkRenderWindowInteractor.h>
>> #include <vtkRenderer.h>
>>
>> int main(int argc, char* argv[])
>> {
>>   //Verify input arguments
>>   if ( argc != 2 )
>>     {
>>     std::cout << "Usage: " << argv[0]
>>               << " Filename(.tif)" << std::endl;
>>     return EXIT_FAILURE;
>>     }
>>
>>   //Read the image
>>   vtkSmartPointer<vtkTIFFReader> reader =
>>     vtkSmartPointer<vtkTIFFReader>::New();
>>   reader->SetFileName ( argv[1] );
>>
>>   // Visualize
>>   vtkSmartPointer<vtkImageViewer2> imageViewer =
>>     vtkSmartPointer<vtkImageViewer2>::New();
>>   imageViewer->SetInputConnection(reader->GetOutputPort());
>>   vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
>>     vtkSmartPointer<vtkRenderWindowInteractor>::New();
>>   imageViewer->SetupInteractor(renderWindowInteractor);
>>   imageViewer->Render();
>>   imageViewer->GetRenderer()->ResetCamera();
>>   imageViewer->Render();
>>
>>   renderWindowInteractor->Start();
>>
>>   return EXIT_SUCCESS;
>> }
>> ________________________________
>> ljp19890525
>>
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Please keep messages on-topic and check the VTK FAQ at:
>> http://www.vtk.org/Wiki/VTK_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.vtk.org/mailman/listinfo/vtkusers
>>
>
> Hi,
>
> An option could be to create a vtkImageData object and generate
> a volumetric image. The steps would be something like the following:
>
> 1. Number of TIFF files is N
> 2. Create vtkImageData object.
> 3. Loop over the N TIFF files:
> 3.a   if N==0:
>               Extract resolution from the TIFF file (gives you X and Y)
>               Set extent on vtkImageData object: SetExtend(0,X,0,Y,0,N)
> 3.  b Loop over pixels in TIFF file and assign them to the corresponding
>      "layer"
>
> 4. Write image to file or return vtkImageData object
>
> Hope it helps.
>
> Marco



Ok, I think I figured it out. I use python code to demonstrate it, but
the sequence
should be exactly the same as in C++.

*** DISCLAIMER ***
Code below should be largely ok, but I could not test it at the moment.

reader = vtkTIFFReader()
reader.SetFileName('test. tiff')
reader.Update()

image = reader.GetOutput()
# For my test TIFF file of 640x400, I get the following
image.GetExtent()
(0, 639, 0, 399, 0, 0)

# So this was for a single image. For the volumetric image
# you now do something like the following

volume = vtkImageData()
volume.SetExtent((0, 639, 0, 399, 0, N-1)   # N  is the number of TIFF images

# Get the number of cells and points for your volume
ncells = volume.GetNumberOfCells()
npoints = volume.GetNumberOfPoints()

The final piece of the puzzle is to get your TIFF data into the
volume image. This is actually quite simple. What you do
is create a data array to hold the data for each point
in your volume image The dimension is npoints. Than you loop
over each TIFF image and copy the data to the array. So something
like the following:

array = vtkUnsignedShortArray()
array.SetNumberOfValues(npoints)

for i in range(N):
     reader.SetFileName('test_%d.tiff' % i)
     reader.Update()
     img = reader.GetOutput()
     vals = img.GetPointData().GetArray('Tiff Scalars')
     offset = i*N
     for i,v in enumerate(vals):
           array.SetValue(offset+i,v)

# Finally we have to assign our array to the volume image.
volume.GetPointData().SetArray(array)

Done!

A few final remarks.
- You might want to check that size of each TIFF image is the same.
- The TIFF reader seems to store the data as point data in the "Tiff
Scalars" array name;
  For the volume image you might like to convert it to cell data.
- The final volume image will be visualized in a sort of parametric
dimensions (namely
  pixel width, pixel height, number of tiff images). You can use the
transform filters to
  scale to physical dimensions.



More information about the vtkusers mailing list