vtk пролистать 2d срез 3d .mhd colume - PullRequest
0 голосов
/ 23 января 2019

Я новичок в vtk, я хочу отобразить объем 3d .mhd файла. Я повторно использовал следующий код, который я получил из сети, внес некоторые изменения для поддержки vtk6.`

#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<vtkMetaImageReader> reader =
      vtkSmartPointer<vtkMetaImageReader>::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();
}

Отображается пустое окно. Я не могу найти проблему. Я просмотрел другие демонстрационные версии vtk medical. Я не хочу отображать срезы на изоконтуре или на поверхности, мне нужен дисплей, похожий на ITK-snap. Может ли кто-нибудь помочь мне с этим, пожалуйста? -swetha `

...