Hello.
I am trying using itk::WatershedImageFilter (https://itk.org/Doxygen/html/classitk_1_1WatershedImageFilter.html), and I have some question about the parameter. I would like to control precisely the number of regions that return the filter. Is it possible with this filter? So if it is possible, how can I do that?
I did not precisely understand the Threshold parameter, is it possible to have more information about it.
To control the number of the region, we can use a seed watershed, so I also try the itk::MorphologicalWatershedFromMarkersImageFilter (https://itk.org/Doxygen/html/classitk_1_1MorphologicalWatershedFromMarkersImageFilter.html), but it connects some region whose have tall border. So it does not give me the result i want.
Thanks a lot for your help.
Best regards
The Level parameter can be used to create a hierarchy of output images in constant time once an initial segmentation is done. A typical scenario might go like this: For the initial execution of the filter, set the Level to the maximum saliency value that you anticipate might be of interest. Once the initial Update() of this process object has finished, the Level can be manipulated anywhere below the initial setting without triggering a full update of the segmentation mini-pipeline. All that is now be required to produce the new output is a simple relabeling of the output image.
The above paragraph is from the Watershed filter’s documentation. There is no direct way to control the number of segments, but you can use the described trick to iteratively narrow down segments to the number you want. Just increase/decrease level and call Update()
again.
Hello
thanks for your answer but dosn’t solve my problem.
I’d like to have some more infirmation about the both parameter : threshold and level. I’don’t understand how they work.
I’d like to know also why MorphologicalWatershedFromMarkersImageFilter does not find the tall border, even the one created.
I did not understand threshold and level just from description either. So pick an image, pass it through the watershed filter with different parameters and then you will understand the effect they have. Here is an ad-hoc example I used:
#include "itkWatershedImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.h"
//C:\Dev\itk-snap-src\Testing\TestData\WB.nrrd wb-seg.nrrd 0.01 0.4
int main(int argc, char *argv[])
{
if (argc < 5)
{
std::cerr << "Missing Parameters " << std::endl;
std::cerr << "Usage: " << argv[0];
std::cerr << " inputImage outputImage lowerThreshold outputScaleLevel" << std::endl;
return 1;
}
typedef short InPixelType;
typedef float InternalPixelType;
const unsigned int Dimension = 3;
typedef itk::Image< InternalPixelType, Dimension > InternalImageType;
typedef itk::Image< InPixelType, Dimension > InImageType;
typedef itk::ImageFileReader< InImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(argv[1]);
reader->ReleaseDataFlagOn();
reader->Update();
typedef itk::GradientMagnitudeRecursiveGaussianImageFilter<
InImageType,
InternalImageType
> GradientMagnitudeFilterType;
GradientMagnitudeFilterType::Pointer gradientMagnitudeFilter = GradientMagnitudeFilterType::New();
gradientMagnitudeFilter->SetInput(reader->GetOutput());
gradientMagnitudeFilter->SetSigma(1.0);
gradientMagnitudeFilter->ReleaseDataFlagOn();
gradientMagnitudeFilter->Update();
typedef itk::WatershedImageFilter<InternalImageType> WatershedFilterType;
WatershedFilterType::Pointer watershedFilter = WatershedFilterType::New();
watershedFilter->SetInput(gradientMagnitudeFilter->GetOutput());
watershedFilter->SetThreshold(atof(argv[3]));
watershedFilter->SetLevel(atof(argv[4]));
watershedFilter->Update();
typedef WatershedFilterType::OutputImageType LabeledImageType;
typedef itk::ImageFileWriter< LabeledImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(argv[2]);
writer->SetInput(watershedFilter->GetOutput());
try
{
writer->Update();
}
catch (itk::ExceptionObject & excep)
{
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
}
return 0;
}
In general the morphological watershed filters result in a much better segmentation.
For more information on the morphological watersheds and their parameters, see this Insight Journal article: