[vtkusers] vtkImageReslice rotation and resampling question

David Gobbi david.gobbi at gmail.com
Thu Jul 21 08:31:50 EDT 2016


Hi Richard,

In my previous email I recommended using SetOutputExtent(), because that
will allow you to resample the kernel directly onto a smaller grid, which
is much more efficient than shrinking the grid after resampling.

You can compute the extent of this "shrunken" grid analytically.  Given the
original kernel extent (before resampling), compute the x,y,z coords of the
8 corner points.  Then apply the transformation to those 8 corner points,
and compute the new bounding box by finding the new x_min, x_max, y_min,
y_max, z_min, z_max.  Convert these bounds to an extent by using floor()
and ceil() operations.

 - David

On Thu, Jul 21, 2016 at 3:07 AM, Richard Brown <richard.j.brown at live.co.uk>
wrote:

> David,
>
> To minimise computing time, I would like to then shrink my kernel after
> resampling it.
>
> Is there a method in VTK to reduce a vtkImageData’s extent, such that the
> cuboid is smallest possible without omitting any non-zero voxels (as in the
> images below).
>
> Regards,
> Richard
>
>
> On 20 Jul 2016, at 16:58, David Gobbi <david.gobbi at gmail.com> wrote:
>
> Hi Richard,
>
> Yes, the resampled kernel will be the full size of your dose grid.  To
> avoid this, you would have to compute for yourself what the bounds of the
> resampled kernel are, and then use the reslice->SetOutputExtent() method to
> declare those bounds.  Or, you could avoid using vtkImageReslice altogether
> and use vtkImageInterpolator directly instead.
>
> The best option, if your kernel is defined by an analytic function, is to
> transform the x,y,z coords of that function and evaluate the dose directly
> on your grid.
>
>  - David
>
>
> On Wed, Jul 20, 2016 at 8:11 AM, Richard Brown <richard.j.brown at live.co.uk
> > wrote:
>
>> David,
>>
>> That sorted it, thanks.
>>
>> So the resampled kernel has the same dimensions as the dose grid? My
>> kernel is very small compared to my dose grid, so superposition will be
>> slower than necessary.
>>
>> Is this why, in your original response, you said the method isn’t very
>> fast if it needs to be used many times?
>>
>> Regards,
>> Richard
>>
>> On 20 Jul 2016, at 16:01, David Gobbi <david.gobbi at gmail.com> wrote:
>>
>> Hi Richard,
>>
>> SetInformationInput(), not SetInformation().  The former (the one you
>> need to use) requires a vtkImageData as input.  It provides the reference
>> image that defines the geometry for the reslicing.
>>
>>  - David
>>
>> On Wed, Jul 20, 2016 at 7:55 AM, Richard Brown <
>> richard.j.brown at live.co.uk> wrote:
>>
>>> Hi David,
>>>
>>> I’ve been working through your advice and I get an error:
>>> Attempt to get an input array for an index that has not been specified
>>>
>>> My code looks like yours:
>>>  vtkSmartPointer<vtkImageReslice> imageReslice = vtkSmartPointer<
>>> vtkImageReslice>::New();
>>>
>>>     imageReslice->SetInputData(kernelImageData);
>>>
>>>     imageReslice->SetInformation(doseGrid->GetInformation());
>>>
>>>     imageReslice->SetInterpolationModeToLinear();
>>>
>>>     imageReslice->SetResliceTransform(transform);
>>>
>>>     imageReslice->Update();
>>>
>>>
>>> It seems like the error is coming from doseGrid (when I comment it out,
>>> the error goes away). The dose grid was initialised like this:
>>>
>>>     vtkSmartPointer<vtkImageData> doseGrid = vtkSmartPointer<vtkImageData>::New();
>>>
>>>     doseGrid->SetOrigin(0.,0.,0.);
>>>
>>>     doseGrid->SetDimensions(500,500,500);
>>>
>>>     doseGrid->SetSpacing(0.5,0.5,0.5);
>>>
>>>     doseGrid->AllocateScalars(VTK_DOUBLE,1);
>>>
>>>
>>> Any idea what I’ve done wrong?
>>>
>>> Regards,
>>> Richard
>>>
>>> On 08 Jul 2016, at 17:42, David Gobbi <david.gobbi at gmail.com> wrote:
>>>
>>> Hi Richard,
>>>
>>> Yes, you can use vtkImageReslice for this.  It would work like this:
>>>
>>> Let's define T as the transform that gives the position and orientation
>>> of the kernel within the larger image.  To resample the kernel, you would
>>> give vtkImageReslice the inverse of T as the ResliceTransform, and you
>>> would supply the larger image as a reference image, e.g. the code would
>>> look like this (using Python):
>>>
>>> reslice = vtkImageReslice()
>>> reslice.SetInputData(kernel_image)
>>> reslice.SetInformationInput(big_image)
>>> reslice.SetResliceTransform(inverse_transform)
>>> reslice.SetInterpolationModeToLinear()
>>> reslice.Update()
>>>
>>> This will produce something like the bottom image from your original
>>> email. In order for the kernel resampling to work properly, your kernel
>>> image must have a border which is all zeros.  If this must be done over and
>>> over again (i.e. if you need to superimpose the kernel hundreds of times at
>>> various locations within the larger image) then the above procedure won't
>>> be fast enough. Another possibility is to use the vtkImageInterpolator
>>> class and some of your own ingenuity to create a fast method for resampling
>>> and superposing the kernel.
>>>
>>> During my PhD, I wrote a custom VTK class that superposed kernels into a
>>> volume in order to do 3D ultrasound reconstruction, but I never generalized
>>> it:
>>>
>>> https://github.com/dgobbi/AIGS/blob/master/Ultrasound/vtkFreehandUltrasound.h
>>>
>>> Some further development of this code was done for the PLUS toolkit:
>>>
>>> https://app.assembla.com/spaces/plus/subversion/source/HEAD/trunk/PlusLib/src/PlusVolumeReconstruction
>>>
>>> However, as far as I know, VTK doesn't provide an efficient
>>> general-purpose way of superposing kernels at different positions and
>>> orientations into a 3D volume.
>>>
>>>  - David
>>>
>>>
>>>
>>> On Fri, Jul 8, 2016 at 7:07 AM, Richard Brown <
>>> richard.j.brown at live.co.uk> wrote:
>>>
>>>>
>>>> Hi all,
>>>>
>>>> I have a fairly simple problem, and one that I’m sure has previously
>>>> been solved here, but I’m struggling to find the right keywords to find a
>>>> useful thread.
>>>>
>>>> I would like to superpose a kernel vtkImageData (kernel.png) onto a
>>>> grid vtkImageData (grid.png). The kernel will be rotated (superpose.png),
>>>> however, so the kernel will requiring resampling before superposition is
>>>> possible (superposition_and_resample.png).
>>>>
>>>> What is the best way to do this? I feel like I can simply use
>>>> vtkImageReslice, but I’m not 100%.
>>>>
>>>> Thanks in advance for any pointers.
>>>>
>>>> Regards,
>>>> Richard
>>>>
>>>
>>>
>>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160721/3f1f8529/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: superposition_and_resample.png
Type: image/png
Size: 7907 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160721/3f1f8529/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: superposition_and_resample.png
Type: image/png
Size: 3363 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160721/3f1f8529/attachment-0001.png>


More information about the vtkusers mailing list