Page MenuHomePhabricator

MITK Workbench freezes on 4-d images with empty time steps
Closed, ResolvedPublic

Description

The reading itself seems to work but as soon as the image is added to the data storage, the application freezes (mitkAbstractFileReader.cpp:125).

Revisions and Commits

rMITK MITK
Restricted Differential Revision
Restricted Differential Revision
Restricted Differential Revision
Restricted Differential Revision
Restricted Differential Revision
Restricted Differential Revision

Related Objects

Event Timeline

kislinsk triaged this task as High priority.Jul 3 2024, 9:42 AM
kislinsk created this task.

The freeze happens at the end of QmitkSliderLevelWindowWidget::resizeEvent() or QmitkSliderLevelWindowWidget::Update() resp. QWidget::repaint() but we need to install the debug files of Qt (Qt6Widgetsd.pdb) for further investigation.

The problem is in QmitkSliderLevelWindowWidget::paintEvent.
The example data lead to a level window range that 2*10^300 and that is why the painting takes for ages because it iterates exhaustively and it does not make realy sense.

Sounds like a default value initialized with max possible value and the assumption that it would always be set to the actual value later on? How did you step into QmitkSliderLevelWindowWidget::paintEvent()? I always get stuck right before in Qt6Widgets.

"Empty time steps" turn out be be represented by frames filled with NaN (double). And I think this is the issue. Here's the file were I replaced all NaNs with 0s:

The origin of the huge level window range is the calculation of the image statistics in mitkImageStatisticsHolder.cpp:100. The function template mitk::_ComputeExtremaInItkImage() is supposed to calculate the extrema and 2nd largest/smallest extrema as well as their counts. However, it does not check for NaN and compares it against the default values (itk::NumericTraits<>::max() resp. NonpositiveMin()). Hence, these extrema stay at their initial default values.

How would we like to handle the situation?

  • I guess we should check for NaN for each pixel value and skip it.
  • Probably track if any valid value was found at all during the pixel iteration.
  • Change the statistics values in this case? Check in level window for max()? and NonpositiveMin() and use a predefined "maximum maximum" and a "minimum minimum"? I think there's already a smallest possible value used in the level window like 1e-9.

I think I found an adequate solution:

  • Track in statistics calculation if any valid value has been found
  • If it's not the case, set min and max to the same value, which is already explicitly handled as edge case appropriately
  • Extend the heuristic in LevelWindow::SetAuto() by another cascade, i.e. after the central slice didn't lead to a result, the whole image at time step 0 is already checked, and now: if this also fails the time steps are iterated to search for valid values
kislinsk added a revision: Restricted Differential Revision.Jul 4 2024, 10:40 AM

Deleted branch from rMITK MITK: bugfix/T30485-HandleNaNImages.