[vtkusers] Iterating through a vtkImageData

David Feng dfeng at cs.unc.edu
Sun Nov 1 20:17:21 EST 2009


David Doria wrote:
> On Sun, Nov 1, 2009 at 4:21 PM, David Feng <dfeng at cs.unc.edu> wrote:
>> This is slow, but I usually do something along these lines:
>>
>> int* dims = image->GetDimensions();
>> for (int z=0; z<dims[2]; z++)
>>  {
>>  for (int y=0; y<dims[1]; y++)
>>   {
>>   for (int x=0; x<dims[0]; x++)
>>     {
>>     // zero is the component, add another loop if you have more
>>     // than one component
>>     double v = image->GetScalarComponentAsDouble(x,y,z,0);
>>         // do something with v
>>     }
>>   }
>>  }
>>
>> GetScalarComponentAsDouble(...) does a lot of range checking and type
>> conversion, so if you want to be faster you can pull out the point data and
>> do the indexing yourself:
>>
>> pd = image->GetPointData()->GetScalars();
>>
>> for (int i=0; i<pd->GetNumberOfTuples(); i++)
>>  {
>>  // etc
>>  }
>>
>> They are indexed x first, then y, then z.  If you happen to know what type
>> your data is, cast the data array as such and you'll have type-specific
>> access.
>>
>> Is this what you wanted?  I've never used vtkImageIterator, so I can't help
>> you there.
>>
>> David
>>
>> David Doria wrote:
>>> I found vtkImageIterator, but from looking at the Test, I saw something
>>> like:
>>>
>>>  int ext[3] = { 0, 0, 0};
>>>  vtkImageData *id = vtkImageData::New();
>>>  id->SetExtent(ext);
>>>  vtkImageIterator<float*> *it = new vtkImageIterator<float*>(id,ext);
>>>
>>> When I try that, I get:
>>> undefined reference to
>>> `vtkImageIterator<float*>::vtkImageIterator(vtkImageData*, int*)'
>>>
>>> If I try to use the "vtk style" object creation:
>>> vtkSmartPointer<vtkImageIterator<float*> > iterator =
>>> vtkSmartPointer<vtkImageIterator<float*> >::New();
>>>
>>> I get:
>>> 'New' is not a member of 'vtkImageIterator<float*>'
>>>
>>> What I am trying to do is simply visit every voxel of a 3d
>>> vtkImageData. It would also be nice to access a particular voxel in an
>>> (x,y,z) type format. Can anyone comment on how to do either of these
>>> things?
>>>
>>> Thanks,
>>>
>>> David
>
>
> David,
>
> So GetScalarComponentAsFloat (int x, int y, int z, int component) is
> specifically for 3d images? What do you do if you have a 2d image? Do
> you simply set z=0? What is 'int component' that you have set to 0?
As you suspected, set the index referring to an empty dimension to zero 
and it will work.  Images can have multiple values stored at each 
pixel.  The most common example is RGB, i.e. the three color 
components.  This is the easiest way to iterate through an image, I think.
>
> Also, you mention if I know what kind of data it is I can cast it and
> then use type specific access. I'm assuming you mean to cast either to
> a StructuredPoints or UniformGrid since these are the only two
> apparent subclasses of vtkImageData. 
I actually meant casting the data array underlying the vtkImageData.  
The base array class is vtkDataArray, which is an abstract class that 
contains flat arrays of different data types (vtkUnsignedCharArray, 
vtkFloatArray, etc).  The vtkImageData class uses a vtkDataArray to 
contain its pixel/voxel values.  If you wanted to iterate through that 
typed array, you would have to know what the type is:

vtkFloatArray* fa = 
vtkFloatArray::SafeDownCast(image->GetPointData()->GetScalars());

The SafeDownCast call attempts to cast the passed scalar array to the 
requested type (vtkFloatArray) and returns null on failure (i.e. it's 
not actually a vtkFloatArray).  If you were to do the following:

vtkDataArray* da = image->GetPointData()->GetScalars();

you could access the data generically as doubles via da->GetTuple(...).  
This results in casting to double again, of course.  vtkDataArray and 
its subclasses don't know anything about the topology of the image, 
though, so you'll have to know how an array index maps to a voxel index.
> I am currently particularly at
> the output of vtkVoxelModeller
> (http://www.vtk.org/doc/nightly/html/classvtkVoxelModeller-members.html).
> It is a vtkImageAlgorithm - I was assuming its GetOutput() would
> return a vtkImageData, but how would I tell if the type is more
> specific? Looking at both of those subclasses I actually don't see any
> better looking accessors - can you elaborate/give an example of what
> you meant?
In your case, it looks like you won't actually know what the data type 
will be, although the documentation for vtkVoxelModeller indicates that 
it might be a vtkBitArray.  Unless you're worried about efficiency, I 
would just use the loop I showed above.  Just set z=0 and component=0 
and you can index a 2D image with no problem. 

David
>
> Thanks for the help so far!
>
> David
> _______________________________________________
> 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
>




More information about the vtkusers mailing list