Page MenuHomePhabricator

Crash in "Create smooth polygon model" for 2-d images
Closed, ResolvedPublic

Description

  • Open 2-d image (static or dynamic)
  • Draw a segmentation
  • Data Manager context menu of segmentation: Create smooth polygon model -> crash

Insights:

No issue for 3-d images even when drawing a single slice at any border slices.

Event Timeline

kislinsk triaged this task as Normal priority.Oct 29 2021, 8:43 PM
kislinsk raised the priority of this task from Normal to High.
kislinsk created this task.

After a first look on this problem, I found out that the issue occurs because of the different dimensions between the image and the segmentation. The image is in 2D and the segmentation mask that is created is in 3D.
This can be seen when taking a normal 2D image or when working with Pic2DplusT.nrrd and creating a static segmentation mask. However, when working with Pic2DplusT and creating a dynamic segmentation mask, the Workbench does not crash (because it is 3 dimensional with time again).

Thanks for the first look. I come to a slightly different but related conclusion. Segmentations are always created with 3 or more dimensions by design choice. So, for the 2-d image, a 3-d segmentation with the third dimension set to 1 is created. Checking the dimension of that segmentation image returns 3 as expected.

Before the 2-d image is considered at all, already in mitk::LabelSetImage::CreateLabelMask(), the mask for the label that is created is wrongly initialized as 2-d image and it is hard to understand without looking into the questionable implementation of the image initialization.

Image initialization has 8 overloads and the one chosen here just passes the label set image as reference for everything related to geometry/dimensions. So it should work, right? - Wrong! It ends up in the initialization of mitkImage.cpp around line 853: The dimensions are written correctly into the dimensions array but then a wrong generalization is made:

unsigned int dimension = 2;
if (dimensions[2] > 1)
  dimension = 3;
if (dimensions[3] > 1)
  dimension = 4;

With this overload of Initialize(), a 3-d image with only one slice can never be initialized as a 3-d image, but instead is automatically flattened to 2-d. Usually I would say this is straight up an error but I guess changing it here could have unforeseen consequences for existing code.

The alternative is to use another overload of Initialize() that explicitly sets the dimensions and the dimensions array:

mitkLabelSetImage.cpp:611 (before)
mask->Initialize(this);
mitkLabelSetImage.cpp:611 (after)
mask->Initialize(this->GetPixelType(), this->GetDimension(), this->GetDimensions());

Now the generated mask has its dimensions set as expected.

However, another error is now triggered down the pipeline regarding dimensions and the vtkMarchingCubes filter, which I will now investigate...

Turns out that VTK has the same issue as MITK in a few filters regarding recognizing a 3-d image as such when it has only a single slice. To fix it, I also added a check in the corresponding MITK filter that adds an empty pad slice to an intermediate pipeline image output for single-sliced images. Also, the result of the filter pipeline is now checked more thoroughly whether it is containing actual surface data or not. If there is no surface data, no surface node is created but instead a warning is printed for all affected labels and a hint is given to try again without smoothing (smoothing does always smooth out single slices completely).