Page MenuHomePhabricator

Make rendering of binary segmentations as outline faster - v2
Closed, ResolvedPublic

Description

This ticket is a continuation of T12691.

The rendering of binary segmentation in binary outline mode is currently very slow. A huge amount of time is spent in the method CreateOutlinePolyData() as it accesses all pixels using 'random access'. This is slow and should be changed to use a normal iterator.

Event Timeline

As stated in the description, loads of time is spent for the computation of the actual outline from the segmentation.

This is due to the excessive use of vtkImageData::GetScalarPointer(x, y, 0) as this is a slow random-access operation.

The fix is quite simple. Get yourself the pointer to the first pixel in the data-array and increase the pointer after each iteration in the while-loop.

I tested the code and compared the runtime using the itk::TimeProbe.
Depending on the dataset and the dimensions of the binary-image, the computation-time was up to 60 times faster (average about 30 times faster).

The resulting outline was not distinguishable from the original one.

I have attached a patch with the necessary changes.

Sounds good to me.

@Tobi: You worked a lot with this stuff. Can you please double-check this?

Could you add a runtime-check, that the pixel/pointer type is correct?

@Joseph: is there a "nicer" solution using the image accessors, especially considering the performance?

I would prefer a save accessor too if one exist that is as fast as accessing the pixels by a pointer.
But actually I don't think that the usage of is a problem as only read access is performed. The worst case would be that in another thread someone changes some values inside the image volume. What causes the outline to be somehow wrong. Keep in mind that only the volume can be changed by someone else. The slice (within CreateOutlinePolyData) extracted within GenerateData is a COPY and thus nobody will ever have the object. So after next update was performed everything is fine again.

What kind of accessor did you have in mind.

Right now, a pixel-type check is not really necessary as the method CreateOutlinePolyData() is only called for 'char-images' anyway. See method ImageVtkMapper2D::GenerateDataForRenderer().

As I said in comment #5 there is a runtime check. So this shouldn't be a problem.

Ans as Tobias said, there should be no problem as this code is read-only.

I think the fix of Markus is a significant improvement and with the run-time check regarding pixel types, it is safe enough to be integrated. If Joseph comes up with a better/safer way, we can definitely adopt it, but I guess this will take some time, right?

[f5f36b]: Merge branch 'bug-13137-fast-outline-creation'

Merged commits:

2012-10-15 16:29:24 Markus Engel [5aef6d]
using pointer magic to iterate over image instead of random-access operation

I merged the fix into master. Issue is resolved, but is closed.

(In reply to comment #7)

I think the fix of Markus is a significant improvement and with the run-time
check regarding pixel types, it is safe enough to be integrated. If Joseph
comes up with a better/safer way, we can definitely adopt it, but I guess
this will take some time, right?

In general the accessor code is easy to use and does not take extra run time. Looking at the implementation I saw it's a VTK image anyway so there are no accessors. But please keep in mind we want to get rid of uncontrolled pointer access to MITK images and the accessor concept exists.