[Insight-users] watershed segmentation without RGB?

Laurent Mundeleer lmundele at ulb.ac.be
Fri, 30 Apr 2004 14:38:06 +0200


Hi James,

I've tried to convert the WatershedSegmentation1.cxx to grayscale=20
images, but I still have problems (abnormal termination).
Here's my code :
--------------------
tumorFilterITK.h
--------------------
#ifndef tumorFilterITK_H
#define tumorFilterITK_H


#include <itkVTKImageExport.h>
#include <itkVTKImageImport.h>
#include <vtkImageImport.h>
#include <vtkImageExport.h>

#include <itkGradientAnisotropicDiffusionImageFilter.h>
#include <itkGradientMagnitudeImageFilter.h>
#include <itkWatershedImageFilter.h>
#include <itkCastImageFilter.h>

class tumorFilterITK
{

public:

    typedef short pixelType;

    typedef itk::Image<pixelType, 3> ImageType;
    typedef itk::Image<unsigned long, 3> ImageTypeOut;

    typedef itk::VTKImageImport<ImageType> ImageImportType;
    typedef itk::VTKImageExport<ImageType> ImageExportType;
=20
    typedef itk::CastImageFilter<ImageTypeOut, ImageType> CastFilterType;=


    typedef itk::GradientAnisotropicDiffusionImageFilter<ImageType,   =20
ImageType>  DiffusionFilterType;
    typedef itk::GradientMagnitudeImageFilter<ImageType, ImageType>=20
GradientMagnitudeFilterType;
    typedef itk::WatershedImageFilter<ImageType> WatershedFilterType;

    tumorFilterITK(vtkImageImport*, vtkImageExport*);
    void tumorFilterITKExec();

private:

    ImageImportType::Pointer itkImporter;
    ImageExportType::Pointer itkExporter;

    CastFilterType::Pointer caster;

    DiffusionFilterType::Pointer diffusion;
    GradientMagnitudeFilterType::Pointer gradient;
    WatershedFilterType::Pointer watershed;
};

#endif
--------------------------------------------
--------------------
tumorFilterITK.cpp
--------------------

#include "tumorFilterITK.h"

/// connexion de ITK a VTK
template <typename ITK_Exporter, typename VTK_Importer>
void ConnectPipelines(ITK_Exporter exporter, VTK_Importer* importer)
{
 =20
importer->SetUpdateInformationCallback(exporter->GetUpdateInformationCall=
back());
 =20
importer->SetPipelineModifiedCallback(exporter->GetPipelineModifiedCallba=
ck());
  importer->SetWholeExtentCallback(exporter->GetWholeExtentCallback());
  importer->SetSpacingCallback(exporter->GetSpacingCallback());
  importer->SetOriginCallback(exporter->GetOriginCallback());
  importer->SetScalarTypeCallback(exporter->GetScalarTypeCallback());
 =20
importer->SetNumberOfComponentsCallback(exporter->GetNumberOfComponentsCa=
llback());
 =20
importer->SetPropagateUpdateExtentCallback(exporter->GetPropagateUpdateEx=
tentCallback());
  importer->SetUpdateDataCallback(exporter->GetUpdateDataCallback());
  importer->SetDataExtentCallback(exporter->GetDataExtentCallback());
  importer->SetBufferPointerCallback(exporter->GetBufferPointerCallback()=
);
  importer->SetCallbackUserData(exporter->GetCallbackUserData());
}

//-----------------------------------------------------------------

/// connexion de VTK a ITK
template <typename VTK_Exporter, typename ITK_Importer>
void ConnectPipelines(VTK_Exporter* exporter, ITK_Importer importer)
{
 =20
importer->SetUpdateInformationCallback(exporter->GetUpdateInformationCall=
back());
 =20
importer->SetPipelineModifiedCallback(exporter->GetPipelineModifiedCallba=
ck());
  importer->SetWholeExtentCallback(exporter->GetWholeExtentCallback());
  importer->SetSpacingCallback(exporter->GetSpacingCallback());
  importer->SetOriginCallback(exporter->GetOriginCallback());
  importer->SetScalarTypeCallback(exporter->GetScalarTypeCallback());
 =20
importer->SetNumberOfComponentsCallback(exporter->GetNumberOfComponentsCa=
llback());
 =20
importer->SetPropagateUpdateExtentCallback(exporter->GetPropagateUpdateEx=
tentCallback());
  importer->SetUpdateDataCallback(exporter->GetUpdateDataCallback());
  importer->SetDataExtentCallback(exporter->GetDataExtentCallback());
  importer->SetBufferPointerCallback(exporter->GetBufferPointerCallback()=
);
  importer->SetCallbackUserData(exporter->GetCallbackUserData());
}

//-----------------------------------------------------------------

///contructeur initialisant le pipeline ITK
tumorFilterITK::tumorFilterITK(vtkImageImport* vtkImporter,=20
vtkImageExport *vtkExporter)
{      =20
    itkImporter =3D ImageImportType::New();
    itkExporter =3D ImageExportType::New();

//    itkExporter->SetInput(itkImporter->GetOutput());
    diffusion =3D DiffusionFilterType::New();
    gradient =3D GradientMagnitudeFilterType::New();
    caster =3D CastFilterType::New();

    watershed =3D WatershedFilterType::New();
  =20
    ConnectPipelines(vtkExporter, itkImporter);
    ConnectPipelines(itkExporter, vtkImporter);  =20

    tumorFilterITKExec();
}

//-----------------------------------------------------------------

/// execution du filtre de detection de tumeurs
void tumorFilterITK::tumorFilterITKExec()
{

     //inputImage outputImage conductanceTerm diffusionIterations=20
lowerThreshold outputScaleLevel gradientMode " << std::endl;

    diffusion->SetNumberOfIterations( 5 ); // 5 typically
    diffusion->SetConductanceParameter( 3.0 ); // 3.0 typically
    diffusion->SetTimeStep(0.125);

    watershed->SetLevel( 0.001 ); // 0->1 en %
    watershed->SetThreshold( 0.001 ); // 0->1 en %

    diffusion->SetInput(itkImporter->GetOutput());
    gradient->SetInput(diffusion->GetOutput());
    watershed->SetInput(gradient->GetOutput());

    try
    {
    watershed->Update();
    }
    catch (itk::ExceptionObject &e)
    {
    std::cerr << e << std::endl;
    }
    caster->SetInput(watershed->GetOutput());
    itkExporter->SetInput(caster->GetOutput());
}

------------------------------------

Maybe can you help me?
Thanks again,

Regards,

Laurent



Miller, James V (Research) wrote:

>Watershed can be run on grayscale images.  The example
>(WatershedSegmentation1.cxx) is set up to process RGB pixels. But you ca=
n
>easily run watershed on a grayscale image.
>
>You'll want to create a similar program to WatershedSegmentation1.cxx th=
at
>reads a scalar image, produces a gradient magnitude image
>(GradientMagnitudeImageFilter or RecursiveGradientMagnitudeImageFilter),=
 and
>runs watershed on the gradient magnitude image.
>
>So you just need to change the pixel type, delete the word "Vector" from=
 any
>class type in example, and change the CastType to a CastImageFilter that=

>converts a scalar image into an image of floating point pixels (alternat=
ive,
>you can remove the cast filter altogether and have the reader return an
>image of floating point pixels.  Here is a quick stab at it (haven't tri=
ed
>to compile it....)
>
>#ifdef _MSC_VER
>#pragma warning ( disable : 4786 )
>#endif
>
>#include <iostream>
>
>#include "itkGradientAnisotropicDiffusionImageFilter.h"
>#include "itkGradientMagnitudeImageFilter.h"
>#include "itkWatershedImageFilter.h"
>
>#include "itkImageFileReader.h"
>#include "itkImageFileWriter.h"
>#include "itkUnaryFunctorImageFilter.h"
>#include "itkScalarToRGBPixelFunctor.h"
>
>int main( int argc, char *argv[] )
>{
>  if (argc < 8 )
>    {
>    std::cerr << "Missing Parameters " << std::endl;
>    std::cerr << "Usage: " << argv[0];
>    std::cerr << " inputImage outputImage conductanceTerm
>diffusionIterations lowerThreshold outputScaleLevel gradientMode " <<
>std::endl;
>    return 1;
>    }
> =20
>  typedef itk::RGBPixel<unsigned char>   RGBPixelType;
>  typedef itk::Image<RGBPixelType, 2>    RGBImageType;
>  typedef itk::Image<unsigned long, 2>   LabeledImageType;
>  typedef itk::Image<float, 2>           ScalarImageType;
>
>  typedef itk::ImageFileReader<ScalarImageType> FileReaderType;
>  typedef itk::GradientAnisotropicDiffusionImageFilter<ScalarImageType,
>    ScalarImageType>  DiffusionFilterType;
>  typedef itk::GradientMagnitudeImageFilter<ScalarImageType>
>    ScalarMagnitudeFilterType;=20
>  typedef itk::WatershedImageFilter<ScalarImageType> WatershedFilterType=
;
>  // Software Guide : EndCodeSnippet
>
>  typedef itk::ImageFileWriter<RGBImageType> FileWriterType;
>
>  FileReaderType::Pointer reader =3D FileReaderType::New();
>  reader->SetFileName(argv[1]);
> =20
>  DiffusionFilterType::Pointer diffusion =3D DiffusionFilterType::New();=

>  diffusion->SetNumberOfIterations( atoi(argv[4]) );
>  diffusion->SetConductanceParameter( atof(argv[3]) );
>  diffusion->SetTimeStep(0.125);
>
>
>  GradientMagnitudeFilterType::Pointer gradient =3D
>GradientMagnitudeFilterType::New();
>  gradient->SetUsePrincipleComponents(atoi(argv[7]));
>
>
>  WatershedFilterType::Pointer watershed =3D WatershedFilterType::New();=

>  watershed->SetLevel( atof(argv[6]) );
>  watershed->SetThreshold( atof(argv[5]) );
>
>
>  typedef itk::Functor::ScalarToRGBPixelFunctor<unsigned long>
>    ColorMapFunctorType;
>  typedef itk::UnaryFunctorImageFilter<LabeledImageType,
>    RGBImageType, ColorMapFunctorType> ColorMapFilterType;
>  ColorMapFilterType::Pointer colormapper =3D ColorMapFilterType::New();=

> =20
>  FileWriterType::Pointer writer =3D FileWriterType::New();
>  writer->SetFileName(argv[2]);
>
>  diffusion->SetInput(reader->GetOutput());
>  gradient->SetInput(diffusion->GetOutput());
>  watershed->SetInput(gradient->GetOutput());
>  colormapper->SetInput(watershed->GetOutput());
>  writer->SetInput(colormapper->GetOutput());
>
>  try=20
>    {
>    writer->Update();
>    }
>  catch (itk::ExceptionObject &e)
>    {
>    std::cerr << e << std::endl;
>    }
>   =20
>  return 0;
>}
>
>
>
>
>
>-----Original Message-----
>From: Laurent Mundeleer [mailto:lmundele at ulb.ac.be]
>Sent: Thursday, April 29, 2004 6:10 AM
>To: insight-users at itk.org
>Subject: [Insight-users] watershed segmentation without RGB?
>
>
>Hi all,
>
>I'd like to apply the watershed filter to CT images, is it possible? In =

>the documentation, it 's specified that RGB values are required...
>How can I do?
>
>Thanks in advance
>
>Regards,
>
>Laurent
>
> =20
>

--=20
********************************************
Laurent Mundeleer
Universit=E9 Libre de Bruxelles (ULB)
Service des Syst=E8mes Logiques et Num=E9riques (SLN) CP165/57
50, Av. F.Roosevelt
1050 Bruxelles
Belgium
tel : ++32.2.650.22.97
fax : ++32.2.650.22.98
e-mail : lmundele at ulb.ac.be
********************************************