[vtkusers] How do I display data bands from RGB image data?

Carl Trapani carl at skytopsoftware.com
Wed Oct 22 16:22:59 EDT 2008


For anyone who might stumble on this posting, I've discovered the following:

1) The vtkTIFFReader seams to merge the RGB scalar pixel values to form 
a grayscale scalar of its own accord(?) The following code suggests this:
//------------------------------
vtkTIFFReader* reader = vtkTIFFReader::New();
  reader->SetFileNames( ishImages );
  // 10 images in the stack, each image is 1000 x 1000 pixels
  reader->SetDataExtent( 0,999, 0,999, 1,10 );
  reader->SetDataSpacing( 8.3, 8.3, 20 );
  reader->UpdateWholeExtent();

  vtkDataObject *readerData = reader->GetOutputDataObject(0);
  vtkImageData *imageData = vtkImageData::SafeDownCast( readerData );
  cout << "imageData has: " << imageData->GetNumberOfPoints() << " 
points." << endl;
  cout << "imageData min: " << imageData->GetScalarRange()[0] << " max: 
" << imageData->GetScalarRange()[1] << endl;
//------------------------------

2) Notice that 10 x 1000 x 1000 is 10,000,000 voxels/points! In order to 
band the data I found the vtkThresholdPoints class which filtered the 
points down to a manageable size (~20,000):
//------------------------------
  vtkThresholdPoints *pointMask = vtkThresholdPoints::New();
  pointMask->ThresholdBetween(40, 120);
  pointMask->SetInputConnection(reader->GetOutputPort());
  //pointMask->SetInputConnection(shrinker->GetOutputPort());
  pointMask->Update();
 
  vtkPolyData *pointData = 
vtkPolyData::SafeDownCast(pointMask->GetOutputDataObject(0));
  cout << "pointData->GetNumberOfPoints:" << 
pointData->GetNumberOfPoints() << endl;
  cout << "pointData min: " << pointData->GetScalarRange()[0] << " max: 
" << pointData->GetScalarRange()[1] << endl;
//------------------------------

3) To show the data I decided to try vtkGlyph3D using a sphere as the 
glyph. This isn't an optimal solution, but vtkGlyph3D allows you to 
scale the size of the glyph according to the scalar values in the 
dataset and by a supplied scale factor:
//------------------------------
  vtkSphereSource *sphere = vtkSphereSource::New();
  sphere->SetRadius(0.01);
  vtkGlyph3D *glyph = vtkGlyph3D::New();
  glyph->SetInputConnection(pointMask->GetOutputPort());
  glyph->SetSourceConnection(sphere->GetOutputPort());
  glyph->SetScaleModeToScaleByScalar();
  glyph->SetScaleFactor(2.0);
  vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
  mapper->SetInputConnection(glyph->GetOutputPort());
//------------------------------

This solution has performance issues and, as indicated in the docs, 
scaling the glyph according to scalar values is not a very good choice. 
Anyone have other ideas?

The whole program is at the bottom of this post, after the previous 
quoted message.
Thanks,
Carl
 

Carl Trapani wrote:
> Hi vtkusers,
>
> I've got a stack of RGB images that I'm displaying using 
> vtkContourFilter and vtkPolyDataNormals following the Medical2.cxx 
> example, but I don't think this is the best choice for visualizing the 
> data because the spots are not contours. A histogram of my data shows 
> that it ranges between 51 and 181 grayscale value where grayscale is 
> simply (red + green + blue)/3.
>
> Can anyone suggest how I might:
>
> 1) convert the RGB scalar data into grayscale values according to 
> grayscale = (red + green + blue)/3
>
> 2) break the resulting grayscale data into three bands, weak (51-94), 
> medium (95-138) and strong (139-182)?
>
> 2) show these scalar values as spots (spheres?) with a size 
> corresponding to the band the scalar falls within, weak->smallest, 
> medium->medium, strong->largest?
>
> Any suggestions would be very welcome.
>
> Thanks in advance,
> Carl Trapani
//----------------------------------------
#include <string>
#include <iostream>

#include "vtkStringArray.h"
#include "vtkTIFFReader.h"
#include "vtkDataObject.h"
#include "vtkImageData.h"

#include "vtkThresholdPoints.h"
#include "vtkImageShrink3D.h"
#include "vtkImageThreshold.h"

#include "vtkSphereSource.h"
#include "vtkGlyph3D.h"

#include "vtkOutlineFilter.h"

#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkLODActor.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"

int main(int argc, char *argv[])
{
  std::string modelName = "model\\p5-object.3DS";
  vtkStringArray* ishImages = vtkStringArray::New();
  ishImages->SetName("ishImages");
  ishImages->InsertNextValue("images\\1-flip_spots.tif");
  ishImages->InsertNextValue("images\\2-flip_spots.tif");
  ishImages->InsertNextValue("images\\3-flip_spots.tif");
  ishImages->InsertNextValue("images\\4-flip_spots.tif");
  ishImages->InsertNextValue("images\\5-flip_spots.tif");
  ishImages->InsertNextValue("images\\6-flip_spots.tif");
  ishImages->InsertNextValue("images\\7-flip_spots.tif");
  ishImages->InsertNextValue("images\\8-flip_spots.tif");
  ishImages->InsertNextValue("images\\9-flip_spots.tif");
  ishImages->InsertNextValue("images\\10-flip_spots.tif");

  vtkTIFFReader* reader = vtkTIFFReader::New();
  reader->SetFileNames( ishImages );
  // 10 images in the stack, each image is 1000 x 1000 pixels
  reader->SetDataExtent( 0,999, 0,999, 1,10 );
  reader->SetDataSpacing( 8.3, 8.3, 20 );
  reader->UpdateWholeExtent();

  vtkDataObject *readerData = reader->GetOutputDataObject(0);
  vtkImageData *imageData = vtkImageData::SafeDownCast( readerData );
  cout << "imageData has: " << imageData->GetNumberOfPoints() << " 
points." << endl;
  cout << "imageData min: " << imageData->GetScalarRange()[0] << " max: 
" << imageData->GetScalarRange()[1] << endl;

  //vtkImageShrink3D* shrinker = vtkImageShrink3D::New();
  //shrinker->SetInputConnection(reader->GetOutputPort());
  //shrinker->SetShrinkFactors(5, 5, 1);
  //shrinker->Update();

  //imageData = 
vtkImageData::SafeDownCast(shrinker->GetOutputDataObject(0));
  //cout << "shrunk data has: " << imageData->GetNumberOfPoints() << " 
points." << endl;
  //cout << "ishrunk data min: " << imageData->GetScalarRange()[0] << " 
max: " << imageData->GetScalarRange()[1] << endl;

  vtkThresholdPoints *pointMask = vtkThresholdPoints::New();
  pointMask->ThresholdBetween(40, 120);
  pointMask->SetInputConnection(reader->GetOutputPort());
  //pointMask->SetInputConnection(shrinker->GetOutputPort());
  pointMask->Update();
 
  vtkPolyData *pointData = 
vtkPolyData::SafeDownCast(pointMask->GetOutputDataObject(0));
  cout << "pointData->GetNumberOfPoints:" << 
pointData->GetNumberOfPoints() << endl;
  cout << "pointData min: " << pointData->GetScalarRange()[0] << " max: 
" << pointData->GetScalarRange()[1] << endl;

  vtkSphereSource *sphere = vtkSphereSource::New();
  sphere->SetRadius(0.01);

  vtkGlyph3D *glyph = vtkGlyph3D::New();
  //glyph->SetInputConnection(reader->GetOutputPort());
  //glyph->SetInputConnection(shrinker->GetOutputPort());
  glyph->SetInputConnection(pointMask->GetOutputPort());
  glyph->SetSourceConnection(sphere->GetOutputPort());
  glyph->SetScaleModeToScaleByScalar();
  glyph->SetScaleFactor(2.0);

  vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
  mapper->SetInputConnection(glyph->GetOutputPort());

  //vtkActor *actor = vtkActor::New();
  vtkLODActor *actor = vtkLODActor::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(1, 0, 0);

  vtkOutlineFilter *outline = vtkOutlineFilter::New();
  outline->SetInputConnection(reader->GetOutputPort());
  vtkPolyDataMapper *outlineMapper = vtkPolyDataMapper::New();
  outlineMapper->SetInputConnection(outline->GetOutputPort());
  vtkActor *outlineActor = vtkActor::New();
  outlineActor->SetMapper(outlineMapper);
  outlineActor->GetProperty()->SetColor( 1.0, 1.0, 1.0 );

  vtkRenderer *renderer = vtkRenderer::New();
  renderer->AddActor(actor);
  renderer->AddActor(outlineActor);
  renderer->SetBackground(0,0,0);

  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->AddRenderer(renderer);
  renWin->SetSize(500,500);

  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);

  renWin->Render();
  iren->Start();

  iren->Delete();
  renWin->Delete();
  renderer->Delete();
  outlineActor->Delete();
  outlineMapper->Delete();
  outline->Delete();
  actor->Delete();
  mapper->Delete();
  glyph->Delete();
  sphere->Delete();
  //shrinker->Delete();
  pointMask->Delete();
  reader->Delete();
  ishImages->Delete();

  return EXIT_SUCCESS;
}



More information about the vtkusers mailing list