[Insight-users] Flexible Vector Image class

Karthik Krishnan Karthik.Krishnan at kitware.com
Tue Nov 22 14:53:28 EST 2005


Sorry for the very long email, but I thought I'd save users/developers 
possible grief to users of these classes by sending this out.

Dr. Uwe Köhler wrote:

>Dear Karthik
>
>ever so many thanks for your help. This will help us on, a lot. I actually 
>started to write a test myself before I found yours. 
>
>I stumbled across some additional points:
>
>1. Can you suggest a file format for Vectors up to a length of 12 in up to 4 
>dimensions. I found so far that I came across undocumented limits quite 
>often.
>  
>
Thanks. Could you please keep emails to the list, so others could 
benifit from it (and I can google it when I run into problems :) )
I've never instantiated a VectorImage with other than 3 dimensions, but 
I don't see why it won't work for 4. Is there a problem.
There is no restriction on the length of each pixel.

>2. 	// Quote handbook page 459:
>	// Consider using the Value() method instead of Get() and Set() when
>	// a call to the operator= on a pixel is non-trivial, such as when 
>	// working with vector pixels, and operations are done in-place in 
>	// the image. 11.2.3
>Canne get that to work at all. The 
>itk::ImageRegionConstIterator<VectorImageType>->Get() fundtion works, but 
>assigns up to 2 GByte of memory in our application.
>  
>
In general, I did not expect anybody to delve into the source code to 
look at this stuff, since most users would be happy to use the 
Get()/Set() interfaces provided by the iterators, but....

Here's the story..

The VectorImage in ITK follows a paradigm similar to std::vector< bool 
 >. See the source for std::vector< bool > and its inlined comments.

http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/stl__bvector_8h-source.html#l00652

As you can see in line 405, std::vector is specialized for booleans. As 
the comments mention, vector< bool > is an example of a proxied 
container.  References and pointer types maintained by this vector are 
not really references and pointers to bools. The actual values 
themselves are packed into chars, 8 bits at a time and the appropriate 
index is computed by the iterator, unpacking the appropriate location 
from the iterator at run time to give you the bool.

To make my point clearer, try the following on a gcc40 compiler (maybe 
other compilers too):
---------------------------
#include <iostream>
#include <vector>

int main()
{
  // The last paragraph in the code will compile for every DataType 
except bool.

  typedef bool DataType;  
  typedef std::vector< DataType > VectorType;
  VectorType v;
  v.reserve( 10 );
  for ( int i=0; i<10; i++ )
    {
    if (i%2) v[i] = true; else v[i]=false;
    }
 
  // Simple iterators work just fine... Dereferencing the iterator works
  // fine because the iterator takes care of the bit unpackings to do when
  // deferencing a std::vector< bool >
  VectorType::const_iterator it = v.begin();
  for( int j=0; j< 10; j++)
    std::cout << *(it+j)  << std::endl;

  // Direct deferencing will not work for std::vector< bool >. It will 
work for
  // every other datatype. Given that bool is specialized in the STL 
implementation,
  // it is possible to throw a compiler error for the following line
  DataType *b = &*v.begin();
  for( int j=0; j< 10; j++)
    std::cout << *(b+j)  << std::endl;

  return 0;
}
-----------------------------

As you can see STL  errors out in the case of direct dereferencing, only 
if the DataType is bool. So that is forbidden.


With the VectorImage, its similar. When you instantiate a VectorImage< 
int, Dimension > and set the VectorLength to l, the pixels in the buffer 
are not arrays of length l, but integers, packed if you will, in 'l' 
consecutive memory blocks.  Direct deferencing using the itk::Iterators 
or the GetBufferContainer() method in the Image *will not* yield the 
correct results, for the same reasons above.

That is why the "Value()" method will not work on the VectorImage, while 
the Get(), Set() methods will...


References:

1. [Herb Sutters paper to ISO C++ about why vector< bool > is 
non-conforming ]
http://www.gotw.ca/publications/N1185.pdf 

2. http://www.boost.org/libs/iterator/doc/index.html


About the 2GB memory consumption, could you please tell me the size of 
the VectorImage, its datatype and the VectorLength ?

>I think I am able to get the rest to work with your previous help.
>
>Great work
>
>Uwe
>
>Am Freitag, 18. November 2005 23:31 schrieben Sie:
>  
>
>>Thanks very much for the bug report. One of those is a bug report, the
>>other is not. The bug is  fixed.
>>
>>Please update your CVS, (at least the files in the Statistics folder.)
>>
>>The MHD reader and all other readers/writers that support
>>multi-component images (VTK, Nrrd.... )
>>
>>The reader has to be instantiated like this:
>>
>>typedef itk::VectorImage< double, 3 > VectorImageType;
>>typedef itk::ImageFileReader< VectorImageType,
>>
>>itk::DefaultConvertPixelTraits< PixelType > > ReaderType;
>>........
>>
>>
>>The writer does not require this.
>>
>>I thought I obtained that via traits from the ImageType, but looks like
>>I forgot to do that. B
>>
>>Please see
>>Testing/Code/Common/itkVectorImageTest.cxx
>>This does IO/Iterators/Adaptors etc on the VectorImage.
>>
>>
>>Thanks
>>Regards
>>Karthik.
>>
>>    
>>
>
>  
>


More information about the Insight-users mailing list