[vtkusers] Fast element access of vtkImageData?
Dominique Töpfer
dominique at toepfer-web.de
Thu Jul 28 13:46:25 EDT 2011
Hi Joseph,
I use GetScalarPointer to get a pointer to the first element. You then
can use simple formulas to pick the desired point and component: If
there's only two dimensions and one scalar component the index to the
array is y * dim_x + x (or you may use GetScalarPointer(x, y, 1)). If
you have four components you have 4*(y*dim_x+x)+i for the i-th component
at (x,y). I don't know if there is also a way to get GetScalarPointer(x,
y, z) working for more than one scalar component.
vtkSmartPointer<vtkImageData> pxImage =
vtkSmartPointer<vtkImageData>::New();
pxImage->SetDimensions(512, 512, 1);
pxImage->SetOrigin(0.0, 0.0, 0.0);
pxImage->SetSpacing(1.0, 1.0, 1.0);
pxImage->SetScalarTypeToUnsignedChar();
pxImage->SetNumberOfScalarComponents(4);
pxImage->AllocateScalars();
unsigned char *pxImageData = static_cast<unsigned char
*>(pxImage->GetScalarPointer());
for(unsigned int x = 0; x < 512; x++)
{
for(unsigned int y = 0; y < 512; y++)
{
pxImageData[4 * (y * 512 + x) + 0] = x / 2; // R
pxImageData[4 * (y * 512 + x) + 1] = y / 2; // G
pxImageData[4 * (y * 512 + x) + 2] = 128; // B
pxImageData[4 * (y * 512 + x) + 3] = 128; // A
}
}
vtkSmartPointer<vtkBMPWriter> writer =
vtkSmartPointer<vtkBMPWriter>::New();
writer->SetInput(pxImage);
writer->SetFileName("test.bmp");
writer->Write();
HTH
Dominique
On 07/28/2011 02:48 AM, Joseph D. Wieber Jr. wrote:
> Hi Dominique,
>
> Thanks for your response. What should I expect from
> GetScalarPointer()? For example, if I have a vtkImageData object with
> four float components (say RGBA), should I expect to be able to cast
> the void* to float* and have it point to an array of four floats? I
> modified my template to the below, but it didn't work. Am I expecting
> the wrong return?
>
> //ImageDataPtr is: typedef vtkSmartPointer< vtkImageData >
> ImageDataPtr;
>
> template< typename T >
> void
> fillImageData( ImageDataPtr pImageData, const T& val )
> {
> int dims[ 3 ];
> pImageData->GetDimensions ( dims );
> int& xMax = dims[ 0 ];
> int& yMax = dims[ 1 ];
> int& zMax = dims[ 2 ];
> int numComponents = pImageData->GetNumberOfScalarComponents ();
>
> for( int z = 0; z < zMax; ++z )
> {
> for ( int y = 0; y < yMax; ++y )
> {
> for( int x = 0; x < xMax; ++x )
> {
> T* ptr = static_cast< T* >(
> pImageData->GetScalarPointer (x, y, z) );
>
> for( int c = 0; c < numComponents; ++c )
> {
> *ptr = val; //*ptr++ = val;
> ++ptr;
> }
> }
> }
> }
> }
>
> Thanks again.
>
> Regards,
> Joseph
>
>
> On 07/27/2011 04:22 PM, Dominique Töpfer wrote:
>> Hi Joseph,
>>
>> you could use GetScalarPointer(), which gives you a void * pointer to
>> the actual image data. After casting it to the pixel type you are
>> using, you can access the array directly, which should be much
>> faster. To access a certain point you could use ComputePointID() to
>> get the correct index.
>>
>> HTH
>> Dominique
>>
>> On 27.07.2011 22:07, Joseph D. Wieber Jr. wrote:
>>>
>>> Hello,
>>>
>>> Is there a fast way to access (get and set) elements in a
>>> vtkImageData object? For instance I have two image data object with
>>> dimensions 512x512x1 that I'm using as part of a cost table (it's
>>> convenient) for an algorithm. One of them gets the output of a
>>> convolution filter and I do lookups into it. The other one has to
>>> be initialized to all 1.0 values at the beginning of the algorithm.
>>> Then based on information from the first one, I set values in the
>>> second one. The algorithm is a specialized Laplacian zero
>>> crossing. I've been using the following template to initialize all
>>> the values to 1.0:
>>>
>>> //-----------------------------------------------------------------------------
>>>
>>> //TODO: This is horribly slow. Find a smarter way!
>>>
>>> template< typename T >
>>> void
>>> fillImageData( ImageDataPtr pImageData, const T& val )
>>> {
>>> int dims[ 3 ];
>>> pImageData->GetDimensions ( dims );
>>> int& xMax = dims[ 0 ];
>>> int& yMax = dims[ 1 ];
>>> int& zMax = dims[ 2 ];
>>> int numComponents = pImageData->GetNumberOfScalarComponents ();
>>>
>>> for( int z = 0; z < zMax; ++z )
>>> {
>>> for ( int y = 0; y < yMax; ++y )
>>> {
>>> for( int x = 0; x < xMax; ++x )
>>> {
>>> for( int c = 0; c < numComponents; ++c )
>>> {
>>> pImageData->SetScalarComponentFromFloat ( x, y,
>>> z, c, val );
>>> }
>>> }
>>> }
>>> }
>>> }
>>>
>>> To get and set values during the zero crossing computation I've been
>>> using combinations of GetScalarComponentAsFloat, and
>>> SetScalarComponentFromFloat and this part is also very slow.
>>>
>>> Can someone please point me to an example that accomplishes similar
>>> tasks in a more efficient manner, or offer a suggestion on where to
>>> look? Thank you.
>>>
>>> Regards,
>>>
>>> Joseph
>>>
>>> _______________________________________________
>>> 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