VTK/Examples/Cxx/WishList/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;
}

Please try the new VTKExamples website.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

PROJECT(HistogramXYPlot)

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})

add_executable(HistogramXYPlot MACOSX_BUNDLE HistogramXYPlot.cxx)

if(VTK_LIBRARIES)
  target_link_libraries(HistogramXYPlot ${VTK_LIBRARIES})
else()
  target_link_libraries(HistogramXYPlot vtkHybrid vtkWidgets)
endif()

Download and Build HistogramXYPlot

Click here to download HistogramXYPlot. and its CMakeLists.txt file.

Once the tarball HistogramXYPlot.tar has been downloaded and extracted,

cd HistogramXYPlot/build 
  • If VTK is installed:
cmake ..
  • If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..

Build the project:

make

and run it:

./HistogramXYPlot

WINDOWS USERS PLEASE NOTE: Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.

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