Overlaying Segmented mask with color over Input Vtkimagedata 3D (Dicom series)

Hi all ,
I am working with ITK Segmentation algorithm’s. My input is a Dicom series and I used VtkDicomReader to get the vtkimagedata and then I converted to itkimage(Short, dmension=3) and I used connected threshold region growing algorithm and I am having the segmented output(itk::image<short,3) . I need to give red color to this segmented output and need to overlay this mask over Input data. I have tried different methods … Everywhere it is saying to convert to 2D slice and then to RGBimagetype… Is there any way to give color to 3D segmented output(vtkimagedata) and overlay over the input without any type conversion and loss of information…

Could Anyone please help with this?

Take a look at these examples:
https://itk.org/ITKExamples/src/Filtering/ImageFusion/OverlayLabelMapOnTopOfAnImage/Documentation.html
https://itk.org/ITKExamples/src/Filtering/ImageFusion/OverlayLabelMapOnImage/Documentation.html
and this notebook (which was written in SimpleITK, but should be easy to translate into ITK):
http://insightsoftwareconsortium.github.io/SimpleITK-Notebooks/Python_html/05_Results_Visualization.html

Hi Thank you so much for your reply…

I have already tried LabelMapOverlayImageFilter. The problem is my input is a dicom data having around 300 slices . This filter is only accepting 2d images … Also for adding color I had to convert the type from short to unsigned char and the rescale the data to 0-255 which will cause a lot of information loss. I am not sure if it is the correct way of doing . Is there any other way to overlay the mask with color without changing my original input.

I also tried doing this for each slice. Please see the code below

    myitkImageDatasegUshort = connectedThresholdFilterUshort->GetOutput();
	inputRegion = myitkImageDatasegUshort->GetLargestPossibleRegion();
	size = inputRegion.GetSize();
	auto slice = size[2];
	size[2] = 0;
	start = inputRegion.GetIndex();
	for (int slices = 0; slices < slice; ++slices)
	{
		start[2] = slices;
		desiredRegion.SetSize(size);
		desiredRegion.SetIndex(start);
		
		
		ExtractFilterM->SetInput(connectedThresholdFilterUshort->GetOutput());
		ExtractFilterM->InPlaceOn();
		ExtractFilterM->SetDirectionCollapseToSubmatrix();
		ExtractFilterM->SetExtractionRegion(desiredRegion);
		ExtractFilterM->UpdateOutputInformation();
        rescalefilterrrM->SetInput(ExtractFilterM->GetOutput());
		rescalefilterrrM->Update();

		ExtractFilterIn->SetInput(myitkImageDataUshort);
		ExtractFilterIn->InPlaceOn();
		ExtractFilterIn->SetDirectionCollapseToSubmatrix();
		ExtractFilterIn->SetExtractionRegion(desiredRegion);
		ExtractFilterIn->UpdateOutputInformation();
		
		rescalefilterrrIn->SetInput(ExtractFilterIn->GetOutput());
		rescalefilterrrIn->SetOutputMinimum(0);
		rescalefilterrrIn->SetOutputMaximum(255);
		rescalefilterrrIn->Update();
		RGBFilter->SetInput(rescalefilterrrM->GetOutput());
		RGBFilter->SetColormap(FilterScalartoRGB::Red);
		RGBFilter->Update();

		RGBFilter1->SetInput(rescalefilterrrIn->GetOutput());
		//RGBFilter1->SetColormap(FilterScalartoRGB::Blue);
		RGBFilter1->Update();


		vtkImageData* colormask = mitkVtkConnector->Itk_Connect_Vtk3(RGBFilter->GetOutput());
		vtkImageData* FeatureImage = mitkVtkConnector->Itk_Connect_Vtk3(RGBFilter1->GetOutput());

		vtkSmartPointer<vtkImageBlend> imgBlender =
			vtkSmartPointer<vtkImageBlend>::New();
		imgBlender->AddInputData(FeatureImage);
		imgBlender->AddInputData(colormask);
		imgBlender->SetOpacity(1, 0.3);
		imgBlender->SetOpacity(0, 0.5);
		imgBlender->Update();
    }

Now this imgBlender output is having the overlayed data with color. But this is a single slice… Now for visualisation I need a Vtkimagedata having all the slices … Is there a way to generate a single 3D data from all these slices. ?
Also Is there any alternate approach for doing this without rescaling the original input ?

If you change

constexpr unsigned int Dimension = 2;
using PixelType = unsigned char;

from C++ example to match your case (d=3 and ushort), does it work? All of the filters involved should work with 3D case, too.

Hi ,
All the filters is working except the one which are using itkRGBpixel which is the one used for coloring. itk:scalartoRGBcolormap filter only works for 2d images… (dimension = 2 , type = unsigned char).
If I changed the imagetype to 3 dimension I am getting an error

What is the error message? ScalarToRGBColormapImageFilter should work for 3D and nD images.

When I am trying for dimension 3 … I am getting these errors …

I guess the error is coming from here. But that is probably an MITK class, and you should probably ask for help on their mailing list.

Hi ,
That is not an mitk class… That is a custom class I have written for itk-vtk conversion… The error is coming only when I change the dimension of RGB filter type to 3…
Please see the declaration below
using FilterScalartoRGB1 = itk::ScalarToRGBColormapImageFilter<ImageTypeUchar, ImageTypeUchar>;
FilterScalartoRGB1::Pointer RGBFilter2 = FilterScalartoRGB1::New();
Here ImageTypeUchar = itk::Image<unsigned char, 3>;
If I used ImageTypeUchar = itk::RGBPixel
Then I am not getting an error…

using FilterScalartoRGB1 = itk::ScalarToRGBColormapImageFilter<ImageTypeUchar, ImageTypeUchar>;

should be changed into

ImageTypeRGB = itk::Image<itk::RGBPixel<unsigned char>, 3>;
using FilterScalartoRGB1 = itk::ScalarToRGBColormapImageFilter<ImageTypeUchar, ImageTypeRGB>;

Thank you so much … It worked …

I have one more doubt. This colored mask I was able to overlay over input data using vtkimageblender.
The only problem is , only after rescaling the input data [short(0-65000)] to [ImagetypeRGB(0-255)] . I was able to see the output…
Is there any other way to overlay this colored mask over the original input without any changes in the datatype or scalar range of the input.

Have you tried FilterScalartoRGB1->UseInputImageExtremaForScalingOn();? If that does not work, the solution is probably in setting a custom colormap function via SetColormap() and fiddling with it.

Hi,
I tried UseInputImageExtremaForScalingOn(). It is not working… Only after rescaling the data to 0-255 … I am able to see the color mask overlayed over the input.

Can you help me for getting the intensity value of a particular point from indexCoordinates?

This can be obtained with Image::GetPixel.

Thank you so much for helping.

1 Like