Scroll through 2d slices of 3d volume - ultrasound .mhd file

Hi ,

I am new to vtk ,I want to display a 3d volume of .mhd file. I reused the following code which I got off the net ,made some changes to support vtk6.` /*=========================================================================

Program: Visualization Toolkit
Module: ImageSlicing.cxx

Copyright © Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
//
// This example shows how to load a 3D image into VTK and then reformat
// that image into a different orientation for viewing. It uses
// vtkImageReslice for reformatting the image, and uses vtkImageActor
// and vtkInteractorStyleImage to display the image. This InteractorStyle
// forces the camera to stay perpendicular to the XY plane.
//
// Thanks to David Gobbi of Atamai Inc. for contributing this example.
//

#include <vtkMetaImageReader.h>
#include <vtkSmartPointer.h>
#include “vtkMatrix4x4.h”
#include “vtkImageReslice.h”
#include “vtkLookupTable.h”
#include “vtkImageMapToColors.h”
#include “vtkImageActor.h”
#include “vtkRenderer.h”
#include “vtkRenderWindow.h”
#include “vtkRenderWindowInteractor.h”
#include “vtkInteractorStyleImage.h”
#include “vtkCommand.h”
#include “vtkImageData.h”

// The mouse motion callback, to turn “Slicing” on and off
class vtkImageInteractionCallback : public vtkCommand
{
public:

static vtkImageInteractionCallback *New() {
return new vtkImageInteractionCallback; };

vtkImageInteractionCallback() {
this->Slicing = 0;
this->ImageReslice = 0;
this->Interactor = 0; };

void SetImageReslice(vtkImageReslice *reslice) {
this->ImageReslice = reslice; };

vtkImageReslice *GetImageReslice() {
return this->ImageReslice; };

void SetInteractor(vtkRenderWindowInteractor *interactor) {
this->Interactor = interactor; };

vtkRenderWindowInteractor *GetInteractor() {
return this->Interactor; };

virtual void Execute(vtkObject *, unsigned long event, void *)
{
vtkRenderWindowInteractor *interactor = this->GetInteractor();

int lastPos[2];
interactor->GetLastEventPosition(lastPos);
int currPos[2];
interactor->GetEventPosition(currPos);

if (event == vtkCommand::LeftButtonPressEvent)
  {
	std::cout << "left button press event" << "\n";
  this->Slicing = 1;
  }
else if (event == vtkCommand::LeftButtonReleaseEvent)
  {
  this->Slicing = 0;
  }
else if (event == vtkCommand::MouseMoveEvent)
  {
  if (this->Slicing)
    {
	  
    vtkImageReslice *reslice = this->ImageReslice;

    // Increment slice position by deltaY of mouse
    int deltaY = lastPos[1] - currPos[1];

	std::cout << deltaY << "\n";
   // reslice->GetOutput()
    double sliceSpacing = reslice->GetOutput()->GetSpacing()[2];
    vtkMatrix4x4 *matrix = reslice->GetResliceAxes();
    // move the center point that we are slicing through
    double point[4];
    double center[4];
    point[0] = 0.0;
    point[1] = 0.0;
    point[2] = sliceSpacing * deltaY;
    point[3] = 1.0;
    matrix->MultiplyPoint(point, center);
    matrix->SetElement(0, 3, center[0]);
    matrix->SetElement(1, 3, center[1]);
    matrix->SetElement(2, 3, center[2]);
    interactor->Render();
    }
  else
    {
    vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(
      interactor->GetInteractorStyle());
    if (style)
      {
      style->OnMouseMove();
      }
    }
  }
};

private:

// Actions (slicing only, for now)
int Slicing;

// Pointer to vtkImageReslice
vtkImageReslice *ImageReslice;

// Pointer to the interactor
vtkRenderWindowInteractor *Interactor;
};

// The program entry point
int main (int argc, char **argv)
{
if (argc < 2)
{
cout << “Usage: " << argv[0] << " DATADIR/headsq/quarter” << endl;
return 1;
}

// Start by loading some data.
std::string inputFilename = argv[1];

vtkSmartPointer reader =
vtkSmartPointer::New();
reader->SetFileName(inputFilename.c_str());
// reader->SetFilePrefix(argv[1]);
reader->SetDataExtent(0, 256, 0, 256, 1, 94);
reader->SetDataSpacing(0.9375, 0.9375, 1.5);
reader->SetDataOrigin(0.0, 0.0, 0.0);
//reader->SetDataScalarTypeToUnsignedShort();
reader->UpdateWholeExtent();
reader->UpdateInformation();
// Calculate the center of the volume
// reader->GetOutput()->UpdateInformation();
int extent[6];
double spacing[3];
double origin[3];
reader->GetOutput()->GetExtent(extent);
reader->GetOutput()->GetSpacing(spacing);
reader->GetOutput()->GetOrigin(origin);

double center[3];
center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);
center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);
center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);
std::cout << “Center:”;
std::cout << center[0] << “,” << center[1] << “,” << center[2] << “\n”;
// Matrices for axial, coronal, sagittal, oblique view orientations
static double axialElements[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };

static double coronalElements[16] = {
1, 0, 0, 0,
0, 0, 1, 0,
0,-1, 0, 0,
0, 0, 0, 1 };

static double sagittalElements[16] = {
0, 0,-1, 0,
1, 0, 0, 0,
0,-1, 0, 0,
0, 0, 0, 1 };

static double obliqueElements[16] = {
1, 0, 0, 0,
0, 0.866025, -0.5, 0,
0, 0.5, 0.866025, 0,
0, 0, 0, 1 };

// Set the slice orientation
vtkMatrix4x4 *resliceAxes = vtkMatrix4x4::New();
resliceAxes->DeepCopy(sagittalElements);
// Set the point through which to slice
resliceAxes->SetElement(0, 3, center[0]);
resliceAxes->SetElement(1, 3, center[1]);
resliceAxes->SetElement(2, 3, center[2]);

// Extract a slice in the desired orientation
vtkImageReslice *reslice = vtkImageReslice::New();
reslice->SetInputConnection(reader->GetOutputPort());
reslice->SetOutputDimensionality(2);
reslice->SetResliceAxes(resliceAxes);
reslice->SetInterpolationModeToLinear();

// Create a greyscale lookup table
vtkLookupTable *table = vtkLookupTable::New();
table->SetRange(0, 2000); // image intensity range
table->SetValueRange(0.0, 1.0); // from black to white
table->SetSaturationRange(0.0, 0.0); // no color saturation
table->SetRampToLinear();
table->Build();

// Map the image through the lookup table
vtkImageMapToColors *color = vtkImageMapToColors::New();
color->SetLookupTable(table);
color->SetInputConnection(reslice->GetOutputPort());

// Display the image
vtkImageActor *actor = vtkImageActor::New();
actor->SetInputData(color->GetOutput());

vtkRenderer *renderer = vtkRenderer::New();
renderer->AddActor(actor);

vtkRenderWindow *window = vtkRenderWindow::New();
window->AddRenderer(renderer);

// Set up the interaction
vtkInteractorStyleImage *imageStyle = vtkInteractorStyleImage::New();
vtkRenderWindowInteractor *interactor = vtkRenderWindowInteractor::New();
interactor->SetInteractorStyle(imageStyle);
window->SetInteractor(interactor);
window->Render();

vtkImageInteractionCallback *callback = vtkImageInteractionCallback::New();
callback->SetImageReslice(reslice);
callback->SetInteractor(interactor);

imageStyle->AddObserver(vtkCommand::MouseMoveEvent, callback);
imageStyle->AddObserver(vtkCommand::LeftButtonPressEvent, callback);
imageStyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);

// Start interaction
// The Start() method doesn’t return until the window is closed by the user
interactor->Start();

std::cout << “interactor done” << “\n”;
// Clean up
callback->Delete();
interactor->Delete();
imageStyle->Delete();
window->Delete();
renderer->Delete();
actor->Delete();
reslice->Delete();
resliceAxes->Delete();
color->Delete();
table->Delete();
reader->Delete();
}

This displays an empty window.I am not able to find out the problem. Could someone help me with this please
-swetha
`

The official code for that program comes with the VTK source (click here).

Probably the best way to work with the code is to start with the original “headsq” dataset (from the vtkdata package at https://vtk.org/download/) and after you have it working with that data, you can modify it to work with your own data.

Thankyou very much. it worked

Hi guys, I’ve used that example to ‘cut’ my volume in the axial and sagittal plane…now i have to render both of them in the same window. I’ve managed to do it, only i can ‘scroll’ up/down through the volume just one of these planes and not both! When i scroll up/down one of my plane changes, while the other doesn’t (it’s a static image).
Do u have any suggestion/guide i could use?
Thanks in advance,
Marco