erosion does not erode the image. It returns the same binary image as the input

(esme) #1

Hi

I am writing because i am trying to erode the image obtained after a threshold to avoid the leakage between 2 objects. Like the example of two coins merged in one and the erosion splits them into two coins. But my problem is that it does not erode the image. It returns the same image as the input with no erosion. I have tried many radius, but the image is exactly the same as the input. No erosion at all. The image is binary as expected.

Thank you very much

using FilterTypeThresh =
	itk::BinaryThresholdImageFilter<ImageType, ImageType>;
FilterTypeThresh::Pointer thresholding = FilterTypeThresh::New();
thresholding->SetInput(ROISegm->GetOutput());
thresholding->SetLowerThreshold(-1000);
thresholding->SetUpperThreshold(300);
thresholding->SetOutsideValue(0);
thresholding->SetInsideValue(1);
    thresholding->Update();

unsigned int radius = 15;
typedef itk::BinaryBallStructuringElement<ImageType::PixelType, ImageType::ImageDimension> StructuringElementType;
StructuringElementType structuringElement;
structuringElement.SetRadius(radius);
structuringElement.CreateStructuringElement();

using BinaryErodeImageFilterType = itk::BinaryErodeImageFilter< ImageType, ImageType,StructuringElementType >;

BinaryErodeImageFilterType::Pointer erodeFilter = BinaryErodeImageFilterType::New();
erodeFilter->SetInput(thresholding->GetOutput());
erodeFilter->SetKernel(structuringElement);
erodeFilter->Update();
(esme) #2

I also tried to change the inside value of both filters and nothing

thresholding->SetInsideValue(255);
erodeFilter->SetErodeValue(255);

The whole code is as follows:

using FilterTypeThresh = itk::BinaryThresholdImageFilter<ImageType, ImageType>;
FilterTypeThresh::Pointer thresholding = FilterTypeThresh::New();
thresholding->SetInput(ROISegm->GetOutput());
thresholding->SetLowerThreshold(-1000);
thresholding->SetUpperThreshold(300);
thresholding->SetOutsideValue(0);
thresholding->SetInsideValue(255);

unsigned int radius = 5;

typedef itk::FlatStructuringElement<2> StructuringElementType;
StructuringElementType::RadiusType elementRadius;
elementRadius.Fill(radius);

StructuringElementType structuringElement = StructuringElementType::Box(elementRadius);

using BinaryErodeImageFilterType = itk::BinaryErodeImageFilter< ImageType, ImageType,
	StructuringElementType >;

BinaryErodeImageFilterType::Pointer erodeFilter =
	BinaryErodeImageFilterType::New();
erodeFilter->SetInput(thresholding->GetOutput());
erodeFilter->SetKernel(structuringElement);
erodeFilter->SetForegroundValue(255);
erodeFilter->Update();

Ad i write the output of the filters an no erosion at all and the foreground of the threshold output is 255.0 and 0.0 background.

Thanks

(Francois Budin) #3

@zandarina: Could you share the image you are trying to apply this filter on? Specifically, could you same the output or ROISegm?

I recreated your filter in Python (see code below) and it worked great for me. The input image was taken from inside the ITK source tree but I still uploaded here to make it easier for anyone to recreate the output images using my script to compare. I have installed the latest version of ITK Python (pip install itk --pre) but I expect this to work with any ITK version.

Input image:
FaceBoundaryCalculator
Thresholded image:
thresholded
Eroded image:
erode

#!/usr/bin/env python

import itk


image = itk.imread("FaceBoundaryCalculator.png", itk.UC)

thresholding = itk.BinaryThresholdImageFilter[image, image].New()
thresholding.SetInput(image)
thresholding.SetLowerThreshold(0)
thresholding.SetUpperThreshold(50)
thresholding.SetOutsideValue(0)
thresholding.SetInsideValue(255)

radius = 1

StructuringElementType = itk.FlatStructuringElement[2]

structuringElement = StructuringElementType.Box(radius)

erodeFilter = itk.BinaryErodeImageFilter[image, image, StructuringElementType].New()
erodeFilter.SetInput(thresholding.GetOutput())
erodeFilter.SetKernel(structuringElement)
erodeFilter.SetForegroundValue(255)
erodeFilter.Update()

print thresholding.GetOutput()

print thresholding.GetOutput().GetPixel([0,0])
print thresholding.GetOutput().GetPixel([230,170])

itk.imwrite(thresholding.GetOutput(), "/tmp/thresholded.png")

itk.imwrite(erodeFilter.GetOutput(), "/tmp/erode.png")
1 Like
(esme) #4

Hi thank you for answering. It works now. In my itk version, i have to add

erodeFilter->SetBackgroundValue(0);

otherwise, it doesn´t work. I realized because i debugged the itk erosion function and i was getting a negative value for the background value when

i defined the background and foreground output in the threshold filter. I do not have clear why.

Thank for your quick answer

(Bradley Lowekamp) #5
1 Like
(esme) #6

Sure, but if i set up the input of the erostion the threshold output as:

thresholding.SetUpperThreshold(255)
thresholding.SetOutsideValue(0)

I cant understand this negative value. Can it be a bug?

Thanks

(Francois Budin) #7

@zandarina: When changing the thresholding filter upper threshold to 255, like you suggested, I simply get a white image (255 everywhere). Are you working with a different image then the one I provided? If so, could you share it?