VTK/Examples/Cxx/Images/HistogramXYPlot

From KitwarePublic

Jump to: navigation, search
VTK Examples Baseline Images TestHistogramXYPlot.png

This example works but there is an issue with vtkImageAccumulate.

It appears the maximum frequency of a histogram generated by vtkImageAccumulate, when that frequency corresponds to the value of 0, cannot be disabled by setting ignore zero to true! See lines 245 and 218 in vtkImageAccumulate.cxx

HistogramXYPlot.cxx

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
 
#include <string>
 
#include <vtkActor.h>
#include <vtkImageAccumulate.h>
#include <vtkImageData.h>
#include <vtkImageExtractComponents.h>
#include <vtkJPEGReader.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkXYPlotActor.h>
 
int main(int argc, char *argv[])
{
  // Handle the arguments
  if( argc < 2 )
    {
    std::cout << "Usage: " << argv[0] << " Filename.jpg, [optional ignore zero:] <y/n>" << std::endl;
    return EXIT_FAILURE;
    }
 
  int ignoreZero = 0;
  if( argc == 3 )
    {
    std::string ignore = argv[2];
    std::cout << ignore << std::endl;
    if( ignore == "y" || ignore == "Y" )
      {
      ignoreZero = 1;
      }
    }
 
  // Read a jpeg image
  vtkSmartPointer<vtkJPEGReader> reader = 
    vtkSmartPointer<vtkJPEGReader>::New();
  if( !reader->CanReadFile( argv[1] ) )
    {
    std::cout << "Error: cannot read " << argv[1] << std::endl;
    return EXIT_FAILURE;
    }
  reader->SetFileName( argv[1] );
  reader->Update();
 
  int numComponents = reader->GetOutput()->GetNumberOfScalarComponents();
  if( numComponents > 3 )
    {
    std::cout << "Error: cannot process an image with " 
              << numComponents << " components!" << std::endl;
    return EXIT_FAILURE;
    }
 
  // Create a vtkXYPlotActor
  vtkSmartPointer<vtkXYPlotActor> plot = 
    vtkSmartPointer<vtkXYPlotActor>::New();
  plot->ExchangeAxesOff();
  plot->SetLabelFormat( "%g" );
  plot->SetXTitle( "Level" );
  plot->SetYTitle( "Frequency" );
  plot->SetXValuesToValue();
 
  double xmax = 0.;
  double ymax = 0.;
 
  double colors[3][3] = {
    { 1, 0, 0 },
    { 0, 1, 0 },
    { 0, 0, 1 } };
 
  const char* labels[3] = {
    "Red", "Green", "Blue" };
 
  // Process the image, extracting and plotting a histogram for each
  // component
  for( int i = 0; i < numComponents; ++i )
    {
    vtkSmartPointer<vtkImageExtractComponents> extract = 
      vtkSmartPointer<vtkImageExtractComponents>::New();
    extract->SetInputConnection( reader->GetOutputPort() );
    extract->SetComponents( i );
    extract->Update();
 
    double range[2];
    extract->GetOutput()->GetScalarRange( range );
 
    vtkSmartPointer<vtkImageAccumulate> histogram = 
      vtkSmartPointer<vtkImageAccumulate>::New();
    histogram->SetInputConnection( extract->GetOutputPort() );
    histogram->SetComponentExtent(
      0,
      static_cast<int>(range[1])-static_cast<int>(range[0])-1,0,0,0,0 );
    histogram->SetComponentOrigin( range[0],0,0 );
    histogram->SetComponentSpacing( 1,0,0 );
    histogram->SetIgnoreZero( ignoreZero );
    histogram->Update();
 
    if( range[1] > xmax ) 
      { 
      xmax = range[1];
      }
    if( histogram->GetOutput()->GetScalarRange()[1] > ymax ) 
      {
      ymax = histogram->GetOutput()->GetScalarRange()[1];
      }
 
#if VTK_MAJOR_VERSION <= 5
    plot->AddInput( histogram->GetOutput() );
#else
    plot->AddDataSetInputConnection( histogram->GetOutputPort() );
#endif
    if( numComponents > 1 )
      {
      plot->SetPlotColor(i,colors[i]);
      plot->SetPlotLabel(i,labels[i]);
      plot->LegendOn();
      }
    }
 
  plot->SetXRange( 0, xmax );
  plot->SetYRange( 0, ymax );
 
  // Visualize the histogram(s)
  vtkSmartPointer<vtkRenderer> renderer = 
    vtkSmartPointer<vtkRenderer>::New();
  renderer->AddActor(plot);
 
  vtkSmartPointer<vtkRenderWindow> renderWindow = 
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer( renderer );
  renderWindow->SetSize(640, 480);
 
  vtkSmartPointer<vtkRenderWindowInteractor> interactor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow( renderWindow );
 
  // Initialize the event loop and then start it
  interactor->Initialize();
  interactor->Start(); 
 
  return EXIT_SUCCESS;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
 
PROJECT(HistogramXYPlot)
 
FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})
 
ADD_EXECUTABLE(HistogramXYPlot HistogramXYPlot.cxx)
 
TARGET_LINK_LIBRARIES(HistogramXYPlot vtkHybrid)

Zoom or do something so the plot takes up the whole window.

Personal tools