[vtkusers] vtk memory issue, support needed
David Gobbi
david.gobbi at gmail.com
Thu Jul 29 11:29:49 EDT 2010
You are correct. When viewing only axial slices of an axial dataset,
VTK should stream the images slice-by-slice. It's important that you
never call Update() on an image in your own code with setting the
UpdateExtent first, since Update() will update the WholeExtent by
default in the UpdateExtent is not set.
Regarding the viewer, I looked through vtkImageViewer2.cxx and saw
this code at line 478:
if (event == vtkCommand::ResetWindowLevelEvent)
{
this->IV->GetInput()->UpdateInformation();
this->IV->GetInput()->SetUpdateExtent
(this->IV->GetInput()->GetWholeExtent());
this->IV->GetInput()->Update();
double *range = this->IV->GetInput()->GetScalarRange();
this->IV->SetColorWindow(range[1] - range[0]);
this->IV->SetColorLevel(0.5 * (range[1] + range[0]));
this->IV->Render();
return;
}
I suspect that this code is the problem. This is one of the reasons
that I never use vtkImageViewer and always use a raw vtkImageActor
instead. The ImageViewer has a lot of "convenience" features that
people have added to make their lives easier, and these convenience
features often have unexpected side effects.
David
2010/7/29 Raúl Ferriz <raul at torresyvalero.com>:
> [I attach a private email, sorry for not sending directly to the list]
>
> I have been done some tests. Having only one vtkImageViewer2 on Axial axis
> (XY the default) when I call vtkImageViewer2->Render() viewet request all
> data to vtkGDCMImageReader and thows Out of mem exception (vtkIntArray
> (0BA636B8): Unable to allocate 154157056 elements of size 4 bytes). As far
> as I can understand your explanation, this should not happen. Each slice is
> 776x776 pixels, and I have 256 slices ... If I do 776x776x256 ... yeah
> 154157056 !! So, vtkImageViewer2 calls Update() / UpdateWholeExtent() / or
> another command or function that request all data, is this a bug?. On gdcm
> list Mathieu Malaterre says that vtkGDCMImageReader implements
> RequestUpdateExtent, so if vtkImageViewer2 only request required slice, that
> should not break out. Or I miss something?
>
> I am doing all this test to try understand how internally vtk works and try
> to develop that vtkImageCache class, but I must admit that is very difficult
> to me understand where to start! :(
>
> El 19/07/2010 18:06, David Gobbi escribió:
>>
>> I see. So, yes, you would need something like the vtkImageCache that
>> I suggested, it would go right after the reader. Note that
>> vtkImageCache is just "hypothetical", I don't know if anyone has
>> written such a thing.
>>
>> The vtkImageCache would just be a way of storing data in a
>> non-contiguous array. So, for example, it could store each slice in a
>> separate block of memory. But is also has to do streaming, e.g. it
>> has to pull its input data through the pipeline slice-by-slice. Also,
>> any filters that take its output would have to request only
>> smallish-sized parts of the data. The vtkImageViewers would be fine,
>> because they request only one slice of data at a time. The
>> vtkImageShrink3D would be a problem, because by default it will try to
>> request the entire image at once from its input, so there would have
>> to be a vtkImageDataStreamer after the vtkImageShrink3D to force it to
>> request the data in smallish chunks.
>>
>> David
>>
>>
>> 2010/7/19 Raúl Ferriz<raul at torresyvalero.com>:
>>
>>>
>>> El 19/07/2010 15:07, David Gobbi escribió:
>>>
>>>>
>>>> On Mon, Jul 19, 2010 at 5:13 AM, Raúl Ferriz<raul at torresyvalero.com>
>>>> wrote:
>>>>
>>>>
>>>>>
>>>>> Hello again!
>>>>>
>>>>> I'm developing a testing application that should load a DICOM series,
>>>>> and
>>>>> display 3 views on 3 render windows (axial, saggittal and coronal). And
>>>>> on a
>>>>> fourth render window I want to display a 3D view of the DICOM.
>>>>>
>>>>> My pipeline is just this:
>>>>>
>>>>> vtkGDCMImageReader -> vtkChangeInformation --> vtkImageShrink3D
>>>>> ->
>>>>> vtkContourFilter -> vtkPolyDataMapper -> vtkActor
>>>>> \-> vtkImageViewer2 (to
>>>>> show
>>>>> slice
>>>>> axial)
>>>>> |-> vtkImageViewer2 (to
>>>>> show
>>>>> slice
>>>>> saggittal)
>>>>> \-> vtkImageViewer2 (to
>>>>> show
>>>>> slice
>>>>> coronal)
>>>>>
>>>>> All, but vtkImageViewer2 and vtkActor, has ReleaseDataFlagOn to ensure
>>>>> little memory footprint.
>>>>> My problem is when I try to load a big DICOM series, or when I load an
>>>>> unload many DICOM series, seems that memory get fragmentated or
>>>>> something
>>>>> like and throws an exception, looking at logs last line is
>>>>> "vtkDoubleArray
>>>>> (07FB1DD0): Unable to allocate 67371008 elements of size 8 bytes." I
>>>>> have
>>>>> 2gb ram, and also a lot of free swap.
>>>>>
>>>>>
>>>>> On vtkusers forum David Gobby suggested:
>>>>> "
>>>>> El 15/07/2010 19:15, David Gobbi escribió:
>>>>>
>>>>>
>>>>>>
>>>>>> The quick answer about VTK splitting memory is that VTK image filters
>>>>>> require the image data to be contiguous in memory. So splitting is
>>>>>> not possible. In summary, large images and Win32 are a bad
>>>>>> combination in VTK, due to memory fragmentation and the 2GB limit
>>>>>> mentioned by John.
>>>>>>
>>>>>> Actually, I shouldn't speak in absolutes. Splitting the volume is
>>>>>> possible, but you would have to write a VTK class that would act as a
>>>>>> "cache" that contained the volume split into chunks, but that could
>>>>>> produce contiguous UpdateExtent-sized slabs for use by its consumers.
>>>>>> As long as the downstream filters only requested one slice at a time
>>>>>> (or were streamed to only require reasonable-sized blocks) then huge
>>>>>> blocks of contiguous memory would never be needed.
>>>>>>
>>>>>> David
>>>>>>
>>>>>>
>>>>>
>>>>> "
>>>>>
>>>>> The fact is that I don't know really know how to implement or use that
>>>>> "cache" class and where on the pipeline should be placed. I think that
>>>>> it
>>>>> should be placed just after vtkChangeInformation, but I'm not really
>>>>> sure.
>>>>>
>>>>> If this question only can be answered by "Incident support", please
>>>>> tell
>>>>> me.
>>>>>
>>>>> Many thanks for your time!
>>>>>
>>>>>
>>>>
>>>> Raul, you should consider whether you can solve your problem by adding
>>>> a vtkImageDataStreamer after your vtkImageShrink3D. If you do all
>>>> your rendering from the shrunk image, and never from the full-size
>>>> DICOM, then all you need to do is stream the data into the
>>>> vtkImageShrink3D so that only the shrunk image is fully stored in
>>>> memory (it will be stored in the output of vtkImageDataStreamer, which
>>>> will be the branch point to the pipelines for each view).
>>>>
>>>> The "cache class" would only be needed if you wanted to render
>>>> full-resolution slices of the image. If you do all your rendering
>>>> after shinking the images, then it would not really be needed.
>>>>
>>>> David
>>>>
>>>>
>>>>
>>>
>>> Excuse me, but I only want to send yo a graphic pipeline of my pipeline
>>> (sorry for redundance) because I am not sure that is displayed correctly
>>> on
>>> messages.
>>> Basically, vtkImageViewer2s and vtkImageShrink3D consumes output from
>>> vtkChangeInformation.
>>>
>>> I want to display full resolution for 3 vtkImageViewer2 and also big
>>> resolution 3d view.
>>>
>>> Many thanks.
>>>
>>>
>>
>>
>
>
More information about the vtkusers
mailing list