ITK  6.0.0
Insight Toolkit
Examples/Statistics/ImageHistogram4.cxx
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
// Software Guide : BeginLatex
//
// The statistics framework in ITK has been designed for managing
// multi-variate statistics in a natural way. The
// \subdoxygen{Statistics}{Histogram} class reflects this concept clearly
// since it is a N-variable joint histogram. This nature of the Histogram
// class is exploited in the following example in order to build the joint
// histogram of a color image encoded in RGB values.
//
// Note that the same treatment could be applied further to any vector image
// thanks to the generic programming approach used in the implementation of
// the statistical framework.
//
// The most relevant class in this example is the
// \subdoxygen{Statistics}{ImageToHistogramFilter}. This class will take
// care of adapting the \doxygen{Image} to a list of samples and then to a
// histogram filter. The user is only bound to provide the desired
// resolution on the histogram bins for each one of the image components.
//
// In this example we compute the joint histogram of the three channels of an
// RGB image. Our output histogram will be equivalent to a 3D array of bins.
// This histogram could be used further for feeding a segmentation method
// based on statistical pattern recognition. Such method was actually used
// during the generation of the image in the cover of the Software Guide.
//
// The first step is to include the header files for the histogram filter,
// the RGB pixel type and the Image.
//
// \index{itk::Statistics::ImageToHistogramFilter!header}
// \index{itk::RGBPixel!header}
// \index{itk::RGBPixel!Statistics}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "itkImage.h"
#include "itkRGBPixel.h"
// Software Guide : EndCodeSnippet
int
main(int argc, char * argv[])
{
if (argc < 3)
{
std::cerr << "Missing command line arguments" << std::endl;
std::cerr << "Usage : ImageHistogram4 inputRGBImageFileName ";
std::cerr << " histogramFilename.raw" << std::endl;
return EXIT_FAILURE;
}
// Software Guide : BeginLatex
//
// We declare now the type used for the components of the RGB pixel,
// instantiate the type of the RGBPixel and instantiate the image type.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using PixelComponentType = unsigned char;
using RGBPixelType = itk::RGBPixel<PixelComponentType>;
constexpr unsigned int Dimension = 2;
// Software Guide : EndCodeSnippet
auto reader = ReaderType::New();
reader->SetFileName(argv[1]);
try
{
reader->Update();
}
catch (const itk::ExceptionObject & excp)
{
std::cerr << "Problem reading image file : " << argv[1] << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
// Software Guide : BeginLatex
//
// Using the type of the color image, and in general of any vector image, we
// can now instantiate the type of the histogram filter class. We then use
// that type for constructing an instance of the filter by invoking its
// \code{New()} method and assigning the result to a smart pointer.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using HistogramFilterType =
auto histogramFilter = HistogramFilterType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The resolution at which the statistics of each one of the color component
// will be evaluated is defined by setting the number of bins along every
// component in the joint histogram. For this purpose we take the
// \code{HistogramSizeType} trait from the filter and use it to instantiate
// a \code{size} variable. We set in this variable the number of bins to use
// for each component of the color image.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using SizeType = HistogramFilterType::HistogramSizeType;
SizeType size(3);
size[0] = 256; // number of bins for the Red channel
size[1] = 256; // number of bins for the Green channel
size[2] = 256; // number of bins for the Blue channel
histogramFilter->SetHistogramSize(size);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Finally, we must specify the upper and lower bounds for the histogram
// using the \code{SetHistogramBinMinimum()} and
// \code{SetHistogramBinMaximum()} methods.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using HistogramMeasurementVectorType =
HistogramFilterType::HistogramMeasurementVectorType;
HistogramMeasurementVectorType binMinimum(3);
HistogramMeasurementVectorType binMaximum(3);
binMinimum[0] = -0.5;
binMinimum[1] = -0.5;
binMinimum[2] = -0.5;
binMaximum[0] = 255.5;
binMaximum[1] = 255.5;
binMaximum[2] = 255.5;
histogramFilter->SetHistogramBinMinimum(binMinimum);
histogramFilter->SetHistogramBinMaximum(binMaximum);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The input to the histogram filter is taken from the output of an image
// reader. Of course, the output of any filter producing an RGB image could
// have been used instead of a reader.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
histogramFilter->SetInput(reader->GetOutput());
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The marginal scale is defined in the histogram filter. This value will
// define the precision in the assignment of values to the histogram bins.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
histogramFilter->SetMarginalScale(10.0);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Finally, the computation of the histogram is triggered by invoking the
// \code{Update()} method of the filter.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
histogramFilter->Update();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// At this point, we can recover the histogram by calling the
// \code{GetOutput()} method of the filter. The result is assigned to a
// variable that is instantiated using the \code{HistogramType} trait of the
// filter type.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using HistogramType = HistogramFilterType::HistogramType;
const HistogramType * histogram = histogramFilter->GetOutput();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We can verify that the computed histogram has the requested size by
// invoking its \code{Size()} method.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
const unsigned int histogramSize = histogram->Size();
std::cout << "Histogram size " << histogramSize << std::endl;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The values of the histogram can now be saved into a file by walking
// through all of the histogram bins and pushing them into a std::ofstream.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
std::ofstream histogramFile;
histogramFile.open(argv[2]);
HistogramType::ConstIterator itr = histogram->Begin();
HistogramType::ConstIterator end = histogram->End();
using AbsoluteFrequencyType = HistogramType::AbsoluteFrequencyType;
while (itr != end)
{
const AbsoluteFrequencyType frequency = itr.GetFrequency();
histogramFile.write((const char *)(&frequency), sizeof(frequency));
if (frequency != 0)
{
index = histogram->GetIndex(itr.GetInstanceIdentifier());
std::cout << "Index = " << index << ", Frequency = " << frequency
<< std::endl;
}
++itr;
}
histogramFile.close();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Note that here the histogram is saved as a block of memory in a raw file.
// At this point you can use visualization software in order to explore the
// histogram in a display that would be equivalent to a scatter plot of the
// RGB components of the input color image.
//
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
itk::RGBPixel
Represent Red, Green and Blue components for color images.
Definition: itkRGBPixel.h:58
itkImageToHistogramFilter.h
itkRGBPixel.h
itkImageFileReader.h
itk::GTest::TypedefsAndConstructors::Dimension2::SizeType
ImageBaseType::SizeType SizeType
Definition: itkGTestTypedefsAndConstructors.h:49
itkImage.h
itk::ImageFileReader
Data source that reads image data from a single file.
Definition: itkImageFileReader.h:75
itk::GTest::TypedefsAndConstructors::Dimension2::IndexType
ImageBaseType::IndexType IndexType
Definition: itkGTestTypedefsAndConstructors.h:50
itk::Index::GetIndex
const IndexValueType * GetIndex() const
Definition: itkIndex.h:230
itk::Image
Templated n-dimensional image class.
Definition: itkImage.h:88
New
static Pointer New()
itk::Statistics::ImageToHistogramFilter
This class generates a histogram from an image.
Definition: itkImageToHistogramFilter.h:50
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44