[vtkusers] Real-Time Image Warping
Jorge Ballesteros (Motiva)
jballesteros at motivando.me
Mon Apr 12 05:02:44 EDT 2010
Hi David,
First of all, thank you very uch for your advice. I have reduced the
resolution of the transform grid and the performance has improved a bit
(about 15 Hz) . Even though i have to set the reduction factor to 4.
Whenever i try to use a grater factor, let's say 8x or 16x, the
performance decreases. I got the best results with the following parameters:
* Image resample from 512x512x100 to 256x256x100 setting the output
extent to 256x256x5.
* Reduction factor = 4. Grid spacing 4x and extent reduced by same factor.
* InterpolationModeToLinear
* GridScalarTypeToFloat
I think i will try to use GPU-based calculation, with VTKEdge package. I
have already used VTKEdge for Volume Rendering and the results are
great. Any hint on how to do image warping with VTKEdge?
Thanks for all,
Jorge
David Gobbi escribió:
> Hi Jorge,
>
> I notice that in vtkTransformToGrid, you are creating a grid that has
> the same resolution as the input. That defeats the purpose of using
> vtkTransformToGrid, since it means that you are evaluating the thin
> plate spline for every voxel in the image. You should set the
> vtkTransformToGrid spacing to 8x or even 16x the image spacing, and
> reduce its extent by the same factor. Then, for vtkGridTransform use
> SetInterpolationModeToCubic().
>
> Also, you might see some small improvements with
> SetGridScalarTypeToFloat(). That will speed up the creation and
> evaluation of the grid transform.
>
> David
>
>
> On Fri, Apr 9, 2010 at 4:19 AM, Jorge Ballesteros
> <jballesteros at motivando.me> wrote:
>
>> Hi David,
>>
>> As you indicated I have rescaled the image to 256x256x98 and the performance
>> is better. For an 256x256x3 input image the warping frame rate is about
>> 25Hz.
>>
>> Even though is a big improve, i would like to keep on improving the
>> performance, but not downsampling the image. I am using
>> vtkThinPlateTransform as the the input to a vtkTransformToGrid and then
>> using a vtkGridTransform as the reslice transform to the vtkImageReslice
>> filter. I have been trying several pipelines but this is the one that
>> returns the best results. Not sure if these are the proper functions to
>> perform a 3D image warp. Am i right? Below is an extract of the code:
>>
>> vtkSmartPointer< vtkDICOMImageReader> reader =
>> vtkSmartPointer<vtkDICOMImageReader>::New();
>> reader->SetDirectoryName(argv[1]);
>> reader->Update();
>>
>> vtkImageData * input = reader->GetOutput(); //256x256x3
>>
>> Downsampling...
>>
>> double point[3];
>> double target[3];
>> ...
>>
>> int limit = 15;
>>
>> vtkSmartPointer< vtkPoints > p1 = vtkSmartPointer< vtkPoints >::New();
>> p1->InsertNextPoint(point[0]-limit, point[1], point[2]);
>> p1->InsertNextPoint(point[0], point[1]+limit, point[2]);
>> p1->InsertNextPoint(point[0]+limit, point[1], point[2]);
>> p1->InsertNextPoint(point[0], point[1]+limit, point[2]);
>> p1->InsertNextPoint(point[0]-limit, point[1]-limit, point[2]);
>> p1->InsertNextPoint(point[0]-limit, point[1]+limit, point[2]);
>> p1->InsertNextPoint(point[0]+limit, point[1]-limit, point[2]);
>> p1->InsertNextPoint(point[0]+limit, point[1]+limit, point[2]);
>> p1->InsertNextPoint(point[0], point[1], point[2]);
>>
>> vtkSmartPointer< vtkPoints > p2 = vtkSmartPointer< vtkPoints >::New();
>> p2->InsertNextPoint(point[0]-limit, point[1], point[2]);
>> p2->InsertNextPoint(point[0], point[1]+limit, point[2]);
>> p2->InsertNextPoint(point[0]+limit, point[1], point[2]);
>> p2->InsertNextPoint(point[0], point[1]+limit, point[2]);
>> p2->InsertNextPoint(point[0]-limit, point[1]-limit, point[2]);
>> p2->InsertNextPoint(point[0]-limit, point[1]+limit, point[2]);
>> p2->InsertNextPoint(point[0]+limit, point[1]-limit, point[2]);
>> p2->InsertNextPoint(point[0]+limit, point[1]+limit, point[2]);
>> p2->InsertNextPoint(target[0], target[1], target[2]);
>>
>>
>> vtkSmartPointer< vtkThinPlateSplineTransform> transform = vtkSmartPointer<
>> vtkThinPlateSplineTransform>::New();
>> transform->SetSourceLandmarks(p1);
>> transform->SetTargetLandmarks(p2);
>> transform->SetBasisToR();
>>
>> //Convert the thin plate spline to a grid
>> vtkSmartPointer<vtkTransformToGrid> transformToGrid =
>> vtkSmartPointer<vtkTransformToGrid>::New();
>> transformToGrid->SetInput(transform);
>> transformToGrid->SetGridExtent(-2*limit, 2*limit, -2*limit, 2*limit, 0,
>> 0);
>> transformToGrid->SetGridOrigin(point);
>> transformToGrid->SetGridSpacing(input->GetSpacing());
>> transformToGrid->SetGridScalarTypeToShort();
>>
>> vtkSmartPointer<vtkGridTransform> gridTransform =
>> vtkSmartPointer<vtkGridTransform>::New();
>> gridTransform->SetDisplacementGrid(transformToGrid->GetOutput());
>>
>> gridTransform->SetDisplacementShift(transformToGrid->GetDisplacementShift());
>>
>> gridTransform->SetDisplacementScale(transformToGrid->GetDisplacementScale());
>>
>> vtkSmartPointer< vtkImageReslice > reslice =
>> vtkSmartPointer<vtkImageReslice >::New();
>> reslice->SetInput(input);
>> reslice->WrapOn();
>> reslice->SetResliceTransform(gridTransform);
>> reslice->SetInterpolationModeToLinear();
>> reslice->SetOutputSpacing(input->GetSpacing());
>> reslice->SetOutputExtent(0, 255, 0, 255, 0, 2);
>> reslice->Update();
>>
>> Thanks for your support,
>>
>> Jorge.
>>
>>
>> David Gobbi wrote:
>>
>>> Hi Jorge,
>>>
>>> For real-time image warping in VTK, you would probably have to go with
>>> 256x256 images in order to achieve the 10Hz goal that you are aiming
>>> for. For warping a 512x512x100 volume in real time, I think your only
>>> option would be to use the GPU.
>>>
>>> David
>>>
>>>
>>> On Thu, Apr 8, 2010 at 4:38 AM, Jorge Ballesteros
>>> <jballesteros at motivando.me> wrote:
>>>
>>>
>>>> Hello all,
>>>>
>>>> I have been trying to perform a real-time image warping with no success.
>>>> I
>>>> have managed to warp a 512x512x100 Image but the computation time it
>>>> takes
>>>> is very high. Then I extracted a portion of the image, just 3 slices and
>>>> warped the image but still don't meet real-time requirements.
>>>>
>>>> FYI i have been following VTK Examples,
>>>> Hybrid/Testing/TestGridWarp3d.tcl,
>>>> using the vtkImageReslice class with a vtkGridTransform as the input
>>>> transform and a 512x512x3 input image, obtaining a ~10 Hz frame rate.
>>>>
>>>> Don't know if there is any other way on doing this. It would be really
>>>> helpful if you could point me on how to achieve it.
>>>>
>>>> Thanks,
>>>>
>>>> Jorge
>>>>
More information about the vtkusers
mailing list