Statistical Properties of Labeled Regions#

Synopsis#

Get statistical properties of labeled regions in an image.

Results#

image.png

image.png#

Output:

Number of labels: 2

min: 255
max: 255
median: 0
mean: 255
sigma: 0
variance: 0
sum: 4080
count: 16
region: ImageRegion (0x7ffedfd04a28)
Dimension: 2
Index: [6, 6]
Size: [4, 4]

min: 0
max: 0
median: 0
mean: 0
sigma: 0
variance: 0
sum: 0
count: 384
region: ImageRegion (0x7ffedfd04a28)
Dimension: 2
Index: [0, 0]
Size: [20, 20]

Code#

C++#

#include "itkImage.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkBinaryImageToLabelMapFilter.h"
#include "itkLabelMapToLabelImageFilter.h"
#include "itkLabelStatisticsImageFilter.h"

using ImageType = itk::Image<unsigned char, 2>;
static void
CreateImage(ImageType::Pointer image);

int
main()
{
  auto image = ImageType::New();
  CreateImage(image);

  using BinaryImageToLabelMapFilterType = itk::BinaryImageToLabelMapFilter<ImageType>;
  auto binaryImageToLabelMapFilter = BinaryImageToLabelMapFilterType::New();
  binaryImageToLabelMapFilter->SetInput(image);
  binaryImageToLabelMapFilter->Update();

  using LabelMapToLabelImageFilterType =
    itk::LabelMapToLabelImageFilter<BinaryImageToLabelMapFilterType::OutputImageType, ImageType>;
  auto labelMapToLabelImageFilter = LabelMapToLabelImageFilterType::New();
  labelMapToLabelImageFilter->SetInput(binaryImageToLabelMapFilter->GetOutput());
  labelMapToLabelImageFilter->Update();

  using LabelStatisticsImageFilterType = itk::LabelStatisticsImageFilter<ImageType, ImageType>;
  auto labelStatisticsImageFilter = LabelStatisticsImageFilterType::New();
  labelStatisticsImageFilter->SetLabelInput(labelMapToLabelImageFilter->GetOutput());
  labelStatisticsImageFilter->SetInput(image);
  labelStatisticsImageFilter->Update();

  std::cout << "Number of labels: " << labelStatisticsImageFilter->GetNumberOfLabels() << std::endl;
  std::cout << std::endl;

  using LabelPixelType = LabelStatisticsImageFilterType::LabelPixelType;

  for (auto vIt = labelStatisticsImageFilter->GetValidLabelValues().begin();
       vIt != labelStatisticsImageFilter->GetValidLabelValues().end();
       ++vIt)
  {
    if (labelStatisticsImageFilter->HasLabel(*vIt))
    {
      LabelPixelType labelValue = *vIt;
      std::cout << "min: " << labelStatisticsImageFilter->GetMinimum(labelValue) << std::endl;
      std::cout << "max: " << labelStatisticsImageFilter->GetMaximum(labelValue) << std::endl;
      std::cout << "median: " << labelStatisticsImageFilter->GetMedian(labelValue) << std::endl;
      std::cout << "mean: " << labelStatisticsImageFilter->GetMean(labelValue) << std::endl;
      std::cout << "sigma: " << labelStatisticsImageFilter->GetSigma(labelValue) << std::endl;
      std::cout << "variance: " << labelStatisticsImageFilter->GetVariance(labelValue) << std::endl;
      std::cout << "sum: " << labelStatisticsImageFilter->GetSum(labelValue) << std::endl;
      std::cout << "count: " << labelStatisticsImageFilter->GetCount(labelValue) << std::endl;
      // std::cout << "box: " << labelStatisticsImageFilter->GetBoundingBox( labelValue ) << std::endl; // can't output
      // a box
      std::cout << "region: " << labelStatisticsImageFilter->GetRegion(labelValue) << std::endl;
      std::cout << std::endl << std::endl;
    }
  }

  return EXIT_SUCCESS;
}

void
CreateImage(ImageType::Pointer image)
{
  // Create a black image with a white square
  ImageType::IndexType start;
  start.Fill(0);

  ImageType::SizeType size;
  size.Fill(20);

  ImageType::RegionType region;
  region.SetSize(size);
  region.SetIndex(start);
  image->SetRegions(region);
  image->Allocate();

  itk::ImageRegionIterator<ImageType> imageIterator(image, image->GetLargestPossibleRegion());

  // Make a square
  while (!imageIterator.IsAtEnd())
  {
    if ((imageIterator.GetIndex()[0] > 5 && imageIterator.GetIndex()[0] < 10) &&
        (imageIterator.GetIndex()[1] > 5 && imageIterator.GetIndex()[1] < 10))
    {
      imageIterator.Set(255);
    }
    else
    {
      imageIterator.Set(0);
    }

    ++imageIterator;
  }

  itk::WriteImage(image, "image.png");
}

Classes demonstrated#

template<typename TInputImage, typename TLabelImage>
class LabelStatisticsImageFilter : public itk::ImageSink<TInputImage>

Given an intensity image and a label map, compute min, max, variance and mean of the pixels associated with each label or segment.

LabelStatisticsImageFilter computes the minimum, maximum, sum, mean, median, variance and sigma of regions of an intensity image, where the regions are defined via a label map (a second input). The label image should be integral type. The filter needs all of its input image. It behaves as a filter with an input and output. Thus it can be inserted in a pipline with other filters and the statistics will only be recomputed if a downstream filter changes.

Optionally, the filter also computes intensity histograms on each object. If histograms are enabled, a median intensity value can also be computed, although its accuracy is limited to the bin width of the histogram. If histograms are not enabled, the median returns zero.

This filter is automatically multi-threaded and can stream its input when NumberOfStreamDivisions is set to more than

  1. Statistics are independently computed for each streamed and threaded region then merged.

ITK Sphinx Examples:

See itk::LabelStatisticsImageFilter for additional documentation.