Page MenuHomePhabricator

[MultiLabel Segmentation] Paint tool does not show a contour on unlocked labels
Open, LowPublic

Description

The paint tool can be used on a label set image with multiple labels. Using the paint tool on label A while drawing on label B, the tool contour is not shown and the locked label B is not masked.
However, unlocking label B allows to "paint over" the mask of label B. While doing this with the Paint tool, the contour of the paint tool while drawing is only shown while moving the mouse outside of the label B but not if the mouse is moved inside the label B (which will be painted over, nevertheless).

To reproduce:

  • load a 3D image, open the multilabel segmentation plugin view, create a new label set image
  • create and draw a new label on the first layer
  • create and draw another label on the first layer (distinct color)
  • unlock the first label
  • use the paint tool while activating the second label
  • see how the paint tool is drawn with a red contour while painting
  • see how the red contour is not being drawn while moving the mouse inside of the first, unlocked label

Event Timeline

kalali created this task.

I guess the problem lies in the fact that the Paintbrush_Node, which is created during painting and contains the "area-to-outline", is a binary image, hence it combines the mask of label A and label B, sees it as one connected label and draws a contour around the whole segmentation.
This leads to the problem that no new outline will be drawn for the area that is newly painted over in an unlocked label, because for the binary image the unlocked label already belongs to the binary mask.

I was looking for the code where the contour of this paintbrush node is computed but I think it is just the general outline of a binary image that is drawn via the VTK image mapper 2D.
I can even set the outline to be a solid face by changing the property m_WorkingNode->SetProperty("outline binary", mitk::BoolProperty::New(true)); to false (m_WorkingNode is the Paintbrush_Node), but this does not help in this situation.

I'm still wondering why both masks are written into the paintbrush node and not only the one with the pixel value of the currently active label:
mitk::ContourModelUtils::FillContourInSlice(contour, m_WorkingSlice, workingImage, m_PaintingPixelValue * activePixelValue); should take care of this but I guess here the contour is already defined as the contour of both masks? However, as mentioned above I don't see why this contour contains both masks, as it should only consist of the circle for the brush and the newly drawn area when moving the mouse.

I think the problem lies in the call to m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone(); inside void mitk::PaintbrushTool::CheckIfCurrentSliceHasChanged(const InteractionPositionEvent *event):
Here the affected slice of the image - which is actually the current working labelsetimage - is extracted, returned and stored in a binary data node. No attention is paid to the labels so the slice with all labels is extracted and all labels are squashed into a binary label.

With the above mentioned call to FillContourInSlice the contour of the whole binary label is filled. The whole contour is used for marking the brushed area, although this area already contains labels which do not belong to the active label of the label that is currently used for brushing.

Furthermore, there is the following code:

void mitk::ContourModelUtils::FillContourInSlice(
  const ContourModel *projectedContour, TimeStepType contourTimeStep, Image *sliceImage, const Image* workingImage, int paintingPixelValue)

  ...

  const double FOREGROUND_VALUE = 255.0;
  const double BACKGROUND_VALUE = 0.0;

  const vtkIdType count = image->GetNumberOfPoints();
  for (std::remove_const_t<decltype(count)> i = 0; i < count; ++i)
    image->GetPointData()->GetScalars()->SetTuple1(i, FOREGROUND_VALUE);

where the whole (copied) image is modified such that it only contains values 0.0 or 255.0.
I'm not sure why this is done here but it opens many question and leaves me confused.