/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
- Authors belong to:
+ Authors belong to:
- University of LYON http://www.universite-lyon.fr/
- Léon Bérard cancer center http://www.centreleonberard.fr
- CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
#include "clitkFilterBase.h"
#include "clitkCropLikeImageFilter.h"
#include "clitkSegmentationUtils.h"
-// #include "itkLabelOverlapMeasuresImageFilter.h"
// itk
#include <itkImageToImageFilter.h>
#include <itkLabelStatisticsImageFilter.h>
+#include <itkLabelOverlapMeasuresImageFilter.h>
#include <iomanip>
namespace clitk {
-
+
//--------------------------------------------------------------------
/*
Analyze the relative position of a Target (mask image) according
to some Object, in a given Support. Indicate the main important
- position of this Target according the Object.
+ position of this Target according the Object.
*/
//--------------------------------------------------------------------
-
+
template <class ImageType>
class LabelImageOverlapMeasureFilter:
public virtual FilterBase,
typedef LabelImageOverlapMeasureFilter<ImageType> Self;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
-
+
/** Method for creation through the object factory. */
itkNewMacro(Self);
-
+
/** Run-time type information (and related methods). */
itkTypeMacro(LabelImageOverlapMeasureFilter, ImageToImageFilter);
/** Some convenient typedefs. */
typedef typename ImageType::ConstPointer ImageConstPointer;
typedef typename ImageType::Pointer ImagePointer;
- typedef typename ImageType::RegionType RegionType;
+ typedef typename ImageType::RegionType RegionType;
typedef typename ImageType::PixelType PixelType;
typedef typename ImageType::SpacingType SpacingType;
typedef typename ImageType::SizeType SizeType;
typedef typename ImageType::IndexType IndexType;
typedef typename ImageType::PointType PointType;
-
+
/** ImageDimension constants */
itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
FILTERBASE_INIT;
-
+
// Options
itkGetConstMacro(BackgroundValue, PixelType);
- itkSetMacro(BackgroundValue, PixelType);
+ //itkSetMacro(BackgroundValue, PixelType);
itkGetConstMacro(Label1, PixelType);
itkSetMacro(Label1, PixelType);
itkGetConstMacro(Label2, PixelType);
itkSetMacro(Label2, PixelType);
+ itkSetMacro(VerboseFlag, bool);
+ itkGetConstMacro(VerboseFlag, bool);
+ itkBooleanMacro(VerboseFlag);
+
+ itkSetMacro(LongFlag, bool);
+ itkGetConstMacro(LongFlag, bool);
+ itkBooleanMacro(LongFlag);
+
// I dont want to verify inputs information
virtual void VerifyInputInformation() { }
-
+
protected:
LabelImageOverlapMeasureFilter();
virtual ~LabelImageOverlapMeasureFilter() {}
-
+
PixelType m_BackgroundValue;
PixelType m_Label1;
PixelType m_Label2;
ImagePointer m_Input1;
ImagePointer m_Input2;
+ bool m_VerboseFlag;
+ bool m_LongFlag;
virtual void GenerateOutputInformation();
virtual void GenerateInputRequestedRegion();
private:
LabelImageOverlapMeasureFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
-
+
}; // end class
//--------------------------------------------------------------------
/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
- Authors belong to:
+ Authors belong to:
- University of LYON http://www.universite-lyon.fr/
- Léon Bérard cancer center http://www.centreleonberard.fr
- CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
this->SetNumberOfRequiredInputs(2);
SetLabel1(1);
SetLabel2(1);
- SetBackgroundValue(0);
+ m_BackgroundValue = 0;
+ SetVerboseFlag(false);
+ SetLongFlag(false);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
template <class ImageType>
-void
+void
clitk::LabelImageOverlapMeasureFilter<ImageType>::
-GenerateOutputInformation()
-{
+GenerateOutputInformation()
+{
// DD("GenerateOutputInformation");
//ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
// ImagePointer outputImage = this->GetOutput(0);
//--------------------------------------------------------------------
template <class ImageType>
-void
+void
clitk::LabelImageOverlapMeasureFilter<ImageType>::
-GenerateInputRequestedRegion()
+GenerateInputRequestedRegion()
{
// Call default
itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
//--------------------------------------------------------------------
template <class ImageType>
-void
+void
clitk::LabelImageOverlapMeasureFilter<ImageType>::
-GenerateData()
+GenerateData()
{
- // DD("GenerateData");
-
// Get input pointer
m_Input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
m_Input2 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
// Resize like the union
ImagePointer input1 = clitk::ResizeImageLike<ImageType>(m_Input1, bbo, GetBackgroundValue());
ImagePointer input2 = clitk::ResizeImageLike<ImageType>(m_Input2, bbo, GetBackgroundValue());
- //DD(input1->GetLargestPossibleRegion());
- //DD(input2->GetLargestPossibleRegion());
-
- // Compute overlap image
- ImagePointer image_union = clitk::Clone<ImageType>(input1);
- ImagePointer image_intersection = clitk::Clone<ImageType>(input1);
- clitk::Or<ImageType>(image_union, input2, GetBackgroundValue());
- clitk::And<ImageType>(image_intersection, input2, GetBackgroundValue());
-
- ImagePointer image_1NotIn2 = clitk::Clone<ImageType>(input1);
- clitk::AndNot<ImageType>(image_1NotIn2, input2, GetBackgroundValue());
-
- ImagePointer image_2NotIn1 = clitk::Clone<ImageType>(input2);
- clitk::AndNot<ImageType>(image_2NotIn1, input1, GetBackgroundValue());
-
- //writeImage<ImageType>(image_union, "union.mha");
- //writeImage<ImageType>(image_intersection, "intersection.mha");
- //writeImage<ImageType>(image_1NotIn2, "image_1NotIn2.mha");
- //writeImage<ImageType>(image_2NotIn1, "image_2NotIn1.mha");
-
- // Compute size
- typedef itk::LabelStatisticsImageFilter<ImageType, ImageType> StatFilterType;
- typename StatFilterType::Pointer statFilter = StatFilterType::New();
- statFilter->SetInput(image_union);
- statFilter->SetLabelInput(image_union);
- statFilter->Update();
- int u = statFilter->GetCount(GetLabel1());
-
- statFilter->SetInput(image_intersection);
- statFilter->SetLabelInput(image_intersection);
- statFilter->Update();
- int inter = statFilter->GetCount(GetLabel1());
-
- statFilter->SetInput(m_Input1);
- statFilter->SetLabelInput(m_Input1);
- statFilter->Update();
- int in1 = statFilter->GetCount(GetLabel1());
-
- statFilter->SetInput(m_Input2);
- statFilter->SetLabelInput(m_Input2);
- statFilter->Update();
- int in2 = statFilter->GetCount(GetLabel1());
-
- statFilter->SetInput(image_1NotIn2);
- statFilter->SetLabelInput(image_1NotIn2);
- statFilter->Update();
- int l1notIn2 = statFilter->GetCount(GetLabel1());
-
- statFilter->SetInput(image_2NotIn1);
- statFilter->SetLabelInput(image_2NotIn1);
- statFilter->Update();
- int l2notIn1 = statFilter->GetCount(GetLabel1());
-
- double dice = 2.0*(double)inter/(double)(in1+in2);
+ /*
+ if (GetVerboseFlag()) {
+ std::cout << "Resize images to the union of bounding boxes: "
+ << input1->GetLargestPossibleRegion().GetSize() << std::endl;
+ }
+ */
+
+ /*
int width = 6;
std::cout << std::setw(width) << in1 << " "
<< std::setw(width) << in2 << " "
<< std::setw(width) << l1notIn2 << " "
<< std::setw(width) << l2notIn1 << " "
<< std::setw(width) << dice << " "; //std::endl;
+ */
+
+ // Compute overlap, dice
+ typedef itk::LabelOverlapMeasuresImageFilter<ImageType> FilterType;
+ typename FilterType::Pointer diceFilter = FilterType::New();
+ diceFilter->SetSourceImage(input1);
+ diceFilter->SetTargetImage(input2);
+ diceFilter->Update();
+
+ // Display information
+ if (!GetLongFlag()) {
+ if (GetVerboseFlag()) {
+ std::cout << "Dice : ";
+ }
+ std::cout << diceFilter->GetDiceCoefficient() << std::endl;
+ }
+ else { // long options
+ if (GetVerboseFlag()) {
+ std::cout << "Dice Jaccard Source Target Inter Union SrComp TarComp" << std::endl;
+ }
+ typename FilterType::MapType m = diceFilter->GetLabelSetMeasures();
+ int width = 6;
+ std::cout << std::setw(width) << diceFilter->GetDiceCoefficient() << " "
+ << std::setw(width) << diceFilter->GetJaccardCoefficient() << " "
+ << std::setw(width) << m[m_Label1].m_Source << " "
+ << std::setw(width) << m[m_Label2].m_Target << " "
+ << std::setw(width) << m[m_Label1].m_Intersection << " "
+ << std::setw(width) << m[m_Label1].m_Union << " "
+ << std::setw(width) << m[m_Label1].m_SourceComplement << " "
+ << std::setw(width) << m[m_Label2].m_TargetComplement << " "
+ << std::endl;
+ }
+
}
//--------------------------------------------------------------------
-