5

I'm trying to calculate texture features for a segmented 3D brain MRI using ITK library with C++. So I followed this example. The example takes a 3D image, and extracts 3 different features for all 13 possible spatial directions. In my program, I just want for a given 3D image to get :

  • Energy
  • Correlation
  • Inertia
  • Haralick Correlation
  • Inverse Difference Moment
  • Cluster Prominence
  • Cluster Shade

Here is what I have so far :

//definitions of used types
typedef itk::Image<float, 3> InternalImageType;
typedef itk::Image<unsigned char, 3> VisualizingImageType;
typedef itk::Neighborhood<float, 3> NeighborhoodType;
typedef itk::Statistics::ScalarImageToCooccurrenceMatrixFilter<InternalImageType>
Image2CoOccuranceType;
typedef Image2CoOccuranceType::HistogramType HistogramType;
typedef itk::Statistics::HistogramToTextureFeaturesFilter<HistogramType> Hist2FeaturesType;
typedef InternalImageType::OffsetType OffsetType;
typedef itk::AddImageFilter <InternalImageType> AddImageFilterType;
typedef itk::MultiplyImageFilter<InternalImageType> MultiplyImageFilterType;

void calcTextureFeatureImage (OffsetType offset, InternalImageType::Pointer inputImage)
{
// principal variables
//Gray Level Co-occurance Matrix Generator
Image2CoOccuranceType::Pointer glcmGenerator=Image2CoOccuranceType::New();
glcmGenerator->SetOffset(offset);
glcmGenerator->SetNumberOfBinsPerAxis(16); //reasonable number of bins
glcmGenerator->SetPixelValueMinMax(0, 255); //for input UCHAR pixel type
Hist2FeaturesType::Pointer featureCalc=Hist2FeaturesType::New();
//Region Of Interest
typedef itk::RegionOfInterestImageFilter<InternalImageType,InternalImageType> roiType;
roiType::Pointer roi=roiType::New();
roi->SetInput(inputImage);



InternalImageType::RegionType window;
InternalImageType::RegionType::SizeType size;
size.Fill(50);
window.SetSize(size);

window.SetIndex(0,0);
window.SetIndex(1,0);
window.SetIndex(2,0);

roi->SetRegionOfInterest(window);
roi->Update();

glcmGenerator->SetInput(roi->GetOutput());
glcmGenerator->Update();

featureCalc->SetInput(glcmGenerator->GetOutput());
featureCalc->Update();

std::cout<<"\n Entropy : ";
std::cout<<featureCalc->GetEntropy()<<"\n Energy";
std::cout<<featureCalc->GetEnergy()<<"\n Correlation";
std::cout<<featureCalc->GetCorrelation()<<"\n Inertia";             
std::cout<<featureCalc->GetInertia()<<"\n HaralickCorrelation";
std::cout<<featureCalc->GetHaralickCorrelation()<<"\n InverseDifferenceMoment";
std::cout<<featureCalc->GetInverseDifferenceMoment()<<"\nClusterProminence";
std::cout<<featureCalc->GetClusterProminence()<<"\nClusterShade";
std::cout<<featureCalc->GetClusterShade();
}

The program works. However I have this problem : it gives the same results for different 3D images, even when I change the window size.

Does any one used ITK to do this ? If there is any other method to achieve that, could anyone point me to a solution please ?

Any help will be much apreciated.

blackbishop
  • 30,945
  • 11
  • 55
  • 76
  • are you sure that the image is read correctly? for example, if you compute something simple as the intensity range of the input, do you get the correct results? http://itk.org/Wiki/ITK/Examples/ImageProcessing/MinimumMaximumImageCalculator – lib Apr 11 '15 at 19:25
  • @lib Yes the image is correctly read, I know that because I was able to display it correcty – blackbishop Apr 11 '15 at 19:35
  • I ran your code with the `main` function taken from the example page (the only change I made was to the `size` object to accommodate the size of my particular images) and got different results for different images. How are you reading your images into your program? Are you using the same `ImageFileReader` object for both images? If that's the case, you may be overwriting one of them in memory and performing the operations twice on the same image. – eigenchris Apr 15 '15 at 22:28

2 Answers2

2

I think that your images have only one gray scale level. For example, if you segment your images using itk-snap tool, when you save the result of the segmentation, itk-snap save it with one gray scale level. So, if you try to calculate texture features for images segmented with itk-snap you'll always have the same results even if you change the images or the window size because you have only one gray scale level in the co-occurrence matrix. Try to run your program using unsegmented images, you'll certainly have different results.

EDIT :

To calculate texture features for segmented images, try another segmentation method which saves the original gray scale levels of the unsegmented image.

M'henni Koroghli
  • 212
  • 2
  • 12
0

Something strange in your code is size.Fill(50), while in the example they show it should hold the image dimension:

 size.Fill(3); //window size=3x3x3
lib
  • 2,918
  • 3
  • 27
  • 53
  • No, `size.Fill(3)` does not represent the image dimensions, it holds the size of region of interest `roi`. The `window` size is needed to calculate the gray level co-occurence matrix and has nothing to do with the image dimensions. – blackbishop Apr 11 '15 at 19:36
  • yes, sorry I see now.. But are you able to get different results for different regions of interest? (visualizing them or computing the max intensity?) And the histogram range 0-255, is it good for your images? – lib Apr 11 '15 at 20:13