[vtkusers] double vtkDataArray::GetTuple1(vtkIdType i) vs void vtkDataArray::GetTuple(vtkIdType i, double *tuple)
David Gobbi
david.gobbi at gmail.com
Thu May 8 11:11:35 EDT 2014
Hi Maarten,
I actually did write an iterator with such a function, but I never got
around to contributing it to VTK. I called it vtkImageRegionIterator.
The source code is here:
http://github.com/dgobbi/AIRS/tree/master/ImageSegmentation
It has three separate inline methods for getting the voxel:
GetIndexX(), GetIndexY(), GetIndexZ().
A couple years ago I had some big plans for improving the VTK
image iterators, but like so many things, there was never enough
time.
David
On Thu, May 8, 2014 at 7:20 AM, Maarten Beek <beekmaarten at yahoo.com> wrote:
> Hi David,
>
> Thanks so much for your clarification!
> I did see issues in the resulting image but was attributing them to noise in
> the original images. Now I see my code just had a huge bug in it.
>
> I guess I would need a row counter in order to initialize voxelid correctly.
>
> Wouldn't it be nice if the image iterator had a function like getVoxel(int
> ijk[3])...? I believe ITK has such an iterator.
>
> Maarten
>
>
> On Wednesday, May 7, 2014 5:26:23 PM, David Gobbi <david.gobbi at gmail.com>
> wrote:
> I should add: you actually have to re-initialize the voxelid at the
> beginning of each row (i.e. at the beginning of each span of the
> iterator).
>
> On Wed, May 7, 2014 at 3:22 PM, David Gobbi <david.gobbi at gmail.com> wrote:
>> Hi Maarten,
>>
>> Since you know it's a vtkUnsignedCharArray, you shouldn't be using
>> the SetTuple/GetTuple methods. Use the SetTupleValue and
>> GetTupleValue methods, they're much faster because 1) they aren't
>> virtual methods and 2) they don't have to convert to/from double.
>> Or even better, if you know that your array only has one component,
>> you can use SetValue/GetValue.
>>
>> Your math for voxelid is too simplistic. Depending on how the update
>> extent is divided amongst the threads, it might give you a location
>> that is totally wrong. To see why, draw a square on a piece of paper.
>> That square represents the total extent of the output. Then divide
>> that square into quadrants, and imagine that each quadrant goes
>> to a different Execute method. Then think about how each thread
>> is going to march through the data.
>>
>> David
>>
>>
>> On Wed, May 7, 2014 at 2:20 PM, Maarten Beek <beekmaarten at yahoo.com>
>> wrote:
>>> Hi all,
>>>
>>> I experienced a crash in my algorithm derived from
>>> vtkThreadedImageAlgorithm, that (I think) I solved, but that I don't
>>> understand. Is there some one who can shed some light on the following?
>>>
>>> What I am trying to do is adding a flag identifying the input(s) that
>>> contribute to the value of each pixel in the output image
>>>
>>>
>>> //----------------------------------------------------------------------------
>>> // This templated function executes the filter for any type of data.
>>> template <class OT>
>>> void cmvtkTemplatedExecute(cmvtkDRRGenerator2* self,
>>> vtkDataSetCollection* inputs,
>>> vtkImageData*
>>> output,
>>> int extent[6], int threadId, OT*)
>>> {
>>> vtkUnsignedCharArray* uchararray =
>>>
>>> vtkUnsignedCharArray::SafeDownCast(output->GetPointData()->GetScalars("input_flag"));
>>>
>>> int numinputs = inputs->GetNumberOfItems();
>>> for( int input_i = 0; input_i < numinputs; ++input_i )
>>> {
>>> vtkImageData* input =
>>> vtkImageData::SafeDownCast(inputs->GetItem(input_i));
>>> if( 0 == input )
>>> {
>>> // should not happen
>>> continue;
>>> }
>>> const int* dims= output->GetDimensions();
>>>
>>> vtkImageProgressIterator<OT> outIt(output, extent, self,
>>> threadId);
>>> vtkIdType voxelid = extent[0] + size[0]*extent[2] +
>>> size[0]*size[1]*extent[4];
>>>
>>> // Loop through output pixels
>>> while( !outIt.IsAtEnd() )
>>> {
>>> OT* outSI = outIt.BeginSpan();
>>> OT* outSIEnd = outIt.EndSpan();
>>>
>>> while( outSI != outSIEnd )
>>> {
>>> // start with setting pixel to 0.0
>>> if( input_i == 0 )
>>> {
>>> *outSI = 0.0;
>>> }
>>>
>>> OT result = 0.0;
>>>
>>> //.... some math resulting in a value for result....
>>>
>>> *outSI += result;
>>>
>>> // this input image participates in voxel values; adjust
>>> bit
>>> if( 0.0 < result && 0 != uchararray )
>>> {
>>> // The commented code crashes...
>>>
>>> //unsigned char oldvalue =
>>> uchararray->GetTuple1(voxelid);
>>> //unsigned char newvalue = oldvalue | (1<<input_i);
>>> //uchararray->SetTuple1(voxelid, newvalue);
>>>
>>> double dOldValue;
>>> uchararray->GetTuple(voxelid, &dOldValue);
>>> unsigned char chOldValue = static_cast<unsigned
>>> char>(dOldValue);
>>> unsigned char chNewValue = chOldValue | (1<<input_i);
>>> double dNewValue = static_cast<double>(chNewValue);
>>> uchararray->SetTuple(voxelid, &dNewValue);
>>> }
>>>
>>> ++outSI;
>>> ++voxelid;
>>> }
>>> outIt.NextSpan();
>>> }
>>> } // input_i < numinputs
>>> }
>
>
More information about the vtkusers
mailing list