Commit 98bf876b authored by David Gobbi's avatar David Gobbi Committed by Kitware Robot
Browse files

Merge topic 'image-histogram'

a54e74f0 ENH: Add a class for generating an image histogram.
parents e968eb24 a54e74f0
......@@ -52,6 +52,8 @@ vtkImageGaussianSource.cxx
vtkImageGradient.cxx
vtkImageGradientMagnitude.cxx
vtkImageGridSource.cxx
vtkImageHistogram.cxx
vtkImageHistogramStatistics.cxx
vtkImageHSIToRGB.cxx
vtkImageHSVToRGB.cxx
vtkImageHybridMedian2D.cxx
......
......@@ -3,7 +3,10 @@ IF (VTK_USE_RENDERING AND VTK_USE_DISPLAY)
CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
ImportExport.cxx
ImageWeightedSum.cxx
ImageAutoRange.cxx
ImageAccumulate.cxx
ImageHistogram.cxx
ImageHistogramStatistics.cxx
FastSplatter.cxx
TestUpdateExtentReset.cxx
EXTRA_INCLUDE vtkTestDriver.h
......
/*=========================================================================
Program: Visualization Toolkit
Module: ImageAutoRange.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// Use vtkImageHistogramStatistics to auto compute the window/level
//
// The command line arguments are:
// -I => run in interactive mode
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkCamera.h"
#include "vtkImageData.h"
#include "vtkImageSliceMapper.h"
#include "vtkImageProperty.h"
#include "vtkImageSlice.h"
#include "vtkPNGReader.h"
#include "vtkImageHistogramStatistics.h"
#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"
int ImageAutoRange(int argc, char *argv[])
{
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
vtkInteractorStyle *style = vtkInteractorStyleImage::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
iren->SetRenderWindow(renWin);
iren->SetInteractorStyle(style);
renWin->Delete();
style->Delete();
vtkPNGReader *reader = vtkPNGReader::New();
char* fname = vtkTestUtilities::ExpandDataFileName(
argc, argv, "Data/fullhead15.png");
reader->SetFileName(fname);
delete[] fname;
vtkImageHistogramStatistics *statistics = vtkImageHistogramStatistics::New();
statistics->SetInputConnection(reader->GetOutputPort());
statistics->GenerateHistogramImageOff();
statistics->Update();
// Get a viewing range based on the full data range
double range[2];
range[0] = statistics->GetMinimum();
range[1] = statistics->GetMaximum();
// Use the autorange feature to get a better image range
double autorange[2];
statistics->GetAutoRange(autorange);
for (int i = 0; i < 2; i++)
{
vtkRenderer *renderer = vtkRenderer::New();
vtkCamera *camera = renderer->GetActiveCamera();
renderer->SetBackground(0.0,0.0,0.0);
renderer->SetViewport(0.5*(i&1), 0.0,
0.5 + 0.5*(i&1), 1.0);
renWin->AddRenderer(renderer);
renderer->Delete();
vtkImageSliceMapper *imageMapper = vtkImageSliceMapper::New();
imageMapper->SetInputConnection(reader->GetOutputPort());
double *bounds = imageMapper->GetBounds();
double point[3];
point[0] = 0.5*(bounds[0] + bounds[1]);
point[1] = 0.5*(bounds[2] + bounds[3]);
point[2] = 0.5*(bounds[4] + bounds[5]);
camera->SetFocalPoint(point);
point[imageMapper->GetOrientation()] += 500.0;
camera->SetPosition(point);
camera->SetViewUp(0.0, 1.0, 0.0);
camera->ParallelProjectionOn();
camera->SetParallelScale(128);
vtkImageSlice *image = vtkImageSlice::New();
image->SetMapper(imageMapper);
imageMapper->Delete();
renderer->AddViewProp(image);
if ((i & 1) == 0)
{
image->GetProperty()->SetColorWindow(range[1] - range[0]);
image->GetProperty()->SetColorLevel(0.5*(range[0] + range[1]));
}
else
{
image->GetProperty()->SetColorWindow(autorange[1] - autorange[0]);
image->GetProperty()->SetColorLevel(0.5*(autorange[0] + autorange[1]));
}
image->Delete();
}
renWin->SetSize(512,256);
renWin->Render();
int retVal = vtkRegressionTestImage( renWin );
if ( retVal == vtkRegressionTester::DO_INTERACTOR )
{
iren->Start();
}
iren->Delete();
statistics->Delete();
reader->Delete();
return !retVal;
}
/*=========================================================================
Program: Visualization Toolkit
Module: ImageHistogram.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// Test the vtkImageHistogram class
//
// The command line arguments are:
// -I => run in interactive mode
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkCamera.h"
#include "vtkImageData.h"
#include "vtkImageSliceMapper.h"
#include "vtkImageProperty.h"
#include "vtkImageSlice.h"
#include "vtkPNGReader.h"
#include "vtkImageHistogram.h"
#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"
int ImageHistogram(int argc, char *argv[])
{
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
vtkInteractorStyle *style = vtkInteractorStyleImage::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
iren->SetRenderWindow(renWin);
iren->SetInteractorStyle(style);
renWin->Delete();
style->Delete();
vtkPNGReader *reader = vtkPNGReader::New();
char* fname = vtkTestUtilities::ExpandDataFileName(
argc, argv, "Data/fullhead15.png");
reader->SetFileName(fname);
delete[] fname;
vtkImageHistogram *histogram = vtkImageHistogram::New();
histogram->SetInputConnection(reader->GetOutputPort());
histogram->GenerateHistogramImageOn();
histogram->SetHistogramImageSize(256,256);
histogram->SetHistogramImageScaleToSqrt();
histogram->AutomaticBinningOn();
histogram->Update();
vtkIdType nbins = histogram->GetNumberOfBins();
double range[2];
range[0] = histogram->GetBinOrigin();
range[1] = range[0] + (nbins - 1)*histogram->GetBinSpacing();
for (int i = 0; i < 2; i++)
{
vtkRenderer *renderer = vtkRenderer::New();
vtkCamera *camera = renderer->GetActiveCamera();
renderer->SetBackground(0.0,0.0,0.0);
renderer->SetViewport(0.5*(i&1), 0.0,
0.5 + 0.5*(i&1), 1.0);
renWin->AddRenderer(renderer);
renderer->Delete();
vtkImageSliceMapper *imageMapper = vtkImageSliceMapper::New();
if ((i & 1) == 0)
{
imageMapper->SetInputConnection(reader->GetOutputPort());
}
else
{
imageMapper->SetInputConnection(histogram->GetOutputPort());
}
double *bounds = imageMapper->GetBounds();
double point[3];
point[0] = 0.5*(bounds[0] + bounds[1]);
point[1] = 0.5*(bounds[2] + bounds[3]);
point[2] = 0.5*(bounds[4] + bounds[5]);
camera->SetFocalPoint(point);
point[imageMapper->GetOrientation()] += 500.0;
camera->SetPosition(point);
camera->SetViewUp(0.0, 1.0, 0.0);
camera->ParallelProjectionOn();
camera->SetParallelScale(128);
vtkImageSlice *image = vtkImageSlice::New();
image->SetMapper(imageMapper);
imageMapper->Delete();
renderer->AddViewProp(image);
if ((i & 1) == 0)
{
image->GetProperty()->SetColorWindow(range[1] - range[0]);
image->GetProperty()->SetColorLevel(0.5*(range[0] + range[1]));
}
else
{
image->GetProperty()->SetInterpolationTypeToNearest();
image->GetProperty()->SetColorWindow(255.0);
image->GetProperty()->SetColorLevel(127.5);
}
image->Delete();
}
renWin->SetSize(512,256);
renWin->Render();
int retVal = vtkRegressionTestImage( renWin );
if ( retVal == vtkRegressionTester::DO_INTERACTOR )
{
iren->Start();
}
iren->Delete();
histogram->Delete();
reader->Delete();
return !retVal;
}
/*=========================================================================
Program: Visualization Toolkit
Module: ImageHistogramStatistics.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// Test the vtkImageHistogramStatistics class
//
// The command line arguments are:
// -I => run in interactive mode
#include "vtkPNGReader.h"
#include "vtkImageCast.h"
#include "vtkImageHistogramStatistics.h"
#include "vtkImageAccumulate.h"
#include "vtkTestUtilities.h"
#include <math.h>
int ImageHistogramStatistics(int argc, char *argv[])
{
vtkPNGReader *reader = vtkPNGReader::New();
char* fname = vtkTestUtilities::ExpandDataFileName(
argc, argv, "Data/fullhead15.png");
reader->SetFileName(fname);
delete[] fname;
// Use float data to get the most code coverage
vtkImageCast *imageCast = vtkImageCast::New();
imageCast->SetOutputScalarTypeToFloat();
imageCast->SetInputConnection(reader->GetOutputPort());
double minValTest = 0;
double maxValTest = 3714;
double meanValTest = 635.8066572717137;
double medianTest = 190.9279926756695;
double stdevTest = 660.9126299774935;
double tol = 1e-6;
vtkImageHistogramStatistics *statistics = vtkImageHistogramStatistics::New();
statistics->SetInputConnection(imageCast->GetOutputPort());
statistics->GenerateHistogramImageOff();
statistics->Update();
double minVal = statistics->GetMinimum();
double maxVal = statistics->GetMaximum();
double meanVal = statistics->GetMean();
double median = statistics->GetMedian();
double stdev = statistics->GetStandardDeviation();
// uncomment to test vtkImageAccumulate instead
/*
vtkImageAccumulate *accumulate = vtkImageAccumulate::New();
accumulate->SetInputConnection(reader->GetOutputPort());
accumulate->Update();
double minVal = accumulate->GetMin()[0];
double maxVal = accumulate->GetMax()[0];
double meanVal = accumulate->GetMean()[0];
double median = medianTest;
double stdev = accumulate->GetStandardDeviation()[0];
*/
bool retVal = true;
if (fabs((minVal - minValTest)/maxValTest) > tol)
{
cout.precision(16);
cout << "minVal " << minVal << " should be " << minValTest << endl;
retVal = false;
}
if (fabs((maxVal - maxValTest)/maxValTest) > tol)
{
cout.precision(16);
cout << "maxVal " << maxVal << " should be " << maxValTest << endl;
retVal = false;
}
if (fabs((meanVal - meanValTest)/maxValTest) > tol)
{
cout.precision(16);
cout << "meanVal " << meanVal << " should be " << meanValTest << endl;
retVal = false;
}
if (fabs((median - medianTest)/maxValTest) > tol)
{
cout.precision(16);
cout << "median " << median << " should be " << medianTest << endl;
retVal = false;
}
if (fabs((stdev - stdevTest)/maxValTest) > tol)
{
cout.precision(16);
cout << "stdev " << stdev << " should be " << stdevTest << endl;
retVal = false;
}
reader->Delete();
imageCast->Delete();
statistics->Delete();
return !retVal;
}
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageHistogram.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkImageHistogram - Compute the histogram for an image.
// .SECTION Description
// vtkImageHistogram generates a histogram from its input, and optionally
// produces a 2D black-and-white image of the histogram as its output.
// Unlike the class vtkImageAccumulate, a multi-component image does not
// result in a multi-dimensional histogram. Instead, the resulting
// histogram will be the sum of the histograms of each of the individual
// components, unless SetActiveComponent is used to choose a single
// component.
// .SECTION Thanks
// Thanks to David Gobbi at the Seaman Family MR Centre and Dept. of Clinical
// Neurosciences, Foothills Medical Centre, Calgary, for providing this class.
#ifndef __vtkImageHistogram_h
#define __vtkImageHistogram_h
#include "vtkThreadedImageAlgorithm.h"
class vtkImageStencilData;
class vtkIdTypeArray;
class VTK_IMAGING_EXPORT vtkImageHistogram : public vtkThreadedImageAlgorithm
{
public:
static vtkImageHistogram *New();
vtkTypeMacro(vtkImageHistogram,vtkThreadedImageAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Scale types for the histogram image.
enum {
Linear = 0,
Log = 1,
Sqrt = 2,
};
// Description:
// Set the component for which to generate a histogram. The default
// value is -1, which produces a histogram that is the sum of the
// histograms of the individual components.
vtkSetMacro(ActiveComponent, int);
vtkGetMacro(ActiveComponent, int);
// Description:
// If this is On, then the histogram binning will be done automatically.
// For char and unsigned char data, there will be 256 bins with unit
// spacing. For data of type short and larger, there will be between
// 256 and MaximumNumberOfBins, depending on the range of the data, and
// the BinOrigin will be set to zero if no negative values are present,
// or to the smallest negative value if negative values are present.
// For float data, the MaximumNumberOfBins will always be used.
// The BinOrigin and BinSpacing will be set so that they provide a mapping
// from bin index to scalar value.
vtkSetMacro(AutomaticBinning, int);
vtkBooleanMacro(AutomaticBinning, int);
vtkGetMacro(AutomaticBinning, int);
// Description:
// The maximum number of bins to use when AutomaticBinning is On.
// When AutomaticBinning is On, the size of the output histogram
// will be set to the full range of the input data values, unless
// the full range is greater than this value. By default, the max
// value is 65536, which is large enough to capture the full range
// of 16-bit integers.
vtkSetMacro(MaximumNumberOfBins, int);
vtkGetMacro(MaximumNumberOfBins, int);
// Description:
// The number of bins in histogram (default 256). This is automatically
// computed unless AutomaticBinning is Off.
vtkSetMacro(NumberOfBins, int);
vtkGetMacro(NumberOfBins, int);
// Description:
// The value for the center of the first bin (default 0). This is
// automatically computed unless AutomaticBinning is Off.
vtkSetMacro(BinOrigin, double);
vtkGetMacro(BinOrigin, double);
// Description:
// The bin spacing (default 1). This is automatically computed unless
// AutomaticBinning is Off.
vtkSetMacro(BinSpacing, double);
vtkGetMacro(BinSpacing, double);
// Description:
// Use a stencil to compute the histogram for just a part of the image.
void SetStencil(vtkImageStencilData *stencil);
vtkImageStencilData *GetStencil();
// Description:
// If this is On, then a histogram image will be produced as the output.
// Regardless of this setting, the histogram is always available as a
// vtkIdTypeArray from the GetHistogram method.
vtkSetMacro(GenerateHistogramImage, int);
vtkBooleanMacro(GenerateHistogramImage, int);
vtkGetMacro(GenerateHistogramImage, int);
// Description:
// Set the size of the histogram image that is produced as output.
// The default is 256 by 256.
vtkSetVector2Macro(HistogramImageSize, int);
vtkGetVector2Macro(HistogramImageSize, int);
// Description:
// Set the scale to use for the histogram image. The default is
// a linear scale, but sqrt and log provide better visualization.
vtkSetClampMacro(HistogramImageScale, int,
vtkImageHistogram::Linear, vtkImageHistogram::Sqrt);
void SetHistogramImageScaleToLinear() {
this->SetHistogramImageScale(vtkImageHistogram::Linear); }
void SetHistogramImageScaleToLog() {
this->SetHistogramImageScale(vtkImageHistogram::Log); }
void SetHistogramImageScaleToSqrt() {
this->SetHistogramImageScale(vtkImageHistogram::Sqrt); }
vtkGetMacro(HistogramImageScale, int);
const char *GetHistogramImageScaleAsString();
// Description:
// Get the histogram as a vtkIdTypeArray. You must call Update()
// before calling this method.
vtkIdTypeArray *GetHistogram();
// Description:
// Get the total count of the histogram. This will be the number of
// voxels times the number of components.
vtkIdType GetTotal() { return this->Total; }
// Description:
// This is part of the executive, but is public so that it can be accessed
// by non-member functions.
virtual void ThreadedRequestData(vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector,
vtkImageData ***inData,
vtkImageData **outData, int ext[6], int id);
protected:
vtkImageHistogram();
~vtkImageHistogram();
virtual int RequestUpdateExtent(vtkInformation *vtkNotUsed(request),
vtkInformationVector **inInfo,
vtkInformationVector *vtkNotUsed(outInfo));
virtual int RequestInformation(vtkInformation *vtkNotUsed(request),
vtkInformationVector **inInfo,
vtkInformationVector *vtkNotUsed(outInfo));
virtual int RequestData(vtkInformation *,
vtkInformationVector **,
vtkInformationVector *);
virtual int FillInputPortInformation(int port, vtkInformation *info);
virtual int FillOutputPortInformation(int port, vtkInformation *info);
// Description:
// Compute the range of the data. The GetScalarRange() function of
// vtkImageData only computes the range of the first component, but
// this filter requires the range for all components.
void ComputeImageScalarRange(vtkImageData *data, double range[2]);
int ActiveComponent;
int AutomaticBinning;
int MaximumNumberOfBins;
int HistogramImageSize[2];
int HistogramImageScale;
int GenerateHistogramImage;
int NumberOfBins;
double BinOrigin;
double BinSpacing;
vtkIdTypeArray *Histogram;
vtkIdType Total;
vtkIdType *ThreadOutput[VTK_MAX_THREADS];
int ThreadBinRange[VTK_MAX_THREADS][2];
private:
vtkImageHistogram(const vtkImageHistogram&); // Not implemented.
void operator=(const vtkImageHistogram&); // Not implemented.
};
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageHistogramStatistics.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/