[vtkusers] Fast element access of vtkImageData?
Joseph D. Wieber Jr.
jdwieber at gmail.com
Thu Jul 28 10:49:54 EDT 2011
Hi Dominique,
Thanks for the reply, and meaningful example. I changed my
implementation to use GetScalarPointer() instead of GetScalarPointer(
int,int,int), and now it works great. The final method is below (for
the next person that reads this thread).
//-----------------------------------------------------------------------------
//N.B. The image data object must be correctly set up and scalars
allocated
//before calling this method. That is: Allocate the object, set the
dimensions,
//set the scalar type, and set the number of components.
template< typename T >
void
fillImageData( vtkSmartPointer< vtkImageData > pImageData, const T&
val )
{
int dims[ 3 ];
pImageData->GetDimensions ( dims );
const int numComponents =
pImageData->GetNumberOfScalarComponents ();
const int numElements = dims[ 0 ] * dims[ 1 ] * dims[ 2 ] *
numComponents;
T* pPixel = static_cast< T* >( pImageData->GetScalarPointer () );
for( int elemCnt = 0; elemCnt < numElements; ++elemCnt )
{
pPixel[ elemCnt ] = val;
}
}
Regards,
Joseph
On 07/28/2011 01:46 PM, Dominique Töpfer wrote:
> 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