[vtkusers] plotting bar chart with vtkBarChartActor and vtkXYPlotActor

michiel mentink michael.mentink at st-hughs.ox.ac.uk
Thu Jan 7 09:29:49 EST 2010


>
> Dear David,
>

thank you for the example, there were some things that were different:
this bit in the code I certainly coded differently than in the example:

  histogram->SetComponentExtent(0, 4000, 0, 0, 0, 0);
  histogram->SetComponentOrigin(0, 0, 0);
  histogram->SetComponentSpacing(0.16, 0.16, 3.26); // component spacing:
depends on spacing of input volume

I'm still a bit confused about the componentspacing.. as described above, I
assumed it to be dependent on the input volume,
but it is not???

Anyway, I've extended your example a bit with writing the corresponding
intensity levels to a file, for opening in a spreadsheet program.
I'm not sure if it's too basic to put in the Examples section, but it helped
me and maybe someone else could benefit from it too.


Michael


#include <vtkActor.h>
#include <vtkImageAccumulate.h>
#include <vtkImageData.h>
#include <vtkImageExtractComponents.h>
#include <vtkJPEGReader.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkStdString.h>
#include <vtkXYPlotActor.h>
#include <vtkPointData.h>

int main( int argc, char *argv[] )
{
  // Handle the arguments
  if( argc < 2 )
    {
    vtkstd::cout << "Required arguments: filename.jpg, [optional ignore
zero:] <y/n>" << vtkstd::endl;
    return EXIT_FAILURE;
    }

  int ignoreZero = 0;
  if( argc == 3 )
    {
    vtkStdString ignore = argv[2];
    cout << ignore << endl;
    if( ignore == "y" || ignore == "Y" )
      {
      ignoreZero = 1;
      }
    }

  // Read a jpeg image
  //
  vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
  if( !reader->CanReadFile( argv[1] ) )
    {
    vtkstd::cout << "Error: cannot read " << argv[1] << vtkstd::endl;
    return EXIT_FAILURE;
    }
  reader->SetFileName( argv[1] );
  reader->Update();

  int numComponents = reader->GetOutput()->GetNumberOfScalarComponents();
  if( numComponents > 3 )
    {
    vtkstd::cout << "Error: cannot process an image with " << numComponents
<< " components!" << vtkstd::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
  //
  //

    ofstream myfile;
    myfile.open ("histogram.txt");
    myfile << "Pixel intensities and their counts.\n";

  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];

    plot->AddInput( histogram->GetOutput() );

    if( numComponents > 1 )
      {
      plot->SetPlotColor(i,colors[i]);
      plot->SetPlotLabel(i,labels[i]);
      plot->LegendOn();

      myfile << "\n" << labels[i] << "\n\n";
      }

    unsigned int temp = (range[1]-1);
    unsigned int frequency[numLevels];

    std::cout<< "range: " << range[0] << " " << range[1] <<std::endl;

    unsigned int j;

    for(j=0;j<temp;j++){
       frequency[j]=0;
              frequency[j] =
histogram->GetOutput()->GetPointData()->GetScalars()->GetTuple1(j);
           myfile << j << "\t" << frequency[j] << "\n";
    }
  }

  myfile.close();

  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;
}




> I reorganized the code a little bit, changed the input to a jpeg, and
> posted an example in the "broken" section:
> http://www.cmake.org/Wiki/VTK/Examples/Histogram
>
> Maybe this will double your chances of someone seeing it and figuring
> out what is wrong :)
>
> Thanks,
>
> David
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100107/c0c94507/attachment.htm>


More information about the vtkusers mailing list