Page MenuHomePhabricator

Make rendering of segmentations as outline faster
Closed, ResolvedPublic

Description

The current implementation of the ImageVtkMapper has serious performace issues when rendering binary images as an outline.

I had a look at the code, did some profiling and came to the conclusion that the biggest problem is the creation of the vtkPolyData that represents the outline of the binary image. To check this, I switched the 'binary outline' property to 'false' and had the segmentation rendered as 'normal' image. Here I saw no performance issues.

The biggest chunk of time seems to be spent in vtkImageData::GetScalarPointer(). A better way of creating the outline or accessing the pixel data is needed to increase the performance.

Furthermore I noticed that the performance is bad even if the segmentation is not even displayed. e.g. when you create a segmentation at the top of the image and scroll around in the lower part of the image.
That's because the mapper does not even check if there is something to render for the current rendering geometry. An easy way to fix this would be to check for an intersection of the 2D rendering geometry with the 3D geometry of the segmentation. If there is no intersection there is nothing to render and we can early out.

Event Timeline

We did not experience any crucial issues regarding performance of binary outline, yet.

Basically, the we do the same pointer operations like the former IIL, but also create the vtkPolyData AND fixed some serious bugs (which have been in the IIL pointer magic).

Can you please describe the circumstances when the outline binary is too slow? Which image, which OS, how many segmentations, during which operations (e.g. zooming)?

I spend some time to find alternatives for creating the vtkPolyData. There are some filters in VTK, but none is meant to produce exactly what we want. I think I can support you here.

I have a DICOM image of 108 slices (0.73*0.73 / 4mm) and one Volume of a liver lesion. The performance problem is noticable if you compare the scrolling speed between having one segementation and having NO segmentation.

It's easily reproducable:

  • Merge branch 'bug-12691-slow-outline-rendering' -> small fix for the second issue described in the description (rendering although there is nothing to render for the current slice)
  • Load a DICOM image and a segmentation (several slices, about 30*30 mm)
  • Segmentation needs to be displayed as binary outline!!!
  • Turn on th PACS like interaction (normal scrolling with the mousewheel is too slow)
  • Scroll through an area of the image without segmentation by pressing the mousewheel and moving up & down
  • Scroll to the area with the segmentation

    -> as soon as you reach the segmentation the performance will reduce

The effect is stronger of you have 2 or 3 segmentations in the same area.
For comparison, turn off the binary outlining and repeat the steps above -> performance is not reduced noticably!

By the way, it's Windows 7 but I don't think that's a problem.

Concerning the algorithm, I agree that the pointer magic is correct and produces the results we desire (unlike most vtk solutions). The big problem I see is how we access the pixel values. According to the profiling, almost half of the time is spent in the CreateOutlinePolyData() method. There almost all the time is spent in GetScalarPointer().

--> almost have the time of the rendering is spent in the accessing the pixel values. Isn't there any kind of iterator that just needs increasing? If I remember correctly, that's what the IIl did. access the pixel values by pointer magic as well...

Markus already has some changes that already removes rendering of completely obviously invisible images. To integrate this early, I grant the Needs_Core_Modification, which will be reset after his merge. When a method for actually rendering faster is designed, a proper change request should be written.

[0a37bc]: Merge branch 'bug-12691-slow-outline-rendering'

Merged commits:

2012-07-30 14:48:44 Markus Engel [eba1f9]
setting 'empty' polydata instead of NULL to avoid VTK error


2012-07-20 10:44:36 Markus Engel [c0d3eb]
not rendering if rendering plane does not intersect image geometry

As Daniel already said, I made some changes to the ImageVtkMapper2D to boost up the performance if the scene contains several images.

I noticed that the imageMapper tries to actually render the image even if the current Geometry2D does NOT intersect the Geometry3D of the image.
In this case, there is nothing to render, so why bother to try at all.

I added a new Method ImageVtkMapper2D::RenderingGeometryIntersectsImage( const Geometry2D* renderingGeometry, SlicedGeometry3D* imageGeometry ) that can be used to check if the given Geometry2D intersects the given Geometry3D.

If this is not the case, the mapper will return early and save some time. These changes are very noticable when scrolling fast through a scene that contains several segmentations that are displayed as outlines.

I reset the core-modification flag as a real solution to the problem still needs to be found.

In this bug, the rendering performance has been improved for the parts of the image where no binary segmentations are located.

The actual problem (that the rendering of binary outlines is very slow) still remains. To fix it, I have created T13137.

This Bug can be closed.