[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